From 04dc01cdd4f949214656095fe952e31c535875ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Wed, 16 Mar 2022 00:47:02 +0000 Subject: [PATCH 001/430] Update configuration for building working drafts after N4910. --- source/config.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/config.tex b/source/config.tex index 5f56bc933e..7b9750928c 100644 --- a/source/config.tex +++ b/source/config.tex @@ -1,8 +1,8 @@ %!TEX root = std.tex %%-------------------------------------------------- %% Version numbers -\newcommand{\docno}{N4910} -\newcommand{\prevdocno}{N4901} +\newcommand{\docno}{Dxxxx} +\newcommand{\prevdocno}{N4910} \newcommand{\cppver}{202002L} %% Release date From fb8135e5ec22acd26cb0dcb1bface21eee118895 Mon Sep 17 00:00:00 2001 From: hewillk <67143766+hewillk@users.noreply.github.com> Date: Sun, 6 Mar 2022 20:22:18 +0800 Subject: [PATCH 002/430] [range.utility.conv.general] Add missing template parameter to container-inserter --- source/ranges.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index f980dd7eca..827e00d272 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -2101,8 +2101,8 @@ \pnum Let \exposid{container-inserter} be defined as follows: \begin{codeblock} -template -auto @\exposid{container-inserter}@(C& c) { // \expos +template +auto @\exposid{container-inserter}@(Container& c) { // \expos if constexpr (requires { c.push_back(declval()); }) return back_inserter(c); else From b7c1f9a77eac8dfeb4cb2e92bd3b2a57d05c298a Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 25 Mar 2022 09:37:42 +0100 Subject: [PATCH 003/430] [spanbuf] Fix template name in subclause heading (#5365) --- source/iostreams.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/iostreams.tex b/source/iostreams.tex index bb586b70d6..31d21065de 100644 --- a/source/iostreams.tex +++ b/source/iostreams.tex @@ -9353,7 +9353,7 @@ } \end{codeblock} -\rSec2[spanbuf]{Class template \tcode{spanbuf}} +\rSec2[spanbuf]{Class template \tcode{basic_spanbuf}} \rSec3[spanbuf.general]{General} From cdca862605ae315e2d7a1ca7c7c1b011651944d2 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 25 Mar 2022 10:44:58 +0100 Subject: [PATCH 004/430] [span.streams] Move non-member swaps to header synopsis (#5366) --- source/iostreams.tex | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/source/iostreams.tex b/source/iostreams.tex index 31d21065de..9ba1433df9 100644 --- a/source/iostreams.tex +++ b/source/iostreams.tex @@ -9330,24 +9330,36 @@ template> class basic_spanbuf; + template + void swap(basic_spanbuf& x, basic_spanbuf& y); + using spanbuf = basic_spanbuf; using wspanbuf = basic_spanbuf; template> class basic_ispanstream; + template + void swap(basic_ispanstream& x, basic_ispanstream& y); + using ispanstream = basic_ispanstream; using wispanstream = basic_ispanstream; template> class basic_ospanstream; + template + void swap(basic_ospanstream& x, basic_ospanstream& y); + using ospanstream = basic_ospanstream; using wospanstream = basic_ospanstream; template> class basic_spanstream; + template + void swap(basic_spanstream& x, basic_spanstream& y); + using spanstream = basic_spanstream; using wspanstream = basic_spanstream; } @@ -9399,9 +9411,6 @@ ios_base::openmode @\exposid{mode}@; // \expos std::span @\exposid{buf}@; // \expos }; - -template - void swap(basic_spanbuf& x, basic_spanbuf& y); } \end{codeblock} @@ -9722,9 +9731,6 @@ private: basic_spanbuf sb; // \expos }; - - template - void swap(basic_ispanstream& x, basic_ispanstream& y); } \end{codeblock} @@ -9910,9 +9916,6 @@ private: basic_spanbuf sb; // \expos }; - - template - void swap(basic_ospanstream& x, basic_ospanstream& y); } \end{codeblock} @@ -10051,9 +10054,6 @@ private: basic_spanbuf sb; // \expos }; - - template - void swap(basic_spanstream& x, basic_spanstream& y); } \end{codeblock} From 3c7ae9b70161c7b5a141969b2410c7d8d22ad8e9 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sat, 26 Mar 2022 21:42:20 +0100 Subject: [PATCH 005/430] [lex.name] Remove extra vertical space in grammar --- source/lex.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/lex.tex b/source/lex.tex index 77e09e142a..cefbfa0a35 100644 --- a/source/lex.tex +++ b/source/lex.tex @@ -712,7 +712,7 @@ \begin{bnf} \nontermdef{identifier}\br identifier-start\br - identifier identifier-continue\br + identifier identifier-continue \end{bnf} \begin{bnf} From 478b8f8807e5b4561874842aa24a132558682f00 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Thu, 31 Mar 2022 19:34:03 +0800 Subject: [PATCH 006/430] [alg.min.max] Consistently specify ranges::minmax_element with minmax_element_result (#5376) LWG3180 was incompletely applied with commit e33be08f8ca49a9a139aa81b7a1ba9787d85f4fc. --- source/algorithms.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/algorithms.tex b/source/algorithms.tex index 4c0f369fac..4649a95619 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -8643,11 +8643,11 @@ template<@\libconcept{forward_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, @\libconcept{indirect_strict_weak_order}@> Comp = ranges::less> - constexpr ranges::minmax_result + constexpr ranges::minmax_element_result ranges::minmax_element(I first, S last, Comp comp = {}, Proj proj = {}); template<@\libconcept{forward_range}@ R, class Proj = identity, @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> - constexpr ranges::minmax_result> + constexpr ranges::minmax_element_result> ranges::minmax_element(R&& r, Comp comp = {}, Proj proj = {}); \end{itemdecl} From c92196bc67e252f06907c6de44173ce7157d71df Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 1 Apr 2022 13:38:03 +0200 Subject: [PATCH 007/430] [memory.syn] Add missing closing bracket for attribute --- source/memory.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/memory.tex b/source/memory.tex index 576a28b9fc..1b5ec82cb3 100644 --- a/source/memory.tex +++ b/source/memory.tex @@ -137,7 +137,7 @@ }; template - [[nodiscard] constexpr allocation_result::pointer> + [[nodiscard]] constexpr allocation_result::pointer> allocate_at_least(Allocator& a, size_t n); // \ref{default.allocator}, the default allocator From 1d2d223ab9fee202b67b31b32b85f44e3f9dc187 Mon Sep 17 00:00:00 2001 From: hewillk <67143766+hewillk@users.noreply.github.com> Date: Thu, 24 Mar 2022 02:13:51 +0800 Subject: [PATCH 008/430] [range.adjacent.transform.iterator] Fix wrong template parameter in adjacent_transform_view::iterator --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index 827e00d272..8d7da0435e 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -10551,7 +10551,7 @@ @\libconcept{regular_invocable}@, N)...> && @\exposconcept{can-reference}@, N)...>> template - class adjacent_transform_view::@\exposid{iterator}@ { + class adjacent_transform_view::@\exposid{iterator}@ { using @\exposidnc{Parent}@ = @\exposidnc{maybe-const}@; // \expos using @\exposidnc{Base}@ = @\exposidnc{maybe-const}@; // \expos @\exposidnc{Parent}@* @\exposid{parent_}@ = nullptr; // \expos From 4813f202b3e2f6d0062967b9fd96ca54b91c7b65 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Wed, 30 Mar 2022 08:29:55 +0200 Subject: [PATCH 009/430] [stacktrace.syn] Add '#include ' LWG3330 added #include to all header files where a three-way comparison operator was declared, but missed this one. --- source/diagnostics.tex | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/diagnostics.tex b/source/diagnostics.tex index b17a6e6fa0..9c2b82be09 100644 --- a/source/diagnostics.tex +++ b/source/diagnostics.tex @@ -1707,6 +1707,8 @@ \indexheader{stacktrace}% \begin{codeblock} +#include // see \ref{compare.syn} + namespace std { // \ref{stacktrace.entry}, class \tcode{stacktrace_entry} class stacktrace_entry; From d9040a775aa528f0576453532f3cb5058a6e6f24 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Wed, 6 Apr 2022 20:03:39 +0800 Subject: [PATCH 010/430] [allocator.requirements.general] Specify all member types with typename (#5386) --- source/lib-intro.tex | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/lib-intro.tex b/source/lib-intro.tex index 04ada51d52..6c634b3449 100644 --- a/source/lib-intro.tex +++ b/source/lib-intro.tex @@ -2464,7 +2464,7 @@ \end{itemdescr} \begin{itemdecl} -X::propagate_on_container_copy_assignment +typename X::propagate_on_container_copy_assignment \end{itemdecl} \begin{itemdescr} @@ -2486,7 +2486,7 @@ \end{itemdescr} \begin{itemdecl} -X::propagate_on_container_move_assignment +typename X::propagate_on_container_move_assignment \end{itemdecl} \begin{itemdescr} @@ -2508,7 +2508,7 @@ \end{itemdescr} \begin{itemdecl} -X::propagate_on_container_swap +typename X::propagate_on_container_swap \end{itemdecl} \begin{itemdescr} @@ -2530,7 +2530,7 @@ \end{itemdescr} \begin{itemdecl} -X::is_always_equal +typename X::is_always_equal \end{itemdecl} \begin{itemdescr} From 2bfa7c4cc96203e03763816cf310e54e5b8940bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Kr=C3=BCgler?= Date: Fri, 15 Apr 2022 21:26:27 +0200 Subject: [PATCH 011/430] [temp.constr.normal] Add missing semicolon in example (#5395) --- source/templates.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/templates.tex b/source/templates.tex index dce8fc693d..65988d76e1 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -1897,7 +1897,7 @@ template concept C1 = sizeof(T) == 1; template concept C2 = C1 && 1 == 2; template concept C3 = requires { typename T::type; }; -template concept C4 = requires (T x) { ++x; } +template concept C4 = requires (T x) { ++x; }; template void f1(U); // \#1 template void f2(U); // \#2 From a8dbfc63227bf596dcf72a31c9fef4af8af9e592 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Wed, 20 Apr 2022 14:41:22 +0100 Subject: [PATCH 012/430] [depr.tuple,depr.variant] Use struct class-key consistently (#5402) --- source/future.tex | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/source/future.tex b/source/future.tex index 17bd08d0ea..b1c352078f 100644 --- a/source/future.tex +++ b/source/future.tex @@ -1488,17 +1488,17 @@ \begin{codeblock} namespace std { - template class tuple_size; - template class tuple_size; + template struct tuple_size; + template struct tuple_size; - template class tuple_element; - template class tuple_element; + template struct tuple_element; + template struct tuple_element; } \end{codeblock} \begin{itemdecl} -template class tuple_size; -template class tuple_size; +template struct tuple_size; +template struct tuple_size; \end{itemdecl} \begin{itemdescr} @@ -1526,8 +1526,8 @@ \end{itemdescr} \begin{itemdecl} -template class tuple_element; -template class tuple_element; +template struct tuple_element; +template struct tuple_element; \end{itemdecl} \begin{itemdescr} @@ -1567,8 +1567,8 @@ \end{codeblock} \begin{itemdecl} -template class variant_size; -template class variant_size; +template struct variant_size; +template struct variant_size; \end{itemdecl} \begin{itemdescr} @@ -1581,8 +1581,8 @@ \end{itemdescr} \begin{itemdecl} -template class variant_alternative; -template class variant_alternative; +template struct variant_alternative; +template struct variant_alternative; \end{itemdecl} \begin{itemdescr} From 4fc805d949bfc99ee6cfcf666123eb982fc4c465 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 21 Apr 2022 09:27:57 +0200 Subject: [PATCH 013/430] [expr.prim.lambda.general] Clarify deduced lambda return type --- source/expressions.tex | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/expressions.tex b/source/expressions.tex index 6710c39aeb..16549b12c4 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -1757,9 +1757,11 @@ at the start of the \grammarterm{lambda-declarator}. If the \grammarterm{lambda-declarator} does not include a \grammarterm{trailing-return-type}, -the lambda return type is \keyword{auto}, -which is deduced from \keyword{return} statements +it is considered to be \tcode{-> \keyword{auto}}. +\begin{note} +In that case, the return type is deduced from \keyword{return} statements as described in \ref{dcl.spec.auto}. +\end{note} \begin{example} \begin{codeblock} auto x1 = [](int i) { return i; }; // OK, return type is \tcode{int} From 193a67c9f17e3d7102061e8e01250562b6292351 Mon Sep 17 00:00:00 2001 From: hewillk <67143766+hewillk@users.noreply.github.com> Date: Sat, 2 Apr 2022 01:32:24 +0800 Subject: [PATCH 014/430] [range.adaptors] Make the prints message format consistent --- source/ranges.tex | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index 8d7da0435e..71ce42b194 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -2472,7 +2472,7 @@ \begin{example} \begin{codeblock} for (int i : views::iota(1, 10)) - cout << i << ' '; // prints: 1 2 3 4 5 6 7 8 9 + cout << i << ' '; // prints \tcode{1 2 3 4 5 6 7 8 9} \end{codeblock} \end{example} @@ -3405,7 +3405,7 @@ auto even = [](int i) { return 0 == i % 2; }; auto square = [](int i) { return i * i; }; for (int i : ints | views::filter(even) | views::transform(square)) { - cout << i << ' '; // prints: 0 4 16 + cout << i << ' '; // prints \tcode{0 4 16} } assert(ranges::equal(ints | views::filter(even), views::filter(ints, even))); \end{codeblock} @@ -3823,7 +3823,7 @@ vector is{ 0, 1, 2, 3, 4, 5, 6 }; auto evens = views::filter(is, [](int i) { return 0 == i % 2; }); for (int i : evens) - cout << i << ' '; // prints: 0 2 4 6 + cout << i << ' '; // prints \tcode{0 2 4 6} \end{codeblock} \end{example} @@ -4248,7 +4248,7 @@ vector is{ 0, 1, 2, 3, 4 }; auto squares = views::transform(is, [](int i) { return i * i; }); for (int i : squares) - cout << i << ' '; // prints: 0 1 4 9 16 + cout << i << ' '; // prints \tcode{0 1 4 9 16} \end{codeblock} \end{example} @@ -4976,7 +4976,7 @@ \begin{codeblock} vector is{0,1,2,3,4,5,6,7,8,9}; for (int i : is | views::take(5)) - cout << i << ' '; // prints: 0 1 2 3 4 + cout << i << ' '; // prints \tcode{0 1 2 3 4} \end{codeblock} \end{example} @@ -5642,7 +5642,7 @@ \begin{codeblock} vector ss{"hello", " ", "world", "!"}; for (char ch : ss | views::join) - cout << ch; // prints: \tcode{hello world!} + cout << ch; // prints \tcode{hello world!} \end{codeblock} \end{example} @@ -6137,8 +6137,8 @@ for (char c : vs | join_with('-')) { cout << c; } +// The above prints \tcode{the-quick-brown-fox} \end{codeblock} -The above prints: \tcode{the-quick-brown-fox} \end{example} \rSec3[range.join.with.view]{Class template \tcode{join_with_view}} @@ -6719,7 +6719,7 @@ cout << ch; cout << '*'; } -// The above prints: the*quick*brown*fox* +// The above prints \tcode{the*quick*brown*fox*} \end{codeblock} \end{example} @@ -7278,7 +7278,7 @@ for (string_view word : split(str, ' ')) { cout << word << '*'; } -// The above prints: the*quick*brown*fox* +// The above prints \tcode{the*quick*brown*fox*} \end{codeblock} \end{example} @@ -7760,7 +7760,7 @@ \begin{codeblock} vector is {0,1,2,3,4}; for (int i : is | views::reverse) - cout << i << ' '; // prints: 4 3 2 1 0 + cout << i << ' '; // prints \tcode{4 3 2 1 0} \end{codeblock} \end{example} @@ -8550,7 +8550,7 @@ // that refers to the first element of \tcode{v} and \tcode{l} for (auto&& [x, y] : z) { - cout << '(' << x << ", " << y << ") "; // prints: (1, a) (2, b) + cout << '(' << x << ", " << y << ") "; // prints \tcode{(1, a) (2, b)} } \end{codeblock} \end{example} @@ -9281,7 +9281,7 @@ vector v2 = {4, 5, 6}; for (auto i : views::zip_transform(plus(), v1, v2)) { - cout << i << ' '; // prints: 5 7 + cout << i << ' '; // prints \tcode{5 7} } \end{codeblock} \end{example} @@ -9815,7 +9815,7 @@ vector v = {1, 2, 3, 4}; for (auto i : v | views::adjacent<2>) { - cout << "(" << i.first << ", " << i.second << ") "; // prints: (1, 2) (2, 3) (3, 4) + cout << "(" << i.first << ", " << i.second << ") "; // prints \tcode{(1, 2) (2, 3) (3, 4)} } \end{codeblock} \end{example} @@ -10455,7 +10455,7 @@ vector v = {1, 2, 3, 4}; for (auto i : v | views::adjacent_transform<2>(std::multiplies())) { - cout << i << ' '; // prints: 2 6 12 + cout << i << ' '; // prints \tcode{2 6 12} } \end{codeblock} \end{example} @@ -10963,8 +10963,8 @@ } cout << "] "; } +// The above prints \tcode{[1, 2] [3, 4] [5]} \end{codeblock} -The above prints: \tcode{[1, 2] [3, 4] [5]} \end{example} \rSec3[range.chunk.view.input]{\tcode{chunk_view} for input ranges} @@ -11923,7 +11923,7 @@ vector v = {1, 2, 3, 4}; for (auto i : v | views::slide(2)) { - cout << '[' << i[0] << ", " << i[1] << "] "; // prints: [1, 2] [2, 3] [3, 4] + cout << '[' << i[0] << ", " << i[1] << "] "; // prints \tcode{[1, 2] [2, 3] [3, 4]} } \end{codeblock} \end{example} @@ -12581,8 +12581,8 @@ } cout << "] "; } +// The above prints \tcode{[1, 2, 2, 3] [0, 4, 5] [2]} \end{codeblock} -The above prints: \tcode{[1, 2, 2, 3] [0, 4, 5] [2]} \end{example} \rSec3[range.chunk.by.view]{Class template \tcode{chunk_by_view}} From 5fb0fd092782f57e8395841470c92176412a10a3 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Thu, 24 Mar 2022 09:29:07 +0000 Subject: [PATCH 015/430] [expected.un.object.general] Reorder constructors in synopsis This matches the order in [expected.un.ctor]. --- source/utilities.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/utilities.tex b/source/utilities.tex index b85cbf93e1..02616de542 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -6541,12 +6541,12 @@ public: constexpr unexpected(const unexpected&) = default; constexpr unexpected(unexpected&&) = default; + template + constexpr explicit unexpected(Err&&); template constexpr explicit unexpected(in_place_t, Args&&...); template constexpr explicit unexpected(in_place_t, initializer_list, Args&&...); - template - constexpr explicit unexpected(Err&&); constexpr unexpected& operator=(const unexpected&) = default; constexpr unexpected& operator=(unexpected&&) = default; From 8e7a9b9fbf2f7a7dfa913a77068b6a6d3488e521 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Thu, 24 Mar 2022 09:36:55 +0000 Subject: [PATCH 016/430] [expected.un.object] Remove unnecessary subclause nesting All the other class templates in are at the rSec3 level, but std::unexpected is below a mostly useless rSec3 [expected.unexpected]. This subclause has two children, [expected.un.general] which is a single sentence, and [expected.un.object] which defines the class template and its members. If we merge the single sentence from [expected.un.general] into the same subclause as the class synopsis then we can get remove the unnecessary nesting. As a nice side effect, this also gets rid of "object" in the [expected.un.object] stable name, which doesn't really make sense in context. --- source/utilities.tex | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/source/utilities.tex b/source/utilities.tex index 02616de542..9b94554e7e 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -6498,7 +6498,7 @@ \indexlibraryglobal{unexpect}% \begin{codeblock} namespace std { - // \ref{expected.un.object}, class template \tcode{unexpected} + // \ref{expected.unexpected}, class template \tcode{unexpected} template class unexpected; // \ref{expected.bad}, class template \tcode{bad_expected_access} @@ -6521,7 +6521,7 @@ } \end{codeblock} -\rSec2[expected.unexpected]{Unexpected objects} +\rSec2[expected.unexpected]{Class template \tcode{unexpected}} \rSec3[expected.un.general]{General} @@ -6529,10 +6529,6 @@ Subclause \ref{expected.unexpected} describes the class template \tcode{unexpected} that represents unexpected objects stored in \tcode{expected} objects. -\rSec3[expected.un.object]{Class template \tcode{unexpected}} - -\rSec4[expected.un.object.general]{General} - \indexlibraryglobal{unexpected}% \begin{codeblock} namespace std { @@ -6579,7 +6575,7 @@ a cv-qualified type is ill-formed. -\rSec4[expected.un.ctor]{Constructors} +\rSec3[expected.un.ctor]{Constructors} \indexlibraryctor{unexpected}% \begin{itemdecl} @@ -6650,7 +6646,7 @@ Any exception thrown by the initialization of \exposid{val}. \end{itemdescr} -\rSec4[expected.un.obs]{Observers} +\rSec3[expected.un.obs]{Observers} \indexlibrarymember{value}{unexpected}% \begin{itemdecl} @@ -6676,7 +6672,7 @@ \tcode{std::move(\exposid{val})}. \end{itemdescr} -\rSec4[expected.un.swap]{Swap} +\rSec3[expected.un.swap]{Swap} \indexlibrarymember{swap}{unexpected}% \begin{itemdecl} @@ -6708,7 +6704,7 @@ Equivalent to \tcode{x.swap(y)}. \end{itemdescr} -\rSec4[expected.un.eq]{Equality operator} +\rSec3[expected.un.eq]{Equality operator} \indexlibrarymember{operator==}{unexpected}% \begin{itemdecl} From 3372ed0572fd8aa59ed9e59432cd8f593868be49 Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Mon, 25 Apr 2022 13:24:24 -0700 Subject: [PATCH 017/430] [range.utility.conv.general] Strike extraneous semicolon (#5414) --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index 71ce42b194..5f8f72a991 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -2107,7 +2107,7 @@ return back_inserter(c); else return inserter(c, c.end()); -}; +} \end{codeblock} \rSec3[range.utility.conv.to]{\tcode{ranges::to}} From 4b7deb009c4dfbbe8f2c879f764be446f94957b2 Mon Sep 17 00:00:00 2001 From: xmh0511 <970252187@qq.com> Date: Tue, 26 Apr 2022 04:26:19 +0800 Subject: [PATCH 018/430] [lex.ccon] Fix typo in character name for U+0027 (#5412) --- source/lex.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/lex.tex b/source/lex.tex index cefbfa0a35..b29d7c6211 100644 --- a/source/lex.tex +++ b/source/lex.tex @@ -1511,7 +1511,7 @@ \ucode{0007} & \uname{alert} & \tcode{\textbackslash a} \\ \ucode{005c} & \uname{reverse solidus} & \tcode{\textbackslash\textbackslash} \\ \ucode{003f} & \uname{question mark} & \tcode{\textbackslash ?} \\ -\ucode{0027} & \uname{apostrohpe} & \tcode{\textbackslash '} \\ +\ucode{0027} & \uname{apostrophe} & \tcode{\textbackslash '} \\ \ucode{0022} & \uname{quotation mark} & \tcode{\textbackslash "} \\ \end{floattable} From 93de6031da2ef99b402e18ee8941fd6c7b554ce4 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Tue, 26 Apr 2022 14:14:02 +0200 Subject: [PATCH 019/430] [string.view.deduct] Move to immediately after [string.view.cons] (#5397) --- source/strings.tex | 54 +++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/source/strings.tex b/source/strings.tex index d163c25419..82a1cadda1 100644 --- a/source/strings.tex +++ b/source/strings.tex @@ -888,6 +888,33 @@ Any exception thrown by \tcode{ranges::data(r)} and \tcode{ranges::size(r)}. \end{itemdescr} +\rSec3[string.view.deduct]{Deduction guides} + +\begin{itemdecl} +template + basic_string_view(It, End) -> basic_string_view>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item \tcode{It} satisfies \libconcept{contiguous_iterator}. +\item \tcode{End} satisfies \tcode{\libconcept{sized_sentinel_for}}. +\end{itemize} +\end{itemdescr} + +\begin{itemdecl} +template + basic_string_view(R&&) -> basic_string_view>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{R} satisfies \tcode{ranges::\libconcept{contiguous_range}}. +\end{itemdescr} + \rSec3[string.view.iterators]{Iterator support} \indexlibrarymember{const_iterator}{basic_string_view}% @@ -1563,33 +1590,6 @@ Otherwise, returns \tcode{npos}. \end{itemdescr} -\rSec2[string.view.deduct]{Deduction guides} - -\begin{itemdecl} -template - basic_string_view(It, End) -> basic_string_view>; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\constraints -\begin{itemize} -\item \tcode{It} satisfies \libconcept{contiguous_iterator}. -\item \tcode{End} satisfies \tcode{\libconcept{sized_sentinel_for}}. -\end{itemize} -\end{itemdescr} - -\begin{itemdecl} -template - basic_string_view(R&&) -> basic_string_view>; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\constraints -\tcode{R} satisfies \tcode{ranges::\libconcept{contiguous_range}}. -\end{itemdescr} - \rSec2[string.view.comparison]{Non-member comparison functions} \pnum From 41bc0c2ab38c32638685ef9a5068e06abbfc07f3 Mon Sep 17 00:00:00 2001 From: hewillk <67143766+hewillk@users.noreply.github.com> Date: Tue, 26 Apr 2022 20:16:26 +0800 Subject: [PATCH 020/430] [expected] Add missing noexcept for expected::error() (#5381) --- source/utilities.tex | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/source/utilities.tex b/source/utilities.tex index 9b94554e7e..3fa1aff3d2 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -6901,10 +6901,10 @@ constexpr T& value() &; constexpr const T&& value() const &&; constexpr T&& value() &&; - constexpr const E& error() const &; - constexpr E& error() &; - constexpr const E&& error() const &&; - constexpr E&& error() &&; + constexpr const E& error() const & noexcept; + constexpr E& error() & noexcept; + constexpr const E&& error() const && noexcept; + constexpr E&& error() && noexcept; template constexpr T value_or(U&&) const &; template constexpr T value_or(U&&) &&; @@ -7958,10 +7958,10 @@ constexpr void operator*() const noexcept; constexpr void value() const &; constexpr void value() &&; - constexpr const E& error() const &; - constexpr E& error() &; - constexpr const E&& error() const &&; - constexpr E&& error() &&; + constexpr const E& error() const & noexcept; + constexpr E& error() & noexcept; + constexpr const E&& error() const && noexcept; + constexpr E&& error() && noexcept; // \ref{expected.void.eq}, equality operators template requires is_void_v @@ -8445,8 +8445,8 @@ \indexlibrarymember{error}{expected}% \begin{itemdecl} -constexpr const E& error() const &; -constexpr E& error() &; +constexpr const E& error() const & noexcept; +constexpr E& error() & noexcept; \end{itemdecl} \begin{itemdescr} @@ -8461,8 +8461,8 @@ \indexlibrarymember{error}{expected}% \begin{itemdecl} -constexpr E&& error() &&; -constexpr const E&& error() const &&; +constexpr E&& error() && noexcept; +constexpr const E&& error() const && noexcept; \end{itemdecl} \begin{itemdescr} From b075835f134e4956fe27eaa5323655137aff3d45 Mon Sep 17 00:00:00 2001 From: Hui <65944694+huixie90@users.noreply.github.com> Date: Tue, 26 Apr 2022 18:56:30 +0100 Subject: [PATCH 021/430] [iterator.concept.readable] Remove obsolete note (#5408) The note was obsoleted by P1878R1. --- source/iterators.tex | 4 ---- 1 file changed, 4 deletions(-) diff --git a/source/iterators.tex b/source/iterators.tex index 14e44f0150..a81902200a 100644 --- a/source/iterators.tex +++ b/source/iterators.tex @@ -1248,10 +1248,6 @@ \pnum Given a value \tcode{i} of type \tcode{I}, \tcode{I} models \libconcept{indirectly_readable} only if the expression \tcode{*i} is equality-preserving. -\begin{note} -The expression \tcode{*i} is indirectly required to be valid via the -exposition-only \exposconcept{dereferenceable} concept\iref{iterator.synopsis}. -\end{note} \rSec3[iterator.concept.writable]{Concept \cname{indirectly_writable}} From eed51157b2011478eb40254fbf191f2dd5fca7ca Mon Sep 17 00:00:00 2001 From: hewillk <67143766+hewillk@users.noreply.github.com> Date: Tue, 3 May 2022 15:26:39 +0800 Subject: [PATCH 022/430] [expected.object.general] Remove explicit keyword for copy/move constructors (#5380) --- source/utilities.tex | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/utilities.tex b/source/utilities.tex index 3fa1aff3d2..867499110f 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -6843,8 +6843,8 @@ // \ref{expected.object.ctor}, constructors constexpr expected(); - constexpr explicit(@\seebelow@) expected(const expected&); - constexpr explicit(@\seebelow@) expected(expected&&) noexcept(@\seebelow@); + constexpr expected(const expected&); + constexpr expected(expected&&) noexcept(@\seebelow@); template constexpr explicit(@\seebelow@) expected(const expected&); template @@ -7917,8 +7917,8 @@ // \ref{expected.void.ctor}, constructors constexpr expected() noexcept; - constexpr explicit(@\seebelow@) expected(const expected&); - constexpr explicit(@\seebelow@) expected(expected&&) noexcept(@\seebelow@); + constexpr expected(const expected&); + constexpr expected(expected&&) noexcept(@\seebelow@); template constexpr explicit(@\seebelow@) expected(const expected&); template From 3cdcfb67e2cd471c23c107aa7a97f4f0044cdb6c Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Tue, 3 May 2022 23:33:38 -0700 Subject: [PATCH 023/430] [range.transform.iterator] Add some missing \exposid (#5441) --- source/ranges.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index 5f8f72a991..8b35e63536 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -4489,7 +4489,7 @@ \end{codeblock} \pnum -\tcode{iterator::iterator_concept} is defined as follows: +\tcode{\exposid{iterator}::iterator_concept} is defined as follows: \begin{itemize} \item If \exposid{Base} models \libconcept{random_access_range}, then \tcode{iterator_concept} denotes \tcode{random_access_iterator_tag}. @@ -4507,7 +4507,7 @@ The member \grammarterm{typedef-name} \tcode{iterator_category} is defined if and only if \exposid{Base} models \libconcept{forward_range}. In that case, -\tcode{iterator::iterator_category} is defined as follows: +\tcode{\exposid{iterator}::iterator_category} is defined as follows: Let \tcode{C} denote the type \tcode{iterator_traits>::iterator_category}. \begin{itemize} From d23b318949c0a74c6f93f50afb1375ba9eb7aefd Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Wed, 4 May 2022 00:50:55 +0100 Subject: [PATCH 024/430] [stringbuf.virtuals] add "override" to setbuf --- source/iostreams.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/iostreams.tex b/source/iostreams.tex index 9ba1433df9..e386ca8e0f 100644 --- a/source/iostreams.tex +++ b/source/iostreams.tex @@ -8320,7 +8320,7 @@ \indexlibrarymember{setbuf}{basic_streambuf}% \begin{itemdecl} -basic_streambuf* setbuf(charT* s, streamsize n); +basic_streambuf* setbuf(charT* s, streamsize n) override; \end{itemdecl} \begin{itemdescr} From fbe06e9076db0116e395e969f4cb921e45ae964a Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Wed, 4 May 2022 00:51:45 +0100 Subject: [PATCH 025/430] [adjacent.difference] fix grammar typo --- source/algorithms.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/algorithms.tex b/source/algorithms.tex index 4649a95619..edad85f3ab 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -10119,7 +10119,7 @@ For all overloads, in the ranges \crange{first}{last} and \crange{result}{result + (last - first)}, \tcode{binary_op} neither modifies elements - nor invalidate iterators or subranges. + nor invalidates iterators or subranges. \begin{footnote} The use of fully closed ranges is intentional. \end{footnote} From bb8729f3cba593b963031bb25a1a4f12e12ad4fb Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Wed, 4 May 2022 00:52:40 +0100 Subject: [PATCH 026/430] [streambuf.virt.get] fix grammar typo --- source/iostreams.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/iostreams.tex b/source/iostreams.tex index e386ca8e0f..da6060f92b 100644 --- a/source/iostreams.tex +++ b/source/iostreams.tex @@ -3884,7 +3884,7 @@ \tcode{traits::eof()}. Otherwise, returns the value of \tcode{traits::to_int_type(*gptr())} -and increment the value of the next pointer for the input sequence. +and increments the value of the next pointer for the input sequence. \pnum \returns From 6fa045bf939eeff4dcea56e1a84ab7e1aac69f78 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Wed, 4 May 2022 01:12:12 +0100 Subject: [PATCH 027/430] [thread.lock.unique.cons] Use nullptr for null pointer constant --- source/threads.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/threads.tex b/source/threads.tex index b2a90ea8d3..bc359fccee 100644 --- a/source/threads.tex +++ b/source/threads.tex @@ -7062,7 +7062,7 @@ \begin{itemdescr} \pnum \ensures -\tcode{pm == 0} and \tcode{owns == false}. +\tcode{pm == nullptr} and \tcode{owns == false}. \end{itemdescr} \indexlibraryctor{unique_lock}% From f6791f7f9346c007921fec0b406a9edcbf667951 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Wed, 4 May 2022 11:55:03 +0200 Subject: [PATCH 028/430] [syncstream.osyncstream.cons] Fix use of parameter name (#5445) --- source/iostreams.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/iostreams.tex b/source/iostreams.tex index da6060f92b..2cd777e276 100644 --- a/source/iostreams.tex +++ b/source/iostreams.tex @@ -12217,7 +12217,7 @@ \pnum \ensures The value returned by \tcode{get_wrapped()} -is the value returned by \tcode{os.get_wrapped()} +is the value returned by \tcode{other.get_wrapped()} prior to calling this constructor. \tcode{nullptr == other.get_wrapped()} is \tcode{true}. \end{itemdescr} From 74ad79739e2a13022bc6a33ff2e32efe59a47578 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Wed, 4 May 2022 11:55:45 +0200 Subject: [PATCH 029/430] [thread.sema.cnt] Add missing parentheses on function call expression (#5443) --- source/threads.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/threads.tex b/source/threads.tex index bc359fccee..f87cdc3884 100644 --- a/source/threads.tex +++ b/source/threads.tex @@ -9253,7 +9253,7 @@ \effects Repeatedly performs the following steps, in order: \begin{itemize} -\item Evaluates \tcode{try_acquire}. If the result is \tcode{true}, returns. +\item Evaluates \tcode{try_acquire()}. If the result is \tcode{true}, returns. \item \indextext{block (execution)}% Blocks on \tcode{*this} until \tcode{counter} is greater than zero. From 8147026d04fe8fb44ed439cea950b5dab136c04c Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Wed, 4 May 2022 11:56:14 +0200 Subject: [PATCH 030/430] [cons.slice] Add copy constructor for 'slice' to synopsis (#5444) --- source/numerics.tex | 1 + 1 file changed, 1 insertion(+) diff --git a/source/numerics.tex b/source/numerics.tex index 811f7d9d90..a27975bcc0 100644 --- a/source/numerics.tex +++ b/source/numerics.tex @@ -7979,6 +7979,7 @@ public: slice(); slice(size_t, size_t, size_t); + slice(const slice&); size_t start() const; size_t size() const; From fb379c19180d1e26b2b8146d547bcc84c59a0da5 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Wed, 4 May 2022 11:56:50 +0200 Subject: [PATCH 031/430] [over.match.best.general] Fix typo in example (#5446) --- source/overloading.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/overloading.tex b/source/overloading.tex index 516ef0ed39..83fcaa0aa1 100644 --- a/source/overloading.tex +++ b/source/overloading.tex @@ -1809,7 +1809,7 @@ // and \tcode{1L} $\to$ \tcode{short} and \tcode{1L} $\to$ \tcode{int} are indistinguishable Fcn(&i, 'c'); // calls \tcode{Fcn(int*, int)}, because \tcode{\&i} $\to$ \tcode{int*} is better than \tcode{\&i} $\to$ \tcode{const int*} - // and \tcode{c} $\to$ \tcode{int} is better than \tcode{c} $\to$ \tcode{short} + // and \tcode{'c'} $\to$ \tcode{int} is better than \tcode{'c'} $\to$ \tcode{short} } \end{codeblock} \end{example} From 81e506da21960bc70c271f775673a311ec957f6b Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Wed, 4 May 2022 02:59:27 -0700 Subject: [PATCH 032/430] [ranges.syn] remove trailing `-> see below` return type from three `to` overloads (#5419) Since there is actually no return type specification to see below in [range.utility.conv]. --- source/ranges.tex | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index 8b35e63536..81e904f353 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -143,11 +143,11 @@ template requires (!@\libconcept{view}@) constexpr C to(R&& r, Args&&... args); template class C, @\libconcept{input_range}@ R, class... Args> - constexpr auto to(R&& r, Args&&... args) -> @\seebelow@; + constexpr auto to(R&& r, Args&&... args); template requires (!@\libconcept{view}@) - constexpr auto to(Args&&... args) -> @\seebelow@; + constexpr auto to(Args&&... args); template class C, class... Args> - constexpr auto to(Args&&... args) -> @\seebelow@; + constexpr auto to(Args&&... args); // \ref{range.empty}, empty view template From 11d886b5c6062ec7291469514eb07424811e4f65 Mon Sep 17 00:00:00 2001 From: languagelawyer <38548419+languagelawyer@users.noreply.github.com> Date: Tue, 26 Apr 2022 17:39:39 +0300 Subject: [PATCH 033/430] [class.access] Remove dangling Note Invalidated by P1847R4 --- source/classes.tex | 6 ------ 1 file changed, 6 deletions(-) diff --git a/source/classes.tex b/source/classes.tex index fa73256323..0eb897f4e9 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -4482,12 +4482,6 @@ \end{codeblock} \end{example} -\pnum -\begin{note} -The effect of access control on the order of allocation -of data members is specified in~\ref{expr.rel}. -\end{note} - \pnum When a member is redeclared within its class definition, the access specified at its redeclaration shall From 5032e88247bafb5c44dcd4d8ac2ffe3f8bff1bd9 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sat, 23 Apr 2022 22:15:46 +0200 Subject: [PATCH 034/430] [associative] Add "i.e." in front of explanation --- source/containers.tex | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index 258a4e7ffb..8b3dc9b124 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -9444,7 +9444,7 @@ \indexlibraryglobal{map}% \pnum A \tcode{map} is an associative container that -supports unique keys (contains at most one of each key value) and +supports unique keys (i.e., contains at most one of each key value) and provides for fast retrieval of values of another type \tcode{T} based on the keys. The \tcode{map} class supports bidirectional iterators. @@ -10022,7 +10022,7 @@ \indexlibraryglobal{multimap}% A \tcode{multimap} -is an associative container that supports equivalent keys (possibly containing multiple copies of +is an associative container that supports equivalent keys (i.e., possibly containing multiple copies of the same key value) and provides for fast retrieval of values of another type \tcode{T} based on the keys. @@ -10382,7 +10382,7 @@ \indexlibraryglobal{set}% A \tcode{set} -is an associative container that supports unique keys (contains at most one of each key value) and +is an associative container that supports unique keys (i.e., contains at most one of each key value) and provides for fast retrieval of the keys themselves. The \tcode{set} class @@ -10695,7 +10695,7 @@ \indexlibraryglobal{multiset}% A \tcode{multiset} -is an associative container that supports equivalent keys (possibly contains multiple copies of +is an associative container that supports equivalent keys (i.e., possibly contains multiple copies of the same key value) and provides for fast retrieval of the keys themselves. The \tcode{multiset} class From 445d18255713e183df2819e565aa5faa7f85bb1d Mon Sep 17 00:00:00 2001 From: hewillk <67143766+hewillk@users.noreply.github.com> Date: Fri, 1 Apr 2022 22:46:44 +0800 Subject: [PATCH 035/430] [range.utility.conv.general] Add missing constexpr for container-inserter --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index 81e904f353..8a89c6d62c 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -2102,7 +2102,7 @@ Let \exposid{container-inserter} be defined as follows: \begin{codeblock} template -auto @\exposid{container-inserter}@(Container& c) { // \expos +constexpr auto @\exposid{container-inserter}@(Container& c) { // \expos if constexpr (requires { c.push_back(declval()); }) return back_inserter(c); else From 64969e2057ef55b7ac3db8e23c37547edff5c8cf Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 5 May 2022 13:14:25 +0200 Subject: [PATCH 036/430] [intro.memory] Fix missing semicolon in example --- source/basic.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/basic.tex b/source/basic.tex index ab94c86677..76b0e2856f 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -3049,7 +3049,7 @@ :0, d:8; struct {int ee:8;} e; -} +}; \end{codeblock} contains four separate memory locations: The member \tcode{a} and bit-fields \tcode{d} and \tcode{e.ee} are each separate memory locations, and can be From dcf0f144f72e8116c59c188c5057a6ca8a7615d3 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 5 May 2022 13:35:33 +0200 Subject: [PATCH 037/430] [intro.progress] Fix grammar typo --- source/basic.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/basic.tex b/source/basic.tex index 76b0e2856f..e0c932f542 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -6207,7 +6207,7 @@ the implementation ensures that the thread will eventually make progress for as long as it has not terminated. \begin{note} -This is required regardless of whether or not other threads of executions (if any) +This is required regardless of whether or not other threads of execution (if any) have been or are making progress. To eventually fulfill this requirement means that this will happen in an unspecified but finite amount of time. \end{note} From 8c743eacc4b8609650d690b774f855507bd0846f Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 5 May 2022 13:41:54 +0200 Subject: [PATCH 038/430] [expr.prim.lambda.general] Fix missing capture-default in example --- source/expressions.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/expressions.tex b/source/expressions.tex index 16549b12c4..54ac953751 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -1767,7 +1767,7 @@ auto x1 = [](int i) { return i; }; // OK, return type is \tcode{int} auto x2 = []{ return { 1, 2 }; }; // error: deducing return type from \grammarterm{braced-init-list} int j; -auto x3 = []()->auto&& { return j; }; // OK, return type is \tcode{int\&} +auto x3 = [&]()->auto&& { return j; }; // OK, return type is \tcode{int\&} \end{codeblock} \end{example} From 359b8f41027c970bbbc63f1319a890adaa338f6f Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 5 May 2022 16:59:35 +0200 Subject: [PATCH 039/430] [expr.await] Fix English grammar in string-literal in example --- source/expressions.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/expressions.tex b/source/expressions.tex index 54ac953751..ef68570a6f 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -4783,7 +4783,7 @@ my_future h(); my_future g() { - std::cout << "just about go to sleep...\n"; + std::cout << "just about to go to sleep...\n"; co_await 10ms; std::cout << "resumed\n"; co_await h(); From 2cdd8a7fb70e6d91659136cc12388e38a0ae7b1a Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 5 May 2022 17:01:28 +0200 Subject: [PATCH 040/430] [expr.mptr.oper] Fix code indentation in example --- source/expressions.tex | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/expressions.tex b/source/expressions.tex index ef68570a6f..95118a8ad4 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -5960,9 +5960,9 @@ }; void f() { -const S cs; -int S::* pm = &S::i; // \tcode{pm} refers to \keyword{mutable} member \tcode{S::i} -cs.*pm = 88; // error: \tcode{cs} is a const object + const S cs; + int S::* pm = &S::i; // \tcode{pm} refers to \keyword{mutable} member \tcode{S::i} + cs.*pm = 88; // error: \tcode{cs} is a const object } \end{codeblock} \end{note} From 117b352d584cac601c22c63328355658271a6f17 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 5 May 2022 17:05:50 +0200 Subject: [PATCH 041/430] [expr.xor] Fix grammar typo --- source/expressions.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/expressions.tex b/source/expressions.tex index 95118a8ad4..06b0c79719 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -6611,7 +6611,7 @@ of the converted operands \tcode{x} and \tcode{y}, the coefficient $\tcode{r}_i$ of the base-2 representation of the result \tcode{r} -is 1 if either (but not both) of $\tcode{x}_i$ and $\tcode{y}_i$ are 1, +is 1 if either (but not both) of $\tcode{x}_i$ and $\tcode{y}_i$ is 1, and 0 otherwise. \begin{note} The result is the bitwise exclusive \logop{OR} function of the operands. From 980aded4060cb408c053b0ee4620a71f3b6b73c6 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 5 May 2022 17:06:01 +0200 Subject: [PATCH 042/430] [expr.or] Fix grammar typo --- source/expressions.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/expressions.tex b/source/expressions.tex index 06b0c79719..3cb940be38 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -6637,7 +6637,7 @@ of the converted operands \tcode{x} and \tcode{y}, the coefficient $\tcode{r}_i$ of the base-2 representation of the result \tcode{r} -is 1 if at least one of $\tcode{x}_i$ and $\tcode{y}_i$ are 1, and 0 otherwise. +is 1 if at least one of $\tcode{x}_i$ and $\tcode{y}_i$ is 1, and 0 otherwise. \begin{note} The result is the bitwise inclusive \logop{OR} function of the operands. \end{note} From edb43d00ec4f5e98d45c03408b5d0be6b0484c27 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 5 May 2022 17:09:06 +0200 Subject: [PATCH 043/430] [expr.yield] Fix typos in examples --- source/expressions.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/expressions.tex b/source/expressions.tex index 3cb940be38..747e23bacd 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -6900,10 +6900,10 @@ }; my_generator> g1() { - for (int i = i; i < 10; ++i) co_yield {i,i}; + for (int i = 0; i < 10; ++i) co_yield {i,i}; } my_generator> g2() { - for (int i = i; i < 10; ++i) co_yield make_pair(i,i); + for (int i = 0; i < 10; ++i) co_yield make_pair(i,i); } auto f(int x = co_yield 5); // error: \grammarterm{yield-expression} outside of function suspension context From 52de3dca36803413ae219e9ad7430dd0a83a4f16 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 5 May 2022 17:19:35 +0200 Subject: [PATCH 044/430] [dcl.fct.default] Fix indentation in example code --- source/declarations.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/declarations.tex b/source/declarations.tex index 5cbc237f24..8cd154afde 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -4086,8 +4086,8 @@ void h() { a = 2; { - int a = 3; - g(); // \tcode{g(f(::a))} + int a = 3; + g(); // \tcode{g(f(::a))} } } \end{codeblock} From 451d8b95bd4c04bf89a5915eb973f837873c432b Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 5 May 2022 17:20:11 +0200 Subject: [PATCH 045/430] [dcl.fct.default] Fix grammar typo in comment in example --- source/declarations.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/declarations.tex b/source/declarations.tex index 8cd154afde..f2fd22f9c8 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -4119,7 +4119,7 @@ }; void C::f(int i = 3) {} // error: default argument already specified in class scope -void C::g(int i = 88, int j) {} // in this translation unit, \tcode{C::g} can be called with no argument +void C::g(int i = 88, int j) {} // in this translation unit, \tcode{C::g} can be called with no arguments \end{codeblock} \end{example} From cd2690e9ace12f901acce1c1e9157f5cbbf06b24 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 5 May 2022 17:21:32 +0200 Subject: [PATCH 046/430] [dcl.init.aggr] Fix grammar typo in example --- source/declarations.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/declarations.tex b/source/declarations.tex index f2fd22f9c8..a73a788184 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -4583,7 +4583,7 @@ \end{codeblock} is not the declaration of an object of class \tcode{X}, -but the declaration of a function taking no argument and returning an +but the declaration of a function taking no arguments and returning an \tcode{X}. The form \tcode{()} From cbc1a36376f32e9d31d5276ba44d8237d0632c37 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 5 May 2022 17:24:29 +0200 Subject: [PATCH 047/430] [dcl.fct.def.coroutine] Fix grammar typo --- source/declarations.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/declarations.tex b/source/declarations.tex index a73a788184..dad7548445 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -6454,7 +6454,7 @@ \tcode{std::coroutine_traits::promise_type}, where \tcode{R} is the return type of the function, and -$\tcode{P}_1 \dotsc \tcode{P}_n$ are the sequence of types of the non-object function parameters, +$\tcode{P}_1 \dotsc \tcode{P}_n$ is the sequence of types of the non-object function parameters, preceded by the type of the object parameter\iref{dcl.fct} if the coroutine is a non-static member function. The promise type shall be a class type. From d7be2ebee9dd3df849cf87bed768f9bb9f8684f8 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 5 May 2022 17:27:11 +0200 Subject: [PATCH 048/430] [class.copy.ctor] Fix grammar typo --- source/classes.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/classes.tex b/source/classes.tex index 0eb897f4e9..363aa264cc 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -1544,7 +1544,7 @@ A defaulted copy/\brk{}move constructor for a class \tcode{X} is defined as deleted\iref{dcl.fct.def.delete} if \tcode{X} has: \begin{itemize} -\item a potentially constructed subobject type +\item a potentially constructed subobject of type \tcode{M} (or array thereof) that cannot be copied/moved because overload resolution\iref{over.match}, as applied to find \tcode{M}'s From 4284e8c31673912ae92bc210bb39aa4b05f0ed86 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 5 May 2022 17:31:25 +0200 Subject: [PATCH 049/430] [class.expl.init] Fix grammar typo --- source/classes.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/classes.tex b/source/classes.tex index 363aa264cc..acf31c93cf 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -5339,7 +5339,7 @@ is called for the initialization of \tcode{v[1]}, \tcode{complex::complex()} -is called for the initialization +is called for the initialization of \tcode{v[2]}, \tcode{v[4]}, and From 6c0d1411779d9e2c3e9a59d10b09605b6e5f1482 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 5 May 2022 17:35:00 +0200 Subject: [PATCH 050/430] [class.base.init] Fix grammar typo in note --- source/classes.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/classes.tex b/source/classes.tex index acf31c93cf..01332f4534 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -5838,7 +5838,7 @@ \pnum \begin{note} -\ref{class.cdtor} describes the result of virtual function calls, +\ref{class.cdtor} describes the results of virtual function calls, \tcode{typeid} and \keyword{dynamic_cast}s From 40483ba8cff2165cd81dd75718559037af3ecaa8 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 5 May 2022 22:43:03 +0200 Subject: [PATCH 051/430] [over.match.class.deduct] Fix syntax error in example --- source/overloading.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/overloading.tex b/source/overloading.tex index 83fcaa0aa1..08ffc975d5 100644 --- a/source/overloading.tex +++ b/source/overloading.tex @@ -1447,7 +1447,7 @@ template concept deduces_A = requires { sizeof(AA); }; // \tcode{f1} is formed from the constructor \#1 of \tcode{C}, generating the following function template -template +template auto f1(T, U) -> C; // Deducing arguments for \tcode{C} from \tcode{C} deduces \tcode{T} as \tcode{V *} and \tcode{U} as \tcode{V *}; From 04cb8da6485b09592008c82eb330125fbf1034cd Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 5 May 2022 23:15:42 +0200 Subject: [PATCH 052/430] [temp.decls.general] Fix missing comma --- source/templates.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/templates.tex b/source/templates.tex index 65988d76e1..00b0c8c6dd 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -2179,7 +2179,7 @@ which is unrelated to the templated function definition or to any other -default arguments +default arguments, \grammarterm{type-constraint}{s}, \grammarterm{requires-clause}{s}, or From e6633adbb2f3a6590cd75a000b377c8736c65094 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 6 May 2022 00:17:50 +0200 Subject: [PATCH 053/430] [temp.deduct.type] Fix grammar typo --- source/templates.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/templates.tex b/source/templates.tex index 00b0c8c6dd..38d6652dcf 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -8603,7 +8603,7 @@ X x1; // uses primary template X x2; // uses partial specialization; \tcode{ArgTypes} contains \tcode{float}, \tcode{double} X x3; // uses primary template -Y<> y1; // use primary template; \tcode{Types} is empty +Y<> y1; // uses primary template; \tcode{Types} is empty Y y2; // uses partial specialization; \tcode{T} is \tcode{int\&}, \tcode{Types} contains \tcode{float}, \tcode{double} Y y3; // uses primary template; \tcode{Types} contains \tcode{int}, \tcode{float}, \tcode{double} int fv = f(g); // OK; \tcode{Types} contains \tcode{int}, \tcode{float} From 1386c5b2cf41b713a12f526077eb578b68bacb9b Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 6 May 2022 00:19:23 +0200 Subject: [PATCH 054/430] [temp.over] Fix grammar typos --- source/templates.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/templates.tex b/source/templates.tex index 38d6652dcf..710ea797f8 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -8748,11 +8748,11 @@ template void f(T); // declaration void g() { - f("Annemarie"); // call of \tcode{f} + f("Annemarie"); // calls \tcode{f} } \end{codeblock} -The call of +The call to \tcode{f} is well-formed even if the template \tcode{f} From 784d6baa623e50276eacf9f9c7e50b0c6b78c56b Mon Sep 17 00:00:00 2001 From: hewillk <67143766+hewillk@users.noreply.github.com> Date: Tue, 17 May 2022 02:31:43 +0800 Subject: [PATCH 055/430] [range.join.with.view] Add missing \libconcept (#5469) --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index 8a89c6d62c..4cdb34309c 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -6211,7 +6211,7 @@ is_reference_v> { using InnerConstRng = range_reference_t; if constexpr (@\libconcept{forward_range}@ && @\libconcept{forward_range}@ && - @\libconcept{common_range}@ && common_range) + @\libconcept{common_range}@ && @\libconcept{common_range}@) return @\exposid{iterator}@{*this, ranges::end(@\exposid{base_}@)}; else return @\exposid{sentinel}@{*this}; From 565390756df2a38e6afda59a44ab3452b89dfc02 Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Tue, 17 May 2022 21:31:00 -0700 Subject: [PATCH 056/430] [ratio.arithmetic] Add missing index entries (#5472) for `ratio_add`, `ratio_subtract`, `ratio_multiply`, and `ratio_divide`. --- source/meta.tex | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/meta.tex b/source/meta.tex index 6c6d7914fd..cc79c00c14 100644 --- a/source/meta.tex +++ b/source/meta.tex @@ -2507,6 +2507,10 @@ \rSec2[ratio.arithmetic]{Arithmetic on \tcode{ratio}{s}} \pnum +\indexlibraryglobal{ratio_add}% +\indexlibraryglobal{ratio_subtract}% +\indexlibraryglobal{ratio_multiply}% +\indexlibraryglobal{ratio_divide}% Each of the alias templates \tcode{ratio_add}, \tcode{ratio_subtract}, \tcode{ratio_multiply}, and \tcode{ratio_divide} denotes the result of an arithmetic computation on two \tcode{ratio}{s} \tcode{R1} and \tcode{R2}. With \tcode{X} and \tcode{Y} computed (in the From 21dc6d863a5acb0c3e5ec008bddb1c02b3dcd29a Mon Sep 17 00:00:00 2001 From: hewillk <67143766+hewillk@users.noreply.github.com> Date: Thu, 19 May 2022 11:23:47 +0800 Subject: [PATCH 057/430] [range.join.view] Simplify range_reference_t to InnerRng I think this is a reasonable simplification and also makes it consistent with join_with_view. --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index 4cdb34309c..6488957c7e 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -5682,7 +5682,7 @@ constexpr auto begin() { constexpr bool use_const = @\exposconcept{simple-view}@ && - is_reference_v>; + is_reference_v<@\exposid{InnerRng}@>; return @\exposid{iterator}@{*this, ranges::begin(@\exposid{base_}@)}; } From 2101d81b42bfcb7ab2227617a5ebe86e0b5733e8 Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Mon, 23 May 2022 04:39:15 -0700 Subject: [PATCH 058/430] [expected.object.ctor] Use the injected-class-name to refer to the current instantiation (#5485) ... as is conventional in library wording. --- source/utilities.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/utilities.tex b/source/utilities.tex index 867499110f..6ffe2554cd 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -7158,7 +7158,7 @@ \item \tcode{is_same_v, in_place_t>} is \tcode{false}; and \item -\tcode{is_same_v, remove_cvref_t>} is \tcode{false}; and +\tcode{is_same_v>} is \tcode{false}; and \item \tcode{remove_cvref_t} is not a specialization of \tcode{unexpected}; and \item From 3ab2493d9a83efd98023694afae154fa01b5b75c Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Mon, 23 May 2022 23:48:18 -0700 Subject: [PATCH 059/430] [expected.object.general] E should use code font (#5487) --- source/utilities.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/utilities.tex b/source/utilities.tex index 6ffe2554cd..9b90ec1ac4 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -6932,7 +6932,7 @@ a value of type \tcode{E} within its own storage. Implementations are not permitted to use additional storage, such as dynamic memory, -to allocate the object of type \tcode{T} or the object of type E. +to allocate the object of type \tcode{T} or the object of type \tcode{E}. These objects are allocated in a region of the \tcode{expected} storage suitably aligned for the types \tcode{T} and \tcode{E}. Members \exposid{has_val}, \exposid{val}, and \exposid{unex} From 5d1f5702af7539c7e3e949f2413e8e33bb6fd7f9 Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Thu, 26 May 2022 01:35:56 +0800 Subject: [PATCH 060/430] [range.chunk.fwd.iter] Fix unformatted semicolon (#5492) --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index 6488957c7e..5c9c70a489 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -11740,7 +11740,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{return *this += -x}; +Equivalent to: \tcode{return *this += -x;} \end{itemdescr} \begin{itemdecl} From a2cb13f59b1bf8f891c74dadd59b73d88935149b Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Thu, 26 May 2022 15:37:15 +0800 Subject: [PATCH 061/430] [range.chunk.overview,range.chunk.by.overview] Add space in use of range-for loop (#5494) --- source/ranges.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index 5c9c70a489..a37dfe0080 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -10957,7 +10957,7 @@ for (auto r : v | views::chunk(2)) { cout << '['; auto sep = ""; - for(auto i : r) { + for (auto i : r) { cout << sep << i; sep = ", "; } @@ -12575,7 +12575,7 @@ for (auto r : v | views::chunk_by(ranges::less_equal{})) { cout << '['; auto sep = ""; - for(auto i : r) { + for (auto i : r) { cout << sep << i; sep = ", "; } From 31be778d39b144fe867e24d80481786ad012661e Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Sun, 29 May 2022 04:51:06 +0800 Subject: [PATCH 062/430] [ranges] Remove redundant "exposition only" comments in \itemdecl (#5499) --- source/ranges.tex | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index a37dfe0080..a8bac005f5 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -5857,7 +5857,7 @@ empty inner ranges. \begin{itemdecl} -constexpr void @\exposid{satisfy}@(); // \expos +constexpr void @\exposid{satisfy}@(); \end{itemdecl} \begin{itemdescr} @@ -7379,7 +7379,7 @@ \end{itemdescr} \begin{itemdecl} -constexpr subrange> @\exposid{find-next}@(iterator_t it); // \expos +constexpr subrange> @\exposid{find-next}@(iterator_t it); \end{itemdecl} \begin{itemdescr} @@ -8115,7 +8115,7 @@ \indexlibrarymember{\exposid{get-element}}{elements_view::iterator}% \begin{itemdecl} -static constexpr decltype(auto) @\exposid{get-element}@(const iterator_t<@\exposid{Base}@>& i); // \expos +static constexpr decltype(auto) @\exposid{get-element}@(const iterator_t<@\exposid{Base}@>& i); \end{itemdecl} \begin{itemdescr} From e6d6a5c3ab02ea58a2870717ab7f957190566f81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johel=20Ernesto=20Guerrero=20Pe=C3=B1a?= Date: Mon, 30 May 2022 13:20:10 -0400 Subject: [PATCH 063/430] [tuple.cnstr] Fix bad escaping in codeblock (#5501) --- source/utilities.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/utilities.tex b/source/utilities.tex index 9b90ec1ac4..37beb12869 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -1689,7 +1689,7 @@ \end{codeblock} This constructor is defined as deleted if \begin{codeblock} -(reference_constructs_from_temporary_v || ...) +(reference_constructs_from_temporary_v || ...) \end{codeblock} is \tcode{true}. \end{itemdescr} From aff22aca63d0fb4b183cf073de8abfd4b9bb22bd Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Fri, 10 Jun 2022 00:24:11 +0800 Subject: [PATCH 064/430] [range.istream.view] Add reference for basic_istream_view::iterator (#5514) --- source/ranges.tex | 1 + 1 file changed, 1 insertion(+) diff --git a/source/ranges.tex b/source/ranges.tex index a8bac005f5..9289875336 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -3257,6 +3257,7 @@ constexpr default_sentinel_t end() const noexcept; private: + // \ref{range.istream.iterator}, class \tcode{basic_istream_view::\exposid{iterator}} struct @\exposidnc{iterator}@; // \expos basic_istream* @\exposid{stream_}@; // \expos Val @\exposid{value_}@ = Val(); // \expos From 10a20b22491f1ff39a47847a68c9e4a648754d10 Mon Sep 17 00:00:00 2001 From: Mathias Stearn Date: Thu, 9 Jun 2022 18:52:42 +0200 Subject: [PATCH 065/430] [res.on.functions] Use regular "behavior is undefined" words of power (#5513) --- source/lib-intro.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/lib-intro.tex b/source/lib-intro.tex index 6c634b3449..93e3a47587 100644 --- a/source/lib-intro.tex +++ b/source/lib-intro.tex @@ -3172,7 +3172,7 @@ on the implementation. \pnum -In particular, the effects are undefined in the following cases: +In particular, the behavior is undefined in the following cases: \begin{itemize} \item From 4bfa5ddf04586b6df76e0f44e4cde8b59f4a0401 Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Thu, 9 Jun 2022 09:56:29 -0700 Subject: [PATCH 066/430] [range.istream.iterator] basic_istream_view::iterator is not a class template (#5515) --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index 9289875336..c9052488e6 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -3287,7 +3287,7 @@ Equivalent to: \tcode{return default_sentinel;} \end{itemdescr} -\rSec3[range.istream.iterator]{Class template \tcode{basic_istream_view::\exposid{iterator}}} +\rSec3[range.istream.iterator]{Class \tcode{basic_istream_view::\exposid{iterator}}} \indexlibraryglobal{basic_istream_view::iterator}% \begin{codeblock} From f73087971183d1daa992ad5165946609a77d39ff Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sun, 12 Jun 2022 16:18:19 +0200 Subject: [PATCH 067/430] [func.wrap.move.ctor] Fix typo naming template parameter packs (#5517) --- source/utilities.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/utilities.tex b/source/utilities.tex index 37beb12869..c0367901aa 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -12134,7 +12134,7 @@ \constraints \begin{itemize} \item -\tcode{is_constructible_v\&, ArgTypes...>} is +\tcode{is_constructible_v\&, Args...>} is \tcode{true}, and \item \tcode{\exposid{is-callable-from}} is \tcode{true}. @@ -12154,7 +12154,7 @@ \ensures \tcode{*this} has a target object of type \tcode{VT} direct-non-list-initialized with -\tcode{ilist, std::for\-ward(args)...}. +\tcode{ilist, std::for\-ward(args)...}. \pnum \throws From 8d3f43888013437a2870877f00f017860b083df4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johel=20Ernesto=20Guerrero=20Pe=C3=B1a?= Date: Sat, 11 Jun 2022 17:34:09 -0400 Subject: [PATCH 068/430] [range.adjacent.iterator] Use correct descriptive element --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index c9052488e6..a29665d85a 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -10070,7 +10070,7 @@ \begin{itemdescr} \pnum -\expects +\effects Equivalent to: \begin{codeblock} auto tmp = *this; From d86e1ef9ef8514e570fdbbc5038f71e272dbb008 Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Sun, 12 Jun 2022 03:11:07 +0800 Subject: [PATCH 069/430] [ranges.syn] Fix the constraints order of slide_view --- source/ranges.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index a29665d85a..5936705c6f 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -419,8 +419,8 @@ namespace views { inline constexpr @\unspec@ chunk = @\unspec@; } // \ref{range.slide}, slide view - template<@\libconcept{view}@ V> - requires @\libconcept{forward_range}@ + template<@\libconcept{forward_range}@ V> + requires @\libconcept{view}@ class slide_view; template From c4a46fb7343c591f8844c2615ec25cfe8021656a Mon Sep 17 00:00:00 2001 From: hewillk <67143766+hewillk@users.noreply.github.com> Date: Sat, 21 May 2022 20:39:59 +0800 Subject: [PATCH 070/430] [move.iter.cons] Add missing Returns --- source/iterators.tex | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/iterators.tex b/source/iterators.tex index a81902200a..ea655c80ff 100644 --- a/source/iterators.tex +++ b/source/iterators.tex @@ -4279,6 +4279,10 @@ \effects Assigns \tcode{u.current} to \tcode{current}. + +\pnum +\returns +\tcode{*this}. \end{itemdescr} \rSec3[move.iter.op.conv]{Conversion} From fb765c72e737608df7759a9637b951f41e7cc661 Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Tue, 14 Jun 2022 00:04:44 +0800 Subject: [PATCH 071/430] [range.join.with.view] Add missing \libconcept for input_range --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index 5936705c6f..0ceda188d3 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -6179,7 +6179,7 @@ constexpr join_with_view(V base, Pattern pattern); - template + template<@\libconcept{input_range}@ R> requires @\libconcept{constructible_from}@> && @\libconcept{constructible_from}@>> constexpr join_with_view(R&& r, range_value_t<@\exposid{InnerRng}@> e); From 4df3a486c91661d5b4e61d1ec3e0ed7de7721b45 Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Tue, 14 Jun 2022 04:44:10 +0800 Subject: [PATCH 072/430] [range.elements.sentinel] Fix incorrect \placeholder (#5526) --- source/ranges.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index 0ceda188d3..364a24f72d 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -8409,8 +8409,8 @@ \begin{codeblock} namespace std::ranges { template<@\libconcept{input_range}@ V, size_t N> - requires @\libconcept{view}@ && @\placeholder{has-tuple-element}@, N> && - @\placeholder{has-tuple-element}@>, N> && + requires @\libconcept{view}@ && @\exposconcept{has-tuple-element}@, N> && + @\exposconcept{has-tuple-element}@>, N> && @\exposconcept{returnable-element}@, N> template class elements_view::@\exposid{sentinel}@ { From a903e9a3d669437a4826eaccdde4f23d1d3ccb81 Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Tue, 14 Jun 2022 04:56:53 +0800 Subject: [PATCH 073/430] [ranges.syn] Add missing \libconcept for owning_view (#5524) --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index 364a24f72d..4580b3d026 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -214,7 +214,7 @@ inline constexpr bool enable_borrowed_range> = true; // \ref{range.owning.view}, owning view - template + template<@\libconcept{range}@ R> requires @\seebelow@ class owning_view; From 1bc1d28c9f491f5d6e2adc84013f43268bdecf5f Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Wed, 15 Jun 2022 22:21:24 +0800 Subject: [PATCH 074/430] [range.chunk.view.input] Add missing \exposid (#5529) --- source/ranges.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index 4580b3d026..e666c44ce6 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -11041,8 +11041,8 @@ \effects Equivalent to: \begin{codeblock} -current_ = ranges::begin(base_); -remainder_ = n_; +@\exposid{current_}@ = ranges::begin(@\exposid{base_}@); +@\exposid{remainder_}@ = @\exposid{n_}@; return @\exposid{outer-iterator}@(*this); \end{codeblock} \end{itemdescr} From 45498df90fa8fa6ffb4de7341c65a2924de9879c Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Thu, 16 Jun 2022 04:57:27 +0800 Subject: [PATCH 075/430] [range.join.with.sentinel] Add missing curly brace (#5530) --- source/ranges.tex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index e666c44ce6..95763a6578 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -6658,7 +6658,8 @@ template requires @\libconcept{sentinel_for}@, iterator_t<@\exposid{maybe-const}@>> friend constexpr bool operator==(const @\exposid{iterator}@& x, const @\exposid{sentinel}@& y); -}; + }; +} \end{codeblock} \begin{itemdecl} From d78d53f96d076f66a8af4ca7e71ae48e1d0596be Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 16 Jun 2022 13:52:29 +0200 Subject: [PATCH 076/430] [allocator.adaptor.syn] Fix typo in comment in header synopsis --- source/memory.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/memory.tex b/source/memory.tex index 1b5ec82cb3..349c18b115 100644 --- a/source/memory.tex +++ b/source/memory.tex @@ -6311,7 +6311,7 @@ \indexheader{scoped_allocator}% \begin{codeblock} namespace std { - // class template \tcode{scoped allocator adaptor} + // class template \tcode{scoped_allocator_adaptor} template class scoped_allocator_adaptor; From e147bda834b3ba05e5bfe7a43aab831294e5c27c Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 16 Jun 2022 17:29:03 +0200 Subject: [PATCH 077/430] [refwrap.helpers] Remove superfluous space after class template name --- source/utilities.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/utilities.tex b/source/utilities.tex index c0367901aa..55ac126dd0 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -9932,7 +9932,7 @@ \begin{itemdescr} \pnum \returns -\tcode{reference_wrapper (t)}. +\tcode{reference_wrapper(t)}. \end{itemdescr} \indexlibrarymember{cref}{reference_wrapper}% From 01f16bc99a6a89e69b7a6ec5ae8bfe307ec5299a Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 16 Jun 2022 17:33:52 +0200 Subject: [PATCH 078/430] [functional.syn,func.search.default] Fix name of template parameter --- source/utilities.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/utilities.tex b/source/utilities.tex index 55ac126dd0..e09baadb88 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -9511,7 +9511,7 @@ class move_only_function; // \seebelow // \ref{func.search}, searchers - template> + template> class default_searcher; template Date: Thu, 16 Jun 2022 17:35:16 +0200 Subject: [PATCH 079/430] [func.search.bm] Prevent stray hyphen --- source/utilities.tex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/utilities.tex b/source/utilities.tex index e09baadb88..0ee7e8235b 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -12440,7 +12440,8 @@ \tcode{pat_first_} with \tcode{pat_first}, \tcode{pat_last_} with \tcode{pat_last}, \tcode{hash_} with \tcode{hf}, and -\tcode{pred_} with \tcode{pred}. +% FIXME: The mbox prevents TeX from adding a bizarre hyphen after pred_. +\mbox{\tcode{pred_}} with \tcode{pred}. \pnum \throws From 01f07ddd353ce6be936294aa37199929988c7fed Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 16 Jun 2022 17:38:32 +0200 Subject: [PATCH 080/430] [func.search.bmh] Prevent stray hyphen --- source/utilities.tex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/utilities.tex b/source/utilities.tex index 0ee7e8235b..e2998b7fb5 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -12540,7 +12540,8 @@ \tcode{pat_first_} with \tcode{pat_first}, \tcode{pat_last_} with \tcode{pat_last}, \tcode{hash_} with \tcode{hf}, and -\tcode{pred_} with \tcode{pred}. +% FIXME: The mbox prevents TeX from adding a bizarre hyphen after pred_. +\mbox{\tcode{pred_}} with \tcode{pred}. \pnum \throws From 0678f9986b2c1f75e55d596f63876979433522d4 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 16 Jun 2022 17:43:07 +0200 Subject: [PATCH 081/430] [meta.rel] Add parentheses for consistency Parentheses are used for is_pointer_interconvertible_base_of. --- source/meta.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/meta.tex b/source/meta.tex index cc79c00c14..87836cacbe 100644 --- a/source/meta.tex +++ b/source/meta.tex @@ -1419,7 +1419,7 @@ without regard to cv-qualifiers & If \tcode{Base} and \tcode{Derived} are non-union class types and are -not possibly cv-qualified versions of the same type, +not (possibly cv-qualified versions of) the same type, \tcode{Derived} shall be a complete type. \begin{tailnote} From c8a496c62d973305cd6eb5a23d80f169062335fc Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 16 Jun 2022 17:51:57 +0200 Subject: [PATCH 082/430] [string.view.general] Add missing template-argument-list --- source/strings.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/strings.tex b/source/strings.tex index 82a1cadda1..8e9ae733a0 100644 --- a/source/strings.tex +++ b/source/strings.tex @@ -526,7 +526,7 @@ \pnum \begin{note} The library provides implicit conversions from \tcode{const charT*} and \tcode{std::basic_string} to \tcode{std::basic_string_view} so that user code can accept just \tcode{std::basic_string_view} as a non-templated parameter wherever a sequence of characters is expected. -User-defined types can define their own implicit conversions to \tcode{std::basic_string_view} in order to interoperate with these functions. +User-defined types can define their own implicit conversions to \tcode{std::basic_string_view} in order to interoperate with these functions. \end{note} \rSec2[string.view.synop]{Header \tcode{} synopsis} From 70d07925ad874144f2dae4359f5a17c6cada1cdb Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 16 Jun 2022 17:55:30 +0200 Subject: [PATCH 083/430] [forward.list.modifiers] Fix misspelled parameter name --- source/containers.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/containers.tex b/source/containers.tex index 8b3dc9b124..7b3925f5c0 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -7333,7 +7333,7 @@ \begin{itemdescr} \pnum \effects -\tcode{insert_after(p, il.begin(), il.end())}. +\tcode{insert_after(position, il.begin(), il.end())}. \pnum \returns From 66fd28de5c730a271bcf631f8452048c0e709232 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 16 Jun 2022 17:56:48 +0200 Subject: [PATCH 084/430] [set.cons] Fix grammar typo --- source/containers.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/containers.tex b/source/containers.tex index 7b3925f5c0..80f526a083 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -10610,7 +10610,7 @@ \begin{itemdescr} \pnum \effects -Constructs an empty \tcode{set} using the specified comparison objects and allocator. +Constructs an empty \tcode{set} using the specified comparison object and allocator. \pnum \complexity From de6b0e70ffe2da0a0f91ce434863202f78c9e029 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 16 Jun 2022 18:00:21 +0200 Subject: [PATCH 085/430] [unord.map.overview] Fix presentation of member types --- source/containers.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/containers.tex b/source/containers.tex index 80f526a083..1ee59dada4 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -11174,7 +11174,7 @@ of a container\iref{container.reqmts}, of an allocator-aware container\iref{container.alloc.reqmts}, and of an unordered associative container\iref{unord.req}. -It provides the operations described in the preceding requirements table for unique keys; that is, an \tcode{unordered_map} supports the \tcode{a_uniq} operations in that table, not the \tcode{a_eq} operations. For an \tcode{unordered_map} the \tcode{key type} is \tcode{Key}, the mapped type is \tcode{T}, and the value type is \tcode{pair}. +It provides the operations described in the preceding requirements table for unique keys; that is, an \tcode{unordered_map} supports the \tcode{a_uniq} operations in that table, not the \tcode{a_eq} operations. For an \tcode{unordered_map} the \tcode{key_type} is \tcode{Key}, the \tcode{mapped_type} is \tcode{T}, and the \tcode{value_type} is \tcode{pair}. \pnum Subclause~\ref{unord.map} only describes operations on \tcode{unordered_map} that From 5be153e248d9e741c841ff3ab6c2e3714ecba24b Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 17 Jun 2022 08:14:19 +0200 Subject: [PATCH 086/430] [unord.set.overview] Fix presentation of member types --- source/containers.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/containers.tex b/source/containers.tex index 1ee59dada4..68f718b8b4 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -12233,7 +12233,7 @@ of a container\iref{container.reqmts}, of an allocator-aware container\iref{container.alloc.reqmts}, of an unordered associative container\iref{unord.req}. -It provides the operations described in the preceding requirements table for unique keys; that is, an \tcode{unordered_set} supports the \tcode{a_uniq} operations in that table, not the \tcode{a_eq} operations. For an \tcode{unordered_set} the \tcode{key type} and the value type are both \tcode{Key}. The \tcode{iterator} and \tcode{const_iterator} types are both constant iterator types. It is unspecified whether they are the same type. +It provides the operations described in the preceding requirements table for unique keys; that is, an \tcode{unordered_set} supports the \tcode{a_uniq} operations in that table, not the \tcode{a_eq} operations. For an \tcode{unordered_set} the \tcode{key_type} and the \tcode{value_type} are both \tcode{Key}. The \tcode{iterator} and \tcode{const_iterator} types are both constant iterator types. It is unspecified whether they are the same type. \pnum Subclause~\ref{unord.set} only describes operations on \tcode{unordered_set} that From 633178f3fd48a784a96a6610f6b12c10700603c0 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 17 Jun 2022 08:15:22 +0200 Subject: [PATCH 087/430] [unord.multiset.overview] Fix presentation of member types --- source/containers.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/containers.tex b/source/containers.tex index 68f718b8b4..cb49d38930 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -12603,7 +12603,7 @@ It provides the operations described in the preceding requirements table for equivalent keys; that is, an \tcode{unordered_multiset} supports the \tcode{a_eq} operations in that table, not the \tcode{a_uniq} operations. -For an \tcode{unordered_multiset} the \tcode{key type} and the value type are +For an \tcode{unordered_multiset} the \tcode{key_type} and the \tcode{value_type} are both \tcode{Key}. The \tcode{iterator} and \tcode{const_iterator} types are both constant iterator types. It is unspecified whether they are the same type. From c426636bb4b9fdb10bca731c4b18ac78205cef3b Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 17 Jun 2022 08:16:19 +0200 Subject: [PATCH 088/430] [span.syn] Fix formatting of comment in header synopsis --- source/containers.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/containers.tex b/source/containers.tex index cb49d38930..3f7b970be9 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -14307,7 +14307,7 @@ // constants inline constexpr size_t @\libglobal{dynamic_extent}@ = numeric_limits::max(); - // \ref{views.span}, class template span + // \ref{views.span}, class template \tcode{span} template class span; From 5ae534c0c522cf661d3e94c58f54c7d37cf7905a Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 17 Jun 2022 08:18:34 +0200 Subject: [PATCH 089/430] [random.access.iterators] Add semicolon at end of statement --- source/iterators.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/iterators.tex b/source/iterators.tex index ea655c80ff..05c8c62344 100644 --- a/source/iterators.tex +++ b/source/iterators.tex @@ -2319,7 +2319,7 @@ \tcode{b - a} & \tcode{difference_type} & - \tcode{return n} & + \tcode{return n;} & \expects there exists a value \tcode{n} of type \tcode{difference_type} such that \tcode{a + n == b}.\br \tcode{b == a + (b - a)}. \\ \rowsep From f60caf420b5210f0ad284999a1e471d50c424856 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 17 Jun 2022 08:21:11 +0200 Subject: [PATCH 090/430] [range.req.general] Fix grammar typo --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index 95763a6578..7cf3d1fabd 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -1090,7 +1090,7 @@ \rSec2[range.req.general]{General} \pnum -Ranges are an abstraction that allow a \Cpp{} program +Ranges are an abstraction that allows a \Cpp{} program to operate on elements of data structures uniformly. Calling \tcode{ranges::begin} on a range returns an object whose type models \libconcept{input_or_output_iterator}\iref{iterator.concept.iterator}. From 2f628c0f0496c0db858cc2c3651ad6702c37f45b Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 17 Jun 2022 08:23:42 +0200 Subject: [PATCH 091/430] [range.iota.view] Add missing \exposid formatting --- source/ranges.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index 7cf3d1fabd..3bf6f2bbc6 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -2694,7 +2694,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{return iterator\{\exposid{value_}\};} +Equivalent to: \tcode{return \exposid{iterator}\{\exposid{value_}\};} \end{itemdescr} \indexlibrarymember{end}{iota_view}% @@ -2722,7 +2722,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{return iterator\{bound_\};} +Equivalent to: \tcode{return \exposid{iterator}\{\exposid{bound_}\};} \end{itemdescr} \indexlibrarymember{size}{iota_view}% From 2284a691d53a979afb7c805f0aa74f9f463dbb71 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 17 Jun 2022 08:25:52 +0200 Subject: [PATCH 092/430] [range.filter.iterator] Add missing \exposid formatting --- source/ranges.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index 3bf6f2bbc6..1b72bd7d78 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -3970,7 +3970,7 @@ satisfy the filter predicate. \pnum -\tcode{iterator::iterator_concept} is defined as follows: +\tcode{\exposid{iterator}::iterator_concept} is defined as follows: \begin{itemize} \item If \tcode{V} models \libconcept{bidirectional_range}, then \tcode{iterator_concept} denotes \tcode{bidirectional_iterator_tag}. @@ -4032,7 +4032,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{return std::move(current_);} +Equivalent to: \tcode{return std::move(\exposid{current_});} \end{itemdescr} \indexlibrarymember{operator*}{filter_view::iterator}% From 5db44289d94ccf03dfba934a786c744f8412ad9c Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 17 Jun 2022 08:27:04 +0200 Subject: [PATCH 093/430] [range.join.iterator] Add missing \exposid formatting --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index 1b72bd7d78..321277d20d 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -5806,7 +5806,7 @@ \end{codeblock} \pnum -\tcode{iterator::iterator_concept} is defined as follows: +\tcode{\exposid{iterator}::iterator_concept} is defined as follows: \begin{itemize} \item If \exposid{ref-is-glvalue} is \tcode{true}, \exposid{Base} models \libconcept{bidirectional_range}, and From 31c97cf007d569f474c2f06110b96900044e6102 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 17 Jun 2022 08:29:40 +0200 Subject: [PATCH 094/430] [range.transform.iterator] Add missing \exposid formatting --- source/ranges.tex | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index 321277d20d..0907504e8d 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -4573,7 +4573,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{return std::move(current_);} +Equivalent to: \tcode{return std::move(\exposid{current_});} \end{itemdescr} \indexlibrarymember{operator++}{transform_view::iterator}% @@ -4599,7 +4599,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to \tcode{++current_}. +Equivalent to \tcode{++\exposid{current_}}. \end{itemdescr} \indexlibrarymember{operator++}{transform_view::iterator}% @@ -4764,7 +4764,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{return iterator\{*i.\exposid{parent_}, i.\exposid{current_} + n\};} +Equivalent to: \tcode{return \exposid{iterator}\{*i.\exposid{parent_}, i.\exposid{current_} + n\};} \end{itemdescr} \indexlibrarymember{operator-}{transform_view::iterator}% @@ -4776,7 +4776,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{return iterator\{*i.\exposid{parent_}, i.\exposid{current_} - n\};} +Equivalent to: \tcode{return \exposid{iterator}\{*i.\exposid{parent_}, i.\exposid{current_} - n\};} \end{itemdescr} \indexlibrarymember{operator-}{transform_view::iterator}% From 75436ee3dd005cf13153ee05c9174a3a3df0054d Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 17 Jun 2022 08:32:31 +0200 Subject: [PATCH 095/430] [range.take.view] Replace 'struct' with 'class' for consistency --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index 0907504e8d..2b86ce9041 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -4997,7 +4997,7 @@ range_difference_t @\exposid{count_}@ = 0; // \expos // \ref{range.take.sentinel}, class template \tcode{take_view::\exposid{sentinel}} - template struct @\exposid{sentinel}@; // \expos + template class @\exposid{sentinel}@; // \expos public: take_view() requires @\libconcept{default_initializable}@ = default; From 8738cac27de2d66addf735f4fc2b370b73bb9ecc Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 17 Jun 2022 08:33:59 +0200 Subject: [PATCH 096/430] [range.take.while.overview] Highlight use of ranges::begin --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index 2b86ce9041..aa8a1de442 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -5170,7 +5170,7 @@ \pnum Given a unary predicate \tcode{pred} and a \libconcept{view} \tcode{r}, \tcode{take_while_view} produces a \libconcept{view} -of the range \range{begin(r)}{ranges::find_if_not(r, pred)}. +of the range \range{ranges::be\-gin(r)}{ranges::find_if_not(r, pred)}. \indexlibraryglobal{take_while}% \pnum From f487808fd968b13821b43d4ace30557f0e622d7b Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 17 Jun 2022 08:36:05 +0200 Subject: [PATCH 097/430] [range.reverse.view] Add missing \exposid formatting --- source/ranges.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index aa8a1de442..32b915369b 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -7846,7 +7846,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{return make_reverse_iterator(ranges::end(base_));} +Equivalent to: \tcode{return make_reverse_iterator(ranges::end(\exposid{base_}));} \end{itemdescr} \indexlibrarymember{end}{reverse_view}% @@ -7858,7 +7858,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{return make_reverse_iterator(ranges::begin(base_));} +Equivalent to: \tcode{return make_reverse_iterator(ranges::begin(\exposid{base_}));} \end{itemdescr} \rSec2[range.elements]{Elements view} From 2fb9e12890a52cbc8ea0f758f1acecc532f4e4f1 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 17 Jun 2022 08:37:03 +0200 Subject: [PATCH 098/430] [range.elements.iterator] Add missing \exposid formatting --- source/ranges.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index 32b915369b..9c40182579 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -8365,7 +8365,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{return iterator\{x\} += y;} +Equivalent to: \tcode{return \exposid{iterator}\{x\} += y;} \end{itemdescr} \indexlibrarymember{operator+}{elements_view::iterator}% @@ -8389,7 +8389,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{return iterator\{x\} -= y;} +Equivalent to: \tcode{return \exposid{iterator}\{x\} -= y;} \end{itemdescr} \indexlibrarymember{operator-}{elements_view::iterator}% From 51cad172464c89cc14fff19d87d6bba6bc68f61d Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 17 Jun 2022 08:38:54 +0200 Subject: [PATCH 099/430] [algorithms.requirements] Add commas for readability --- source/algorithms.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/algorithms.tex b/source/algorithms.tex index edad85f3ab..b646bd13b7 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -163,10 +163,10 @@ \pnum When not otherwise constrained, the \tcode{BinaryPredicate} parameter is used -whenever an algorithm expects a function object that when applied +whenever an algorithm expects a function object that, when applied to the result of dereferencing two corresponding iterators or to dereferencing an iterator and type \tcode{T} -when \tcode{T} is part of the signature +when \tcode{T} is part of the signature, returns a value testable as \tcode{true}. In other words, if an algorithm takes \tcode{BinaryPredicate binary_pred} as its argument and From 5096e87c6c882ae2aff40c3558db7c2ec95ff4a8 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 17 Jun 2022 08:39:08 +0200 Subject: [PATCH 100/430] [algorithms.requirements] Add hyphen for non-copied --- source/algorithms.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/algorithms.tex b/source/algorithms.tex index b646bd13b7..cd17a1f624 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -208,7 +208,7 @@ Unless otherwise specified, algorithms that take function objects as arguments can copy those function objects freely. If object identity is important, -a wrapper class that points to a noncopied implementation object +a wrapper class that points to a non-copied implementation object such as \tcode{reference_wrapper}\iref{refwrap}, or some equivalent solution, can be used. \end{note} From 63f3e4030497e43f39ff89ec0171f89a11dfc0a7 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 17 Jun 2022 08:41:53 +0200 Subject: [PATCH 101/430] [alg.equal] Add missing period --- source/algorithms.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/algorithms.tex b/source/algorithms.tex index cd17a1f624..7037c1bd98 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -3979,7 +3979,7 @@ \returns If \tcode{last1 - first1 != last2 - first2}, return \tcode{false}. Otherwise return \tcode{true} -if $E$ holds for every iterator \tcode{i} in the range \range{first1}{last1} +if $E$ holds for every iterator \tcode{i} in the range \range{first1}{last1}. Otherwise, returns \tcode{false}. \pnum From 4f62d36b26809765947b44ef3ba9475adce50cfa Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 17 Jun 2022 08:43:16 +0200 Subject: [PATCH 102/430] [alg.copy] Add missing \tcode formatting --- source/algorithms.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/algorithms.tex b/source/algorithms.tex index 7037c1bd98..2fbe3854c1 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -4615,7 +4615,7 @@ into the range \range{result - $N$}{result} starting from \tcode{last - 1} and proceeding to \tcode{first}. \begin{footnote} -\tcode{copy_backward} can be used instead of copy +\tcode{copy_backward} can be used instead of \tcode{copy} when \tcode{last} is in the range \range{result - $N$}{result}. \end{footnote} For each positive integer $n \le N$, From 736c755c70be70d5fb75e71f2c212c3c633ddc34 Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Thu, 23 Jun 2022 14:26:40 -0700 Subject: [PATCH 103/430] [priqueue.overview] Add misssing `>` to deduction guide (#5535) --- source/containers.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/containers.tex b/source/containers.tex index 3f7b970be9..0600166880 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -13530,7 +13530,7 @@ priority_queue(InputIterator, InputIterator, Compare = Compare(), Container = Container()) -> priority_queue<@\exposid{iter-value-type}@, Container, Compare>; - template> + template>> priority_queue(from_range_t, R&&, Compare = Compare()) -> priority_queue, vector>, Compare>; From 3bf6ac52ddd619ae925d32ebb68a90a5bec0c115 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 24 Jun 2022 15:50:30 +0200 Subject: [PATCH 104/430] [class.prop] Clarify definition of implicit-lifetime class (#5319) --- source/classes.tex | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/source/classes.tex b/source/classes.tex index 01332f4534..279a7696b3 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -302,10 +302,14 @@ \end{note} \pnum -A class \tcode{S} is an \defnadj{implicit-lifetime}{class} -if it is an aggregate or -has at least one trivial eligible constructor and +A class \tcode{S} is an \defnadj{implicit-lifetime}{class} if +\begin{itemize} +\item +it is an aggregate or +\item +it has at least one trivial eligible constructor and a trivial, non-deleted destructor. +\end{itemize} \rSec1[class.name]{Class names} \indextext{definition!class name as type}% From e4710acd8314dea04f663160ca8f99296f9b1e03 Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Wed, 6 Jul 2022 20:10:39 +0800 Subject: [PATCH 105/430] [range.elements.view] Add missing \libconcept for move_constructible (#5552) --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index 9c40182579..430d57e237 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -7944,7 +7944,7 @@ template concept @\defexposconcept{returnable-element}@ = // \expos - is_reference_v || move_constructible>; + is_reference_v || @\libconcept{move_constructible}@>; template<@\libconcept{input_range}@ V, size_t N> requires @\libconcept{view}@ && @\exposconcept{has-tuple-element}@, N> && From 3cc3926aac56b2aec198035edffab727a487ce6f Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Fri, 8 Jul 2022 03:30:34 +0800 Subject: [PATCH 106/430] [algorithm.syn,alg.swap] Add missing \libconcept for input_range (#5554) --- source/algorithms.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/algorithms.tex b/source/algorithms.tex index 2fbe3854c1..52b2945e36 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -1318,7 +1318,7 @@ requires @\libconcept{indirectly_swappable}@ constexpr swap_ranges_result swap_ranges(I1 first1, S1 last1, I2 first2, S2 last2); - template<@\libconcept{input_range}@ R1, input_range R2> + template<@\libconcept{input_range}@ R1, @\libconcept{input_range}@ R2> requires @\libconcept{indirectly_swappable}@, iterator_t> constexpr swap_ranges_result, borrowed_iterator_t> swap_ranges(R1&& r1, R2&& r2); @@ -4808,7 +4808,7 @@ requires @\libconcept{indirectly_swappable}@ constexpr ranges::swap_ranges_result ranges::swap_ranges(I1 first1, S1 last1, I2 first2, S2 last2); -template<@\libconcept{input_range}@ R1, input_range R2> +template<@\libconcept{input_range}@ R1, @\libconcept{input_range}@ R2> requires @\libconcept{indirectly_swappable}@, iterator_t> constexpr ranges::swap_ranges_result, borrowed_iterator_t> ranges::swap_ranges(R1&& r1, R2&& r2); From 0e3568368828d3d9b85b7894d64b6bd6fa8e5e62 Mon Sep 17 00:00:00 2001 From: Hewill Kang Date: Fri, 8 Jul 2022 12:17:46 +0800 Subject: [PATCH 107/430] [specialized.algorithms,iterator.concept.readable] Replace \placeholdernc with \exposconcept for exposition-only concepts --- source/algorithms.tex | 54 +++++++++++++++++++++---------------------- source/iterators.tex | 2 +- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/source/algorithms.tex b/source/algorithms.tex index 52b2945e36..b5e850ae17 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -10383,7 +10383,7 @@ \begin{itemdescr} \pnum -A type \tcode{I} models \tcode{\placeholder{nothrow-input-iterator}} only if +A type \tcode{I} models \exposconcept{nothrow-input-iterator} only if no exceptions are thrown from increment, copy construction, move construction, copy assignment, move assignment, @@ -10403,7 +10403,7 @@ \begin{itemdescr} \pnum -Types \tcode{S} and \tcode{I} model \tcode{\placeholder{nothrow-sentinel-for}} +Types \tcode{S} and \tcode{I} model \exposconcept{nothrow-sentinel-for} only if no exceptions are thrown from copy construction, move construction, copy assignment, move assignment, or comparisons between valid values of type \tcode{I} and \tcode{S}. @@ -10419,13 +10419,13 @@ template concept @\defexposconcept{nothrow-input-range}@ = // \expos range && - @\placeholder{nothrow-input-iterator}@> && - @\placeholder{nothrow-sentinel-for}@, iterator_t>; + @\exposconcept{nothrow-input-iterator}@> && + @\exposconcept{nothrow-sentinel-for}@, iterator_t>; \end{itemdecl} \begin{itemdescr} \pnum -A type \tcode{R} models \tcode{\placeholder{nothrow-input-range}} only if +A type \tcode{R} models \exposconcept{nothrow-input-range} only if no exceptions are thrown from calls to \tcode{ranges::begin} and \tcode{ranges::end} on an object of type \tcode{R}. \end{itemdescr} @@ -10433,9 +10433,9 @@ \begin{itemdecl} template concept @\defexposconcept{nothrow-forward-iterator}@ = // \expos - @\placeholder{nothrow-input-iterator}@ && + @\exposconcept{nothrow-input-iterator}@ && @\libconcept{forward_iterator}@ && - @\placeholder{nothrow-sentinel-for}@; + @\exposconcept{nothrow-sentinel-for}@; \end{itemdecl} \begin{itemdescr} @@ -10449,8 +10449,8 @@ \begin{itemdecl} template concept @\defexposconcept{nothrow-forward-range}@ = // \expos - @\placeholder{nothrow-input-range}@ && - @\placeholder{nothrow-forward-iterator}@>; + @\exposconcept{nothrow-input-range}@ && + @\exposconcept{nothrow-forward-iterator}@>; \end{itemdecl} \rSec2[uninitialized.construct.default]{\tcode{uninitialized_default_construct}} @@ -10475,10 +10475,10 @@ \indexlibraryglobal{uninitialized_default_construct}% \begin{itemdecl} namespace ranges { - template<@\placeholdernc{nothrow-forward-iterator}@ I, @\placeholder{nothrow-sentinel-for}@ S> + template<@\exposconcept{nothrow-forward-iterator}@ I, @\exposconcept{nothrow-sentinel-for}@ S> requires @\libconcept{default_initializable}@> I uninitialized_default_construct(I first, S last); - template<@\placeholdernc{nothrow-forward-range}@ R> + template<@\exposconcept{nothrow-forward-range}@ R> requires @\libconcept{default_initializable}@> borrowed_iterator_t uninitialized_default_construct(R&& r); } @@ -10516,7 +10516,7 @@ \indexlibraryglobal{uninitialized_default_construct_n}% \begin{itemdecl} namespace ranges { - template<@\placeholdernc{nothrow-forward-iterator}@ I> + template<@\exposconcept{nothrow-forward-iterator}@ I> requires @\libconcept{default_initializable}@> I uninitialized_default_construct_n(I first, iter_difference_t n); } @@ -10554,10 +10554,10 @@ \indexlibraryglobal{uninitialized_value_construct}% \begin{itemdecl} namespace ranges { - template<@\placeholdernc{nothrow-forward-iterator}@ I, @\placeholder{nothrow-sentinel-for}@ S> + template<@\exposconcept{nothrow-forward-iterator}@ I, @\exposconcept{nothrow-sentinel-for}@ S> requires @\libconcept{default_initializable}@> I uninitialized_value_construct(I first, S last); - template<@\placeholdernc{nothrow-forward-range}@ R> + template<@\exposconcept{nothrow-forward-range}@ R> requires @\libconcept{default_initializable}@> borrowed_iterator_t uninitialized_value_construct(R&& r); } @@ -10595,7 +10595,7 @@ \indexlibraryglobal{uninitialized_value_construct_n}% \begin{itemdecl} namespace ranges { - template<@\placeholdernc{nothrow-forward-iterator}@ I> + template<@\exposconcept{nothrow-forward-iterator}@ I> requires @\libconcept{default_initializable}@> I uninitialized_value_construct_n(I first, iter_difference_t n); } @@ -10643,11 +10643,11 @@ \begin{itemdecl} namespace ranges { template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S1, - @\placeholdernc{nothrow-forward-iterator}@ O, @\placeholder{nothrow-sentinel-for}@ S2> + @\exposconcept{nothrow-forward-iterator}@ O, @\exposconcept{nothrow-sentinel-for}@ S2> requires @\libconcept{constructible_from}@, iter_reference_t> uninitialized_copy_result uninitialized_copy(I ifirst, S1 ilast, O ofirst, S2 olast); - template<@\libconcept{input_range}@ IR, @\placeholdernc{nothrow-forward-range}@ OR> + template<@\libconcept{input_range}@ IR, @\exposconcept{nothrow-forward-range}@ OR> requires @\libconcept{constructible_from}@, range_reference_t> uninitialized_copy_result, borrowed_iterator_t> uninitialized_copy(IR&& in_range, OR&& out_range); @@ -10698,7 +10698,7 @@ \indexlibraryglobal{uninitialized_copy_n}% \begin{itemdecl} namespace ranges { - template<@\libconcept{input_iterator}@ I, @\placeholdernc{nothrow-forward-iterator}@ O, @\placeholder{nothrow-sentinel-for}@ S> + template<@\libconcept{input_iterator}@ I, @\exposconcept{nothrow-forward-iterator}@ O, @\exposconcept{nothrow-sentinel-for}@ S> requires @\libconcept{constructible_from}@, iter_reference_t> uninitialized_copy_n_result uninitialized_copy_n(I ifirst, iter_difference_t n, O ofirst, S olast); @@ -10750,11 +10750,11 @@ \begin{itemdecl} namespace ranges { template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S1, - @\placeholdernc{nothrow-forward-iterator}@ O, @\placeholder{nothrow-sentinel-for}@ S2> + @\exposconcept{nothrow-forward-iterator}@ O, @\exposconcept{nothrow-sentinel-for}@ S2> requires @\libconcept{constructible_from}@, iter_rvalue_reference_t> uninitialized_move_result uninitialized_move(I ifirst, S1 ilast, O ofirst, S2 olast); - template<@\libconcept{input_range}@ IR, @\placeholdernc{nothrow-forward-range}@ OR> + template<@\libconcept{input_range}@ IR, @\exposconcept{nothrow-forward-range}@ OR> requires @\libconcept{constructible_from}@, range_rvalue_reference_t> uninitialized_move_result, borrowed_iterator_t> uninitialized_move(IR&& in_range, OR&& out_range); @@ -10809,7 +10809,7 @@ \indexlibraryglobal{uninitialized_move_n}% \begin{itemdecl} namespace ranges { - template<@\libconcept{input_iterator}@ I, @\placeholdernc{nothrow-forward-iterator}@ O, @\placeholder{nothrow-sentinel-for}@ S> + template<@\libconcept{input_iterator}@ I, @\exposconcept{nothrow-forward-iterator}@ O, @\exposconcept{nothrow-sentinel-for}@ S> requires @\libconcept{constructible_from}@, iter_rvalue_reference_t> uninitialized_move_n_result uninitialized_move_n(I ifirst, iter_difference_t n, O ofirst, S olast); @@ -10860,10 +10860,10 @@ \indexlibraryglobal{uninitialized_fill}% \begin{itemdecl} namespace ranges { - template<@\placeholdernc{nothrow-forward-iterator}@ I, @\placeholder{nothrow-sentinel-for}@ S, class T> + template<@\exposconcept{nothrow-forward-iterator}@ I, @\exposconcept{nothrow-sentinel-for}@ S, class T> requires @\libconcept{constructible_from}@, const T&> I uninitialized_fill(I first, S last, const T& x); - template<@\placeholdernc{nothrow-forward-range}@ R, class T> + template<@\exposconcept{nothrow-forward-range}@ R, class T> requires @\libconcept{constructible_from}@, const T&> borrowed_iterator_t uninitialized_fill(R&& r, const T& x); } @@ -10901,7 +10901,7 @@ \indexlibraryglobal{uninitialized_fill_n}% \begin{itemdecl} namespace ranges { - template<@\placeholdernc{nothrow-forward-iterator}@ I, class T> + template<@\exposconcept{nothrow-forward-iterator}@ I, class T> requires @\libconcept{constructible_from}@, const T&> I uninitialized_fill_n(I first, iter_difference_t n, const T& x); } @@ -10985,10 +10985,10 @@ \indexlibraryglobal{destroy}% \begin{itemdecl} namespace ranges { - template<@\placeholdernc{nothrow-input-iterator}@ I, @\placeholder{nothrow-sentinel-for}@ S> + template<@\exposconcept{nothrow-input-iterator}@ I, @\exposconcept{nothrow-sentinel-for}@ S> requires @\libconcept{destructible}@> constexpr I destroy(I first, S last) noexcept; - template<@\placeholdernc{nothrow-input-range}@ R> + template<@\exposconcept{nothrow-input-range}@ R> requires @\libconcept{destructible}@> constexpr borrowed_iterator_t destroy(R&& r) noexcept; } @@ -11025,7 +11025,7 @@ \indexlibraryglobal{destroy_n}% \begin{itemdecl} namespace ranges { - template<@\placeholdernc{nothrow-input-iterator}@ I> + template<@\exposconcept{nothrow-input-iterator}@ I> requires @\libconcept{destructible}@> constexpr I destroy_n(I first, iter_difference_t n) noexcept; } diff --git a/source/iterators.tex b/source/iterators.tex index 05c8c62344..c552fbd18f 100644 --- a/source/iterators.tex +++ b/source/iterators.tex @@ -1242,7 +1242,7 @@ \begin{codeblock} template concept @\deflibconcept{indirectly_readable}@ = - @\placeholdernc{indirectly-readable-impl}@>; + @\exposconcept{indirectly-readable-impl}@>; \end{codeblock} \pnum From 269177cf3217e31262f0672a8349eff03ce6d6ce Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Sun, 10 Jul 2022 01:21:49 +0800 Subject: [PATCH 108/430] [range.join.with.iterator] Add missing \libconcept and \exposid (#5557) --- source/ranges.tex | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index 430d57e237..fbcd636320 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -6264,7 +6264,7 @@ class join_with_view::@\exposid{iterator}@ { using @\exposid{Parent}@ = @\exposid{maybe-const}@; // \expos using @\exposid{Base}@ = @\exposid{maybe-const}@; // \expos - using @\exposid{InnerBase}@ = range_reference_t; // \expos + using @\exposid{InnerBase}@ = range_reference_t<@\exposid{Base}@>; // \expos using @\exposid{PatternBase}@ = @\exposid{maybe-const}@; // \expos using @\exposid{OuterIter}@ = iterator_t<@\exposid{Base}@>; // \expos @@ -6487,9 +6487,9 @@ \begin{itemdecl} constexpr @\exposid{iterator}@(@\exposid{iterator}@ i) - requires Const && convertible_to, @\exposid{OuterIter}@> && - convertible_to, @\exposid{InnerIter}@> && - convertible_to, @\exposid{PatternIter}@>; + requires Const && @\libconcept{convertible_to}@, @\exposid{OuterIter}@> && + @\libconcept{convertible_to}@, @\exposid{InnerIter}@> && + @\libconcept{convertible_to}@, @\exposid{PatternIter}@>; \end{itemdecl} \begin{itemdescr} From 57cdb995ea0ffd942c93d673aa9d67a8769b2b69 Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Wed, 13 Jul 2022 01:52:57 +0800 Subject: [PATCH 109/430] [unord.map.overview] Replace \tcode with \libconcept for input_range (#5562) --- source/containers.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/containers.tex b/source/containers.tex index 0600166880..c106e15e27 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -11431,7 +11431,7 @@ -> unordered_map<@\placeholder{iter-key-type}@, @\placeholder{iter-mapped-type}@, Hash, equal_to<@\placeholder{iter-key-type}@>, Allocator>; - template + template unordered_map(from_range_t, R&&, typename @\seebelow@::size_type, Allocator) -> unordered_map<@\exposid{range-key-type}@, @\exposid{range-mapped-type}@, hash<@\exposid{range-key-type}@>, equal_to<@\exposid{range-key-type}@>, Allocator>; From 314fa9e2c16bcdaba33febddf2992b3e26c02212 Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Wed, 13 Jul 2022 01:54:20 +0800 Subject: [PATCH 110/430] [sequence.reqmts] Add ranges namespace qualifier for range concepts (#5563) --- source/containers.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index c106e15e27..bf2b4b012c 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -1371,7 +1371,7 @@ from \tcode{*ranges::begin(rg)}. For \tcode{vector}, if \tcode{R} models -neither \libconcept{sized_range} nor \libconcept{forward_range}, +neither \tcode{ranges::\libconcept{sized_range}} nor \tcode{ranges::\libconcept{forward_range}}, \tcode{T} is also \oldconcept{MoveInsertable} into \tcode{X}. \pnum @@ -1727,7 +1727,7 @@ from \tcode{*ranges::begin(rg)}. For \tcode{vector}, if \tcode{R} models -neither \libconcept{sized_range} nor \libconcept{forward_range}, +neither \tcode{ranges::\libconcept{sized_range}} nor \tcode{ranges::\libconcept{forward_range}}, \tcode{T} is also \oldconcept{MoveInsertable} into \tcode{X}. \tcode{rg} and \tcode{a} do not overlap. From 433b7af41ef02b8656c3153ab6ebb1c1c616f5b3 Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Wed, 13 Jul 2022 23:40:21 +0800 Subject: [PATCH 111/430] [range.take.overview] Fix punctuation (#5564) --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index fbcd636320..d40c735595 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -4966,7 +4966,7 @@ then \tcode{ranges::iota_view(*ranges::begin(E), *(ranges::begin(E) + std::\linebreak{}min(ranges::distance(E), F)))}, -except that \tcode{E} is evaluated only once; +except that \tcode{E} is evaluated only once. \item Otherwise, \tcode{ranges::take_view(E, F)}. From 52cd1c2e023fe1c50de79909a44887105668d84a Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Mon, 25 Jul 2022 17:38:51 +0800 Subject: [PATCH 112/430] [range.filter.view] Add missing \exposid (#5646) --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index d40c735595..b3f329454f 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -3902,7 +3902,7 @@ \begin{itemdescr} \pnum \expects -\tcode{pred_.has_value()} is \tcode{true}. +\tcode{\exposid{pred_}.has_value()} is \tcode{true}. \pnum \returns From b2527fa263b52e475379790571477e656ce72c37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johel=20Ernesto=20Guerrero=20Pe=C3=B1a?= Date: Mon, 25 Jul 2022 12:58:32 -0400 Subject: [PATCH 113/430] [range.ref.view] Fix index command (#5648) --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index b3f329454f..a3f5b5cc8d 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -3716,7 +3716,7 @@ } \end{codeblock} -\indexlibraryglobal{ref_view}% +\indexlibraryctor{ref_view}% \begin{itemdecl} template<@\exposconcept{different-from}@ T> requires @\seebelow@ From f6cb84439e8094ec7c67c708d1cc0ddef59262ec Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Tue, 26 Jul 2022 23:09:38 +0800 Subject: [PATCH 114/430] [ranges.syn] Add \ref for `ref_view` (#5652) --- source/ranges.tex | 1 + 1 file changed, 1 insertion(+) diff --git a/source/ranges.tex b/source/ranges.tex index a3f5b5cc8d..4e5c1763a1 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -206,6 +206,7 @@ using all_t = decltype(all(declval())); } + // \ref{range.ref.view}, ref view template<@\libconcept{range}@ R> requires is_object_v class ref_view; From 1033bad71873df6471c9102f4d92bd1e4989aec3 Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Thu, 28 Jul 2022 00:26:01 +0800 Subject: [PATCH 115/430] [concept.booleantestable] Use plain \exposconcept (#5657) --- source/concepts.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/concepts.tex b/source/concepts.tex index ac641ec5ce..6bedb99991 100644 --- a/source/concepts.tex +++ b/source/concepts.tex @@ -981,7 +981,7 @@ \tcode{true_type}\iref{meta.type.synop}, \tcode{int*}, and \tcode{bitset::reference}\iref{template.bitset} -model \exposconceptx{boolean\--testable}{boolean-testable}. +model \exposconcept{boolean-testable}. \end{example} \rSec2[concept.equalitycomparable]{Concept \cname{equality_comparable}} From f244e1c58bae7ed2bccbafe41778e340312bba8e Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Thu, 28 Jul 2022 00:27:03 +0800 Subject: [PATCH 116/430] [concept.equalitycomparable] Use \exposconcept (#5660) --- source/concepts.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/concepts.tex b/source/concepts.tex index 6bedb99991..bdd3512057 100644 --- a/source/concepts.tex +++ b/source/concepts.tex @@ -1005,7 +1005,7 @@ \tcode{const remove_reference_t} and \tcode{const remove_reference_t} respectively. \tcode{T} and \tcode{U} model -\tcode{\placeholder{weakly-equality-comparable-with}} only if +\tcode{\exposconcept{weakly-equality-comparable-with}} only if \begin{itemize} \item \tcode{t == u}, \tcode{u == t}, \tcode{t != u}, and \tcode{u != t} have the same domain. From fff3a59414846fd7ccd032af11510ed412853ef1 Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Fri, 29 Jul 2022 01:05:12 +0800 Subject: [PATCH 117/430] [special.mem.concepts] Add \libconcept (#5668) --- source/algorithms.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/algorithms.tex b/source/algorithms.tex index b5e850ae17..4996e6cec4 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -10418,7 +10418,7 @@ \begin{itemdecl} template concept @\defexposconcept{nothrow-input-range}@ = // \expos - range && + @\libconcept{range}@ && @\exposconcept{nothrow-input-iterator}@> && @\exposconcept{nothrow-sentinel-for}@, iterator_t>; \end{itemdecl} From c816ae797e36daa466c287f3eff445aa87d8bfeb Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Fri, 29 Jul 2022 03:11:43 +0800 Subject: [PATCH 118/430] [istreambuf.iterator.general] Add \ref for proxy (#5669) --- source/iterators.tex | 1 + 1 file changed, 1 insertion(+) diff --git a/source/iterators.tex b/source/iterators.tex index c552fbd18f..0b49fb07bc 100644 --- a/source/iterators.tex +++ b/source/iterators.tex @@ -6225,6 +6225,7 @@ using streambuf_type = basic_streambuf; using istream_type = basic_istream; + // \ref{istreambuf.iterator.proxy}, class \tcode{istreambuf_iterator::\exposid{proxy}} class @\placeholder{proxy}@; // \expos constexpr istreambuf_iterator() noexcept; From d59a4f3392fd1cf87af4ba128518fb4c00cbf77c Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Fri, 29 Jul 2022 03:13:33 +0800 Subject: [PATCH 119/430] [algorithm.syn,bitset.syn,rand.synopsis,valarray.syn] Add \ref for header (#5666) --- source/algorithms.tex | 2 +- source/numerics.tex | 4 ++-- source/utilities.tex | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/algorithms.tex b/source/algorithms.tex index 4996e6cec4..fbe42e26fa 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -616,7 +616,7 @@ \indexheader{algorithm}% \begin{codeblock} -#include +#include // see \ref{initializer.list.syn} namespace std { namespace ranges { diff --git a/source/numerics.tex b/source/numerics.tex index a27975bcc0..8d7df319d7 100644 --- a/source/numerics.tex +++ b/source/numerics.tex @@ -1386,7 +1386,7 @@ \indextext{random number generation!synopsis|(} \begin{codeblock} -#include +#include // see \ref{initializer.list.syn} namespace std { // \ref{rand.req.urng}, uniform random bit generator requirements @@ -6568,7 +6568,7 @@ \rSec2[valarray.syn]{Header \tcode{} synopsis} \indexheader{valarray}% \begin{codeblock} -#include +#include // see \ref{initializer.list.syn} namespace std { template class valarray; // An array of type \tcode{T} diff --git a/source/utilities.tex b/source/utilities.tex index e2998b7fb5..f3bf151ea4 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -8523,7 +8523,7 @@ and manipulating fixed-size sequences of bits. \begin{codeblock} -#include +#include // see \ref{string.syn} #include // for \tcode{istream}\iref{istream.syn}, \tcode{ostream}\iref{ostream.syn}, see \ref{iosfwd.syn} namespace std { From 78b91e849b270423ec3296f7f95666078531e032 Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Sat, 30 Jul 2022 05:13:40 +0800 Subject: [PATCH 120/430] [range.join.with.overview,range.split.overview] use qualified name in examples (#5683) --- source/ranges.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index 4e5c1763a1..c1b1795099 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -6136,7 +6136,7 @@ \begin{example} \begin{codeblock} vector vs = {"the", "quick", "brown", "fox"}; -for (char c : vs | join_with('-')) { +for (char c : vs | views::join_with('-')) { cout << c; } // The above prints \tcode{the-quick-brown-fox} @@ -7278,7 +7278,7 @@ \begin{example} \begin{codeblock} string str{"the quick brown fox"}; -for (string_view word : split(str, ' ')) { +for (string_view word : views::split(str, ' ')) { cout << word << '*'; } // The above prints \tcode{the*quick*brown*fox*} From 616629660570e7395bb21bed7ce2fa9ce8cc5d3b Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Jul 2022 14:29:49 -0700 Subject: [PATCH 121/430] CWG2355 Deducing noexcept-specifiers --- source/compatibility.tex | 18 +++++++ source/templates.tex | 113 ++++++++++++++++++++++++++------------- 2 files changed, 95 insertions(+), 36 deletions(-) diff --git a/source/compatibility.tex b/source/compatibility.tex index 6070af42ea..736962bffa 100644 --- a/source/compatibility.tex +++ b/source/compatibility.tex @@ -55,6 +55,24 @@ // now equivalent to \tcode{arr.operator[](1, 2)} or ill-formed \end{codeblock} +\rSec2[diff.cpp20.temp]{\ref{temp}: templates} + +\diffref{temp.deduct.type} +\change +Deducing template arguments from exception specifications. +\rationale +Facilitate generic handling of throwing and non-throwing functions. +\effect +Valid ISO \CppXX{} code may be ill-formed in this revision of \Cpp{}. +\begin{codeblock} +template struct A { }; +template void f(void (*)(A) noexcept(B)); +void g(A) noexcept; +void h() { + f(g); // ill-formed; previously well-formed +} +\end{codeblock} + \rSec2[diff.cpp20.library]{\ref{library}: library introduction} \diffref{headers} diff --git a/source/templates.tex b/source/templates.tex index 710ea797f8..217c2a693f 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -8013,8 +8013,8 @@ \begin{itemize} \item -A function type includes the types of each of the function parameters -and the return type. +A function type includes the types of each of the function parameters, +the return type, and its exception specification. \item A pointer-to-member type includes the type of the class object pointed to and the type of the member pointed to. @@ -8167,6 +8167,25 @@ } \end{codeblock} +Here is an example where the exception specification of a function type +is deduced: + +\begin{codeblock} +template void f1(void (*)() noexcept(E)); +template struct A { }; +template void f2(void (*)(A) noexcept(B)); + +void g1(); +void g2() noexcept; +void g3(A); + +void h() { + f1(g1); // OK, \tcode{E} is \tcode{false} + f1(g2); // OK, \tcode{E} is \tcode{true} + f2(g3); // error: \tcode{B} deduced as both \tcode{true} and \tcode{false} +} +\end{codeblock} + Here is an example where a qualification conversion applies between the argument type on the function call and the deduced template argument type: @@ -8199,7 +8218,7 @@ A template type argument \tcode{T}, a template template argument -\tcode{TT} +\tcode{TT}, or a template non-type argument \tcode{i} can be deduced if @@ -8208,44 +8227,49 @@ \tcode{A} have one of the following forms: \begin{codeblock} -T -@\cv{}@ T +@\opt{\cv{}}@ T T* T& T&& -T[@\placeholder{integer-constant}@] -@\grammarterm{template-name}@ @\textrm{(where \tcode{\grammarterm{template-name}} refers to a class template)}@ -@\placeholder{type}@(T) -T() -T(T) -T @\placeholder{type}@::* -@\placeholder{type}@ T::* -T T::* -T (@\placeholder{type}@::*)() -@\placeholder{type}@ (T::*)() -@\placeholder{type}@ (@\placeholder{type}@::*)(T) -@\placeholder{type}@ (T::*)(T) -T (@\placeholder{type}@::*)(T) -T (T::*)() -T (T::*)(T) -@\placeholder{type}@[i] -@\grammarterm{template-name}@ @\textrm{(where \tcode{\grammarterm{template-name}} refers to a class template)}@ -TT -TT -TT<> +@\opt{T}@[@\opt{i}@] +@\opt{T}@(@\opt{T}@) noexcept(@\opt{i}@) +@\opt{T}@ @\opt{T}@::* +@\opt{TT}@ +@\opt{TT}@ +@\opt{TT}@ +@\opt{TT}@<> \end{codeblock} where -\tcode{(T)} -represents -a parameter-type-list\iref{dcl.fct} -where at least one parameter type contains a -\tcode{T}, -and -\tcode{()} -represents -a parameter-type-list -where no parameter type contains a -\tcode{T}. +\begin{itemize} +\item +\tcode{\opt{T}} represents a type or parameter-type-list that either +satisfies these rules recursively, +is a non-deduced context in \tcode{P} or \tcode{A}, or +is the same non-dependent type in \tcode{P} and \tcode{A}, + +\item +\tcode{\opt{TT}} represents either a class template or +a template template parameter, + +\item +\tcode{\opt{i}} represents an expression that either +is an \tcode{i}, +is value-dependent in \tcode{P} or \tcode{A}, or +has the same constant value in \tcode{P} and \tcode{A}, and + +\item +\tcode{\keyword{noexcept}(\opt{i})} represents an +exception specification\iref{except.spec} +in which the (possibly-implicit, see~\ref{dcl.fct}) +\grammarterm{noexcept-specifier}'s operand +satisfies the rules for an \tcode{\opt{i}} above. +\end{itemize} + +\begin{note} +If a type matches such a form but contains no +\tcode{T}s, \tcode{i}s, or \tcode{TT}s, deduction is not possible. +\end{note} + Similarly, \tcode{} represents template argument lists where at least one argument contains a @@ -8417,6 +8441,21 @@ \end{codeblock} \end{example} +\pnum +The type of \tcode{B} in the \grammarterm{noexcept-specifier} +\tcode{\keyword{noexcept}(B)} of a function type is \tcode{bool}. +\begin{example} +\begin{codeblock} +template struct A { }; +template struct B; +template struct B { + A ax; +}; +void f_nothrow() noexcept; +B bn; // OK, type of \tcode{X} deduced as \tcode{bool} +\end{codeblock} +\end{example} + \pnum \begin{example} \begin{codeblock} @@ -8509,6 +8548,8 @@ \tcode{true} because the array bound will be nonzero. \end{footnote} +If \tcode{P} has a form that includes \tcode{\keyword{noexcept}(i)} and +the type of \tcode{i} is not \tcode{bool}, deduction fails. \begin{example} \begin{codeblock} template class A { @\commentellip@ }; From ae8340a31a13249cbcdfd54e368a4ddafe1642c1 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Jul 2022 15:02:06 -0700 Subject: [PATCH 122/430] CWG2405 Additional type-dependent expressions --- source/templates.tex | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/source/templates.tex b/source/templates.tex index 217c2a693f..7d58efd994 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -5072,13 +5072,17 @@ Expressions of the following forms are type-dependent only if the type specified by the \grammarterm{type-id}, -\grammarterm{simple-type-specifier} +\grammarterm{simple-type-specifier}, +\grammarterm{typename-specifier}, or \grammarterm{new-type-id} is dependent, even if any subexpression is type-dependent: \begin{ncsimplebnf} simple-type-specifier \terminal{(} \opt{expression-list} \terminal{)}\br +simple-type-specifier braced-init-list\br +typename-specifier \terminal{(} \opt{expression-list} \terminal{)}\br +typename-specifier braced-init-list\br \opt{\terminal{::}} \keyword{new} \opt{new-placement} new-type-id \opt{new-initializer}\br \opt{\terminal{::}} \keyword{new} \opt{new-placement} \terminal{(} type-id \terminal{)} \opt{new-initializer}\br \keyword{dynamic_cast} \terminal{<} type-id \terminal{>} \terminal{(} expression \terminal{)}\br From 18449224780c533cbbe2047e4033c2a0326dd7e4 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Jul 2022 15:05:57 -0700 Subject: [PATCH 123/430] CWG2534 Value category of pseudo-destructor expression --- source/expressions.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/expressions.tex b/source/expressions.tex index 747e23bacd..ba0b7298db 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -3478,7 +3478,7 @@ If the object expression is of scalar type, \tcode{E2} shall name the pseudo-destructor of that same type (ignoring cv-qualifications) and -\tcode{E1.E2} is an lvalue of type ``function of () returning \keyword{void}''. +\tcode{E1.E2} is a prvalue of type ``function of () returning \keyword{void}''. \begin{note} This value can only be used for a notional function call\iref{expr.prim.id.dtor}. From 0a514fcb817eac74c202701a6a4e91a128701266 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Jul 2022 15:27:02 -0700 Subject: [PATCH 124/430] CWG2535 Type punning in class member access --- source/classes.tex | 6 ------ source/expressions.tex | 28 ++++++++++++++++++++++++---- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/source/classes.tex b/source/classes.tex index 279a7696b3..3d224f571b 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -931,12 +931,6 @@ its class or a class derived from its class, or a member thereof, as described below. -\pnum -\indextext{member function!call undefined}% -If a non-static member function of a class \tcode{X} is called for an -object that is not of type \tcode{X}, or of a type derived from -\tcode{X}, the behavior is undefined. - \pnum When an \grammarterm{id-expression}\iref{expr.prim.id} that is not part of a class member access syntax\iref{expr.ref} and not used to form a diff --git a/source/expressions.tex b/source/expressions.tex index ba0b7298db..78ae5a9ae1 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -3561,8 +3561,8 @@ \end{itemize} \pnum -If \tcode{E2} is a non-static data member or a non-static member -function, the program is ill-formed if the class of which \tcode{E2} is +If \tcode{E2} is a non-static member, +the program is ill-formed if the class of which \tcode{E2} is directly a member is an ambiguous base\iref{class.member.lookup} of the naming class\iref{class.access.base} of \tcode{E2}. \begin{note} @@ -3570,6 +3570,24 @@ of the object expression; see~\ref{class.access.base}. \end{note} +\pnum +If \tcode{E2} is a non-static member and +the result of \tcode{E1} is an object whose type +is not similar\iref{conv.qual} to the type of \tcode{E1}, +the behavior is undefined. +\begin{example} +\begin{codeblock} +struct A { int i; }; +struct B { int j; }; +struct D : A, B {}; +void f() { + D d; + static_cast(d).j; // OK, object expression designates the \tcode{B} subobject of \tcode{d} + reinterpret_cast(d).j; // undefined behavior +} +\end{codeblock} +\end{example} + \rSec3[expr.post.incr]{Increment and decrement} \pnum @@ -5939,10 +5957,12 @@ \pnum Abbreviating \grammarterm{pm-expression}\tcode{.*}\grammarterm{cast-expression} as \tcode{E1.*E2}, \tcode{E1} is called the \defn{object expression}. -If the dynamic type of \tcode{E1} does not +If the result of \tcode{E1} is an object +whose type is not similar to the type of \tcode{E1}, or +whose most derived object does not contain the member to which \tcode{E2} refers, the behavior is undefined. -Otherwise, the expression \tcode{E1} is sequenced before the expression \tcode{E2}. +The expression \tcode{E1} is sequenced before the expression \tcode{E2}. \pnum The restrictions on cv-qualification, and the manner in which From cf1f63105cdbf28b0dac0f1160f75afc36c41752 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Jul 2022 15:38:44 -0700 Subject: [PATCH 125/430] CWG2540 Unspecified interpretation of numeric-escape-sequence --- source/lex.tex | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/source/lex.tex b/source/lex.tex index b29d7c6211..ef524f4c00 100644 --- a/source/lex.tex +++ b/source/lex.tex @@ -1464,9 +1464,17 @@ A \grammarterm{character-literal} with a \grammarterm{c-char-sequence} consisting of a single \grammarterm{numeric-escape-sequence} -that specifies an integer value $v$ has a value as follows: +has a value as follows: \begin{itemize} \item +Let $v$ be the integer value represented by +the octal number comprising +the sequence of \grammarterm{octal-digit}{s} in +an \grammarterm{octal-escape-sequence} or by +the hexadecimal number comprising +the sequence of \grammarterm{hexadecimal-digit}{s} in +a \grammarterm{hexadecimal-escape-sequence}. +\item If $v$ does not exceed the range of representable values of the \grammarterm{character-literal}'s type, then the value is $v$. @@ -1922,10 +1930,17 @@ \end{note} \item Each \grammarterm{numeric-escape-sequence}\iref{lex.ccon} -that specifies an integer value $v$ contributes a single code unit with a value as follows: \begin{itemize} \item +Let $v$ be the integer value represented by +the octal number comprising +the sequence of \grammarterm{octal-digit}{s} in +an \grammarterm{octal-escape-sequence} or by +the hexadecimal number comprising +the sequence of \grammarterm{hexadecimal-digit}{s} in +a \grammarterm{hexadecimal-escape-sequence}. +\item If $v$ does not exceed the range of representable values of the \grammarterm{string-literal}'s array element type, then the value is $v$. From 5c96e48415679035c717ddf3e1b3f53b439f5411 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Jul 2022 15:47:17 -0700 Subject: [PATCH 126/430] CWG2571 Evaluation order for subscripting --- source/expressions.tex | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/source/expressions.tex b/source/expressions.tex index 78ae5a9ae1..8ab39e0f75 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -3057,9 +3057,17 @@ A \defnadj{subscript}{expression} is a postfix expression followed by square brackets containing a possibly empty, comma-separated list of \grammarterm{initializer-clause}s -which constitute the arguments to the subscript operator. -The \grammarterm{postfix-expression} is sequenced before -each expression in the \grammarterm{expression-list}. +that constitute the arguments to the subscript operator. +The \grammarterm{postfix-expression} and +the initialization of the object parameter of +any applicable subscript operator function is sequenced before +each expression in the \grammarterm{expression-list} and also before +any default argument. +The initialization of a non-object parameter of +a subscript operator function \tcode{S}\iref{over.sub}, +including every associated value computation and side effect, +is indeterminately sequenced with respect to that of +any other non-object parameter of \tcode{S}. \pnum With the built-in subscript operator, From baeb197c4e32cae5cdd07e2f8ea4b3e00dab6f30 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Jul 2022 15:50:46 -0700 Subject: [PATCH 127/430] CWG2582 Differing member lookup from nested classes [class.member.lookup] Added reference for complete-class context. --- source/basic.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/basic.tex b/source/basic.tex index e0c932f542..1de8db9238 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -1564,7 +1564,7 @@ The result of the search is the declaration set of $S(N,T)$. If it is an invalid set, the program is ill-formed. If it differs from the result of a search in $T$ for $N$ -from immediately after the \grammarterm{class-specifier} of $T$, +in a complete-class context\iref{class.mem} of $T$, the program is ill-formed, no diagnostic required. \begin{example} \begin{codeblock} From 1cd1897305ab7fdcb0a8f2d7e21d1319e17b4d32 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Jul 2022 16:00:45 -0700 Subject: [PATCH 128/430] CWG2585 Name lookup for coroutine allocation --- source/declarations.tex | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/source/declarations.tex b/source/declarations.tex index dad7548445..996be36c21 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -6563,18 +6563,20 @@ The allocation function's name is looked up by searching for it in the scope of the promise type. \begin{itemize} \item -If any declarations are found, +If the search finds any declarations, overload resolution is performed on a function call created by assembling an -argument list. The first argument is the amount of space requested, and has -type \tcode{std::size_t}. -The lvalues $\tcode{p}_1 \dotsc \tcode{p}_n$ are the succeeding arguments. -\item -Otherwise, a search is performed in the global scope. -\end{itemize} +argument list. The first argument is the amount of space requested, and +is a prvalue of type \tcode{std::size_t}. +The lvalues $\tcode{p}_1 \dotsc \tcode{p}_n$ are the successive arguments. If no viable function is found\iref{over.match.viable}, overload resolution is performed again on a function call created by passing just -the amount of space required as an argument of type \tcode{std::size_t}. +the amount of space required as a prvalue of type \tcode{std::size_t}. +\item +If the search finds no declarations, a search is performed in the global scope. +Overload resolution is performed on a function call created by +passing the amount of space required as a prvalue of type \tcode{std::size_t}. +\end{itemize} \pnum If a search for the name \tcode{get_return_object_on_allocation_failure} From acaac256e2a12632930bfd1c112e0518b00d36d9 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Jul 2022 16:05:39 -0700 Subject: [PATCH 129/430] CWG2594 Disallowing a global function template main --- source/basic.tex | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/source/basic.tex b/source/basic.tex index 1de8db9238..b7a8b0102b 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -6382,12 +6382,19 @@ The function \tcode{main} shall not be a coroutine\iref{dcl.fct.def.coroutine}. The \tcode{main} function shall not be declared with a \grammarterm{linkage-specification}\iref{dcl.link}. -A program -that declares a variable \tcode{main} that belongs to the global scope, or -that declares a function \tcode{main} that belongs to the global scope and +A program that declares +\begin{itemize} +\item +a variable \tcode{main} that belongs to the global scope, or +\item +a function \tcode{main} that belongs to the global scope and is attached to a named module, or -that declares an entity named \tcode{main} +\item +a function template \tcode{main} that belongs to the global scope, or +\item +an entity named \tcode{main} with C language linkage (in any namespace) +\end{itemize} is ill-formed. The name \tcode{main} is not otherwise reserved. From 527ad4cf393001c41cc631708b25527a2e22bbb7 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Jul 2022 16:11:08 -0700 Subject: [PATCH 130/430] CWG2597 Replaceable allocation and deallocation functions in the global module --- source/basic.tex | 4 +++- source/modules.tex | 6 ++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/source/basic.tex b/source/basic.tex index b7a8b0102b..582f7bb2c4 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -3829,7 +3829,9 @@ \pnum The library provides default definitions for the global allocation and deallocation functions. Some global allocation and deallocation -functions are replaceable\iref{new.delete}. A \Cpp{} program shall +functions are replaceable\iref{new.delete}; +these are attached to the global module\iref{module.unit}. +A \Cpp{} program shall provide at most one definition of a replaceable allocation or deallocation function. Any such function definition replaces the default version provided in the library\iref{replacement.functions}. The diff --git a/source/modules.tex b/source/modules.tex index cfd4928bb7..05118f0b13 100644 --- a/source/modules.tex +++ b/source/modules.tex @@ -148,10 +148,8 @@ it is attached to the module to which the friend is attached\iref{basic.link}. \item Otherwise, if the declaration \begin{itemize} -\item is a replaceable global allocation or deallocation -function\iref{new.delete.single,new.delete.array}, or -\item is a \grammarterm{namespace-definition} with external linkage, or -\item appears within a \grammarterm{linkage-specification}, +\item is a \grammarterm{namespace-definition} with external linkage or +\item appears within a \grammarterm{linkage-specification}\iref{dcl.link} \end{itemize} it is attached to the global module. From 94931754b6f55217d5ae61644cf380f131a401c1 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Jul 2022 16:13:19 -0700 Subject: [PATCH 131/430] CWG2606 static_cast from "pointer to void" does not handle similar types --- source/expressions.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/expressions.tex b/source/expressions.tex index 8ab39e0f75..89a0b1852c 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -4106,7 +4106,7 @@ \tcode{A} does not satisfy the alignment requirement of \tcode{T}, then the resulting pointer value is unspecified. Otherwise, if the original pointer value points to an object \placeholder{a}, -and there is an object \placeholder{b} of type \tcode{T} (ignoring cv-qualification) +and there is an object \placeholder{b} of type similar to \tcode{T} that is pointer-interconvertible\iref{basic.compound} with \placeholder{a}, the result is a pointer to \placeholder{b}. Otherwise, the pointer value is unchanged by the conversion. From dfa3d7ec2fc971931c71074e9c179a5215022973 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Jul 2022 16:16:25 -0700 Subject: [PATCH 132/430] CWG2608 Omitting an empty template argument list --- source/templates.tex | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/templates.tex b/source/templates.tex index 7d58efd994..f7fd576ae7 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -6830,7 +6830,9 @@ A trailing template parameter pack\iref{temp.variadic} not otherwise deduced will be deduced as an empty sequence of template arguments. \end{note} -If all of the template arguments can be deduced, they may all be omitted; +If all of the template arguments can be +deduced or obtained from default \grammarterm{template-argument}{s}, +they may all be omitted; in this case, the empty template argument list \tcode{<>} itself may also be omitted. \begin{example} From 2ba4c2fec53e6ce6ed50a266726c459c27f9d480 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Jul 2022 16:26:30 -0700 Subject: [PATCH 133/430] CWG2507 Default arguments for operator[] --- source/overloading.tex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/overloading.tex b/source/overloading.tex index 08ffc975d5..938c5d1b1e 100644 --- a/source/overloading.tex +++ b/source/overloading.tex @@ -3292,7 +3292,8 @@ \pnum A \defnadj{subscripting}{operator function} is a function named \tcode{\keyword{operator}[]} -that is a non-static member function. +that is a non-static member function with an arbitrary number of parameters. +It may have default arguments. For an expression of the form \begin{ncsimplebnf} postfix-expression \terminal{[} \opt{expression-list} \terminal{]} From 2ad31290a4b6b314a2c045a9f2c329bf234ae461 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Jul 2022 16:49:29 -0700 Subject: [PATCH 134/430] CWG2586 Explicit object parameter for assignment and comparison --- source/classes.tex | 15 +++++++-------- source/declarations.tex | 36 +++++++++++++++++++++++------------- 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/source/classes.tex b/source/classes.tex index 3d224f571b..3110a48318 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -1678,7 +1678,7 @@ \indextext{operator!move assignment|see{assignment operator, move}}% A user-declared \term{copy} assignment operator \tcode{X::operator=} is a non-static non-template member function of class \tcode{X} with exactly one -parameter of type \tcode{X}, \tcode{X\&}, \tcode{const X\&}, +non-object parameter of type \tcode{X}, \tcode{X\&}, \tcode{const X\&}, \tcode{volatile X\&}, or \tcode{const volatile X\&}. \begin{footnote} Because @@ -1763,7 +1763,7 @@ \pnum A user-declared move assignment operator \tcode{X::operator=} is a non-static non-template member function of class \tcode{X} with exactly -one parameter of type \tcode{X\&\&}, \tcode{const X\&\&}, \tcode{volatile X\&\&}, or +one non-object parameter of type \tcode{X\&\&}, \tcode{const X\&\&}, \tcode{volatile X\&\&}, or \tcode{const volatile X\&\&}. \begin{note} An overloaded assignment operator must be @@ -6457,15 +6457,14 @@ that is \begin{itemize} \item -a non-static const non-volatile member of \tcode{C} having -one parameter of type \tcode{const C\&} and either -no \grammarterm{ref-qualifier} or -the \grammarterm{ref-qualifier} \tcode{\&}, or +a non-static member or friend of \tcode{C} and \item -a friend of \tcode{C} having either +either has two parameters of type \tcode{const C\&} or -two parameters of type \tcode{C}. +two parameters of type \tcode{C}, +where the implicit object parameter (if any) is considered to be +the first parameter. \end{itemize} A comparison operator function for class \tcode{C} that is defaulted on its first declaration and diff --git a/source/declarations.tex b/source/declarations.tex index 996be36c21..3cd7812e32 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -6211,28 +6211,38 @@ \end{itemize} \pnum -The type \tcode{T}$_1$ of an explicitly defaulted special member function \tcode{F} -is allowed to differ from the type \tcode{T}$_2$ it would have had -if it were implicitly declared, as follows: +An explicitly defaulted special member function $\tcode{F}_1$ +with type $\tcode{T}_1$ +is allowed to differ from +the corresponding special member function $\tcode{F}_2$ +with type $\tcode{T}_2$ +that would have been implicitly declared, as follows: \begin{itemize} \item - \tcode{T}$_1$ and \tcode{T}$_2$ may have differing \grammarterm{ref-qualifier}{s}; + $\tcode{T}_1$ and $\tcode{T}_2$ may have differing \grammarterm{ref-qualifier}{s}; \item - \tcode{T}$_1$ and \tcode{T}$_2$ may have differing exception specifications; and + if $\tcode{F}_2$ has an implicit object parameter of + type ``reference to \tcode{C}'', + $\tcode{F}_1$ may be an explicit object member function whose + explicit object parameter is of type ``reference to \tcode{C}''; \item - if \tcode{T}$_2$ has a parameter of type \tcode{const C\&}, - the corresponding parameter of \tcode{T}$_1$ may be of type \tcode{C\&}. + $\tcode{T}_1$ and $\tcode{T}_2$ may have differing exception specifications; and +\item + if $\tcode{F}_2$ has a non-object parameter of type \tcode{const C\&}, + the corresponding non-object parameter of $\tcode{F}_1$ may be of + type \tcode{C\&}. \end{itemize} -If \tcode{T}$_1$ differs from \tcode{T}$_2$ in any other way, then: +If $\tcode{T}_1$ differs from $\tcode{T}_2$ in a way +other than as allowed by the preceding rules, then: \begin{itemize} \item - if \tcode{F} is an assignment operator, and - the return type of \tcode{T}$_1$ differs from - the return type of \tcode{T}$_2$ or - \tcode{T}$_1${'s} parameter type is not a reference, + if $\tcode{F}_1$ is an assignment operator, and + the return type of $\tcode{T}_1$ differs from + the return type of $\tcode{T}_2$ or + $\tcode{F}_1${'s} non-object parameter type is not a reference, the program is ill-formed; \item - otherwise, if \tcode{F} is explicitly defaulted on its first declaration, + otherwise, if $\tcode{F}_1$ is explicitly defaulted on its first declaration, it is defined as deleted; \item otherwise, the program is ill-formed. From 53cf988805d116e055e93938c525fd7cde16543d Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Mon, 25 Jul 2022 21:44:54 +0200 Subject: [PATCH 135/430] P2468R2 The Equality Operator You Are Looking For --- source/modules.tex | 12 +++++++++-- source/overloading.tex | 49 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/source/modules.tex b/source/modules.tex index 05118f0b13..075f05e62c 100644 --- a/source/modules.tex +++ b/source/modules.tex @@ -606,11 +606,19 @@ \item $S$ contains a dependent call \tcode{E}\iref{temp.dep} -and $D$ is found by name lookup for the dependent name -in an expression synthesized from \tcode{E} +and $D$ is found by any name lookup performed +for an expression synthesized from \tcode{E} by replacing each type-dependent argument or operand with a value of a placeholder type with no associated namespaces or entities, or +\begin{note} +This includes the lookup for \tcode{\keyword{operator}==} performed +when considering rewriting an \tcode{!=} expression, +the lookup for \tcode{\keyword{operator}<=>} +performed when considering rewriting a relational comparison, and +the lookup for \tcode{\keyword{operator}!=} +when considering whether an \tcode{\keyword{operator}==} is a rewrite target. +\end{note} \item $S$ contains an expression that diff --git a/source/overloading.tex b/source/overloading.tex index 938c5d1b1e..18f26832e7 100644 --- a/source/overloading.tex +++ b/source/overloading.tex @@ -755,13 +755,15 @@ For the \tcode{!=} operator\iref{expr.eq}, the rewritten candidates include all non-rewritten candidates -for the expression \tcode{x == y}. +for the expression \tcode{x == y} +that are rewrite targets with first operand \tcode{x} (see below). \item For the equality operators, the rewritten candidates also include a synthesized candidate, with the order of the two parameters reversed, for each non-rewritten candidate -for the expression \tcode{y == x}. +for the expression \tcode{y == x} +that is a rewrite target with first operand \tcode{y}. \item For all other operators, the rewritten candidate set is empty. \end{itemize} @@ -772,6 +774,49 @@ \end{note} \end{itemize} +\pnum +A non-template function or function template \tcode{F} named \tcode{\keyword{operator}==} +is a rewrite target with first operand \tcode{o} +unless a search for the name \tcode{\keyword{operator}!=} in the scope $S$ +from the instantiation context of the operator expression +finds a function or function template +that would correspond\iref{basic.scope.scope} to \tcode{F} +if its name were \tcode{\keyword{operator}==}, +where $S$ is the scope of the class type of \tcode{o} +if \tcode{F} is a class member, and +the namespace scope of which \tcode{F} is a member otherwise. +A function template specialization named \tcode{\keyword{operator}==} is a rewrite target +if its function template is a rewrite target. +\begin{example} +\begin{codeblock} +struct A {}; +template bool operator==(A, T); // \#1 +bool a1 = 0 == A(); // OK, calls reversed \#1 +template bool operator!=(A, T); +bool a2 = 0 == A(); // error, \#1 is not a rewrite target + +struct B { + bool operator==(const B&); // \#2 +}; +struct C : B { + C(); + C(B); + bool operator!=(const B&); // \#3 +}; +bool c1 = B() == C(); // OK, calls \#2; reversed \#2 is not a candidate + // because search for \tcode{\keyword{operator}!=} in \tcode{C} finds \#3 +bool c2 = C() == B(); // error: ambiguous between \#2 found when searching \tcode{C} and + // reversed \#2 found when searching \tcode{B} + +struct D {}; +template bool operator==(D, T); // \#4 +inline namespace N { + template bool operator!=(D, T); // \#5 +} +bool d1 = 0 == D(); // OK, calls reversed \#4; \#5 does not forbid \#4 as a rewrite target +\end{codeblock} +\end{example} + \pnum For the built-in assignment operators, conversions of the left operand are restricted as follows: From 0aebf5cacded1b64cf089dbc7a0504fbb9f50aa6 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Mon, 25 Jul 2022 22:10:33 +0200 Subject: [PATCH 136/430] P2327R1 De-deprecating volatile compound operations --- source/expressions.tex | 6 ++++-- source/future.tex | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/source/expressions.tex b/source/expressions.tex index 89a0b1852c..07fad83978 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -7067,7 +7067,7 @@ \impldefplain{value of bit-field that cannot represent!assigned value}. \pnum -A simple assignment whose left operand is of +An assignment whose left operand is of a volatile-qualified type is deprecated\iref{depr.volatile.type} unless the (possibly parenthesized) assignment is a discarded-value expression or an unevaluated operand\iref{term.unevaluated.operand}. @@ -7077,7 +7077,9 @@ is equivalent to \tcode{E1 = E1 \placeholder{op} E2} except that \tcode{E1} is evaluated only once. Such expressions are deprecated -if \tcode{E1} has volatile-qualified type; see~\ref{depr.volatile.type}. +if \tcode{E1} has volatile-qualified type +and \placeholder{op} is not one of the bitwise operators +\tcode{|}, \tcode{\&}, \tcode{\~}; see~\ref{depr.volatile.type}. For \tcode{+=} and \tcode{-=}, \tcode{E1} shall either have arithmetic type or be a pointer to a possibly cv-qualified completely-defined object type. In all other diff --git a/source/future.tex b/source/future.tex index b1c352078f..609e7cfceb 100644 --- a/source/future.tex +++ b/source/future.tex @@ -106,6 +106,7 @@ tail = brachiosaur = neck; // deprecated brachiosaur += neck; // deprecated brachiosaur = brachiosaur + neck; // OK +brachiosaur |= neck; // OK, bitwise compound expression \end{codeblock} \end{example} From 1de58fc3d06c157da68036f4b9112f5176f4c556 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Mon, 25 Jul 2022 22:26:24 +0200 Subject: [PATCH 137/430] P2437R1 Support for #warning --- source/preprocessor.tex | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/source/preprocessor.tex b/source/preprocessor.tex index 7528bd6c83..1362638193 100644 --- a/source/preprocessor.tex +++ b/source/preprocessor.tex @@ -56,6 +56,7 @@ \terminal{\# undef } identifier new-line\br \terminal{\# line } pp-tokens new-line\br \terminal{\# error } \opt{pp-tokens} new-line\br + \terminal{\# warning} \opt{pp-tokens} new-line\br \terminal{\# pragma } \opt{pp-tokens} new-line\br \terminal{\# }new-line \end{bnf} @@ -1603,18 +1604,21 @@ one of the two previous forms, the behavior is undefined; otherwise, the result is processed as appropriate. -\rSec1[cpp.error]{Error directive}% +\rSec1[cpp.error]{Diagnostic directives}% \indextext{preprocessing directive!error}% +\indextext{preprocessing directive!diagnostic}% +\indextext{preprocessing directive!warning}% \indextext{\idxcode{\#error}|see{preprocessing directive, error}} \pnum -A preprocessing directive of the form +A preprocessing directive of either of the following forms \begin{ncsimplebnf} -\terminal{\# error} \opt{pp-tokens} new-line +\terminal{\# error} \opt{pp-tokens} new-line\br +\terminal{\# warning} \opt{pp-tokens} new-line \end{ncsimplebnf} causes the implementation to produce -a diagnostic message that should include the specified sequence of preprocessing tokens, -and renders the program ill-formed. +a diagnostic message that should include the specified sequence of preprocessing tokens; +the \tcode{\# error} directive renders the program ill-formed. \rSec1[cpp.pragma]{Pragma directive}% \indextext{preprocessing directive!pragma}% From 0bf84a355cd4006bfe555e8ea744cd088407a191 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Tue, 26 Jul 2022 08:55:23 +0200 Subject: [PATCH 138/430] P2362R3 Remove non-encodable wide character literals and multicharacter wide character literals --- source/lex.tex | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/source/lex.tex b/source/lex.tex index ef524f4c00..dedea4ad6d 100644 --- a/source/lex.tex +++ b/source/lex.tex @@ -1356,7 +1356,7 @@ more than one \grammarterm{c-char}. The \grammarterm{encoding-prefix} of a non-encodable character literal or a multicharacter literal -shall be absent or \tcode{L}. +shall be absent. Such \grammarterm{character-literal}s are conditionally-supported. \pnum @@ -1367,17 +1367,17 @@ as defined by \tref{lex.ccon.literal}. The special cases for non-encodable character literals and multicharacter literals -take precedence over their respective base kinds. +take precedence over the base kind. \begin{note} -The associated character encoding for ordinary and wide character literals +The associated character encoding for ordinary character literals determines encodability, but does not determine the value of -non-encodable ordinary or wide character literals or -ordinary or wide multicharacter literals. +non-encodable ordinary character literals or +ordinary multicharacter literals. The examples in \tref{lex.ccon.literal} -for non-encodable ordinary and wide character literals assume that +for non-encodable ordinary character literals assume that the specified character lacks representation in -the ordinary literal encoding or wide literal encoding, respectively, or +the ordinary literal encoding or that encoding the character would require more than one code unit. \end{note} @@ -1405,18 +1405,9 @@ \tcode{L} & \defnx{wide character literal}{literal!character!wide} & \keyword{wchar_t} & -wide & -\tcode{L'w'} \\ \cline{2-3}\cline{5-5} - & -non-encodable wide character literal & -\keyword{wchar_t} & -literal & -\tcode{L'\textbackslash U0001F32A'} \\ \cline{2-3}\cline{5-5} - & -wide multicharacter literal & -\keyword{wchar_t} & -encoding & -\tcode{L'abcd'} \\ \hline +wide literal & +\tcode{L'w'} \\ + & & & encoding & \\ \hline \tcode{u8} & \defnx{UTF-8 character literal}{literal!character!UTF-8} & \keyword{char8_t} & From aab09dc7fcbc0e9a1008126604288c50fa5e8234 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Tue, 26 Jul 2022 09:22:52 +0200 Subject: [PATCH 139/430] P2324R2 Labels at the end of compound statements (C compatibility) --- source/statements.tex | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/source/statements.tex b/source/statements.tex index 65b4534ee1..3aff25a9b7 100644 --- a/source/statements.tex +++ b/source/statements.tex @@ -117,19 +117,25 @@ \grammarterm{decl-specifier} shall be either a \grammarterm{type-specifier} or \keyword{constexpr}. -\rSec1[stmt.label]{Labeled statement}% +\rSec1[stmt.label]{Label}% \indextext{statement!labeled} \pnum \indextext{statement!labeled}% \indextext{\idxcode{:}!label specifier}% -A statement can be labeled. +A label can be added to a statement or +used anywhere in a \grammarterm{compound-statement}. + +\begin{bnf} +\nontermdef{label}\br + \opt{attribute-specifier-seq} identifier \terminal{:}\br + \opt{attribute-specifier-seq} \keyword{case} constant-expression \terminal{:}\br + \opt{attribute-specifier-seq} \keyword{default} \terminal{:} +\end{bnf} \begin{bnf} \nontermdef{labeled-statement}\br - \opt{attribute-specifier-seq} identifier \terminal{:} statement\br - \opt{attribute-specifier-seq} \keyword{case} constant-expression \terminal{:} statement\br - \opt{attribute-specifier-seq} \keyword{default} \terminal{:} statement + label statement \end{bnf} The optional \grammarterm{attribute-specifier-seq} appertains to the label. @@ -139,7 +145,7 @@ \indextext{label!scope of}% No two labels in a function shall have the same \grammarterm{identifier}. A label can be used in a \tcode{goto} statement -before its introduction by a \grammarterm{labeled-statement}. +before its introduction. \pnum \indextext{label!\idxcode{case}}% @@ -169,8 +175,7 @@ a \defn{null statement}. \begin{note} Most statements are expression statements --- usually assignments or -function calls. A null statement is useful to carry a label just before -the \tcode{\}} of a compound statement and to supply a null body to an +function calls. A null statement is useful to supply a null body to an iteration statement such as a \keyword{while} statement\iref{stmt.while}. \end{note} @@ -184,7 +189,7 @@ \begin{bnf} \nontermdef{compound-statement}\br - \terminal{\{} \opt{statement-seq} \terminal{\}} + \terminal{\{} \opt{statement-seq} \opt{label-seq} \terminal{\}} \end{bnf} \begin{bnf} @@ -193,6 +198,16 @@ statement-seq statement \end{bnf} +\begin{bnf} +\nontermdef{label-seq}\br + label\br + label-seq label +\end{bnf} + +A label at the end of a \grammarterm{compound-statement} +is treated as if it were followed by a null statement. + +\pnum \begin{note} A compound statement defines a block scope\iref{basic.scope}. A declaration is a \grammarterm{statement}\iref{stmt.dcl}. From 2ba2fbbf0bb33af9d47b4bc77a8dd7f1b5e495a8 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Tue, 26 Jul 2022 17:27:52 +0200 Subject: [PATCH 140/430] P2290R3 Delimited escape sequences --- source/lex.tex | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/source/lex.tex b/source/lex.tex index dedea4ad6d..7fb88c4f94 100644 --- a/source/lex.tex +++ b/source/lex.tex @@ -293,10 +293,17 @@ hexadecimal-digit hexadecimal-digit hexadecimal-digit hexadecimal-digit \end{bnf} +\begin{bnf} +\nontermdef{simple-hexadecimal-digit-sequence}\br + hexadecimal-digit\br + simple-hexadecimal-digit-sequence hexadecimal-digit +\end{bnf} + \begin{bnf} \nontermdef{universal-character-name}\br \terminal{\textbackslash u} hex-quad\br - \terminal{\textbackslash U} hex-quad hex-quad + \terminal{\textbackslash U} hex-quad hex-quad\br + \terminal{\textbackslash u\{} simple-hexadecimal-digit-sequence \terminal{\}} \end{bnf} A \grammarterm{universal-character-name} @@ -1310,17 +1317,25 @@ hexadecimal-escape-sequence \end{bnf} +\begin{bnf} +\nontermdef{simple-octal-digit-sequence}\br + octal-digit\br + simple-octal-digit-sequence octal-digit +\end{bnf} + \begin{bnf} \nontermdef{octal-escape-sequence}\br \terminal{\textbackslash} octal-digit\br \terminal{\textbackslash} octal-digit octal-digit\br - \terminal{\textbackslash} octal-digit octal-digit octal-digit + \terminal{\textbackslash} octal-digit octal-digit octal-digit\br + \terminal{\textbackslash o\{} simple-octal-digit-sequence \terminal{\}}\br \end{bnf} \begin{bnf} \nontermdef{hexadecimal-escape-sequence}\br \terminal{\textbackslash x} hexadecimal-digit\br - hexadecimal-escape-sequence hexadecimal-digit + hexadecimal-escape-sequence hexadecimal-digit\br + \terminal{\textbackslash x\{} simple-hexadecimal-digit-sequence \terminal{\}} \end{bnf} \begin{bnf} @@ -1330,7 +1345,7 @@ \begin{bnf} \nontermdef{conditional-escape-sequence-char}\br - \textnormal{any member of the basic character set that is not an} octal-digit\textnormal{, a} simple-escape-sequence-char\textnormal{, or the characters \terminal{u}, \terminal{U}, or \terminal{x}} + \textnormal{any member of the basic character set that is not an} octal-digit\textnormal{, a} simple-escape-sequence-char\textnormal{, or the characters \terminal{o}, \terminal{u}, \terminal{U}, or \terminal{x}} \end{bnf} \pnum From 1557a453a3680a83d56de707a0df6a67c3b2a08d Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Tue, 26 Jul 2022 18:20:04 +0200 Subject: [PATCH 141/430] P2448R2 Relaxing some constexpr restrictions --- source/classes.tex | 57 ++----------------------- source/declarations.tex | 94 +++-------------------------------------- source/preprocessor.tex | 2 +- 3 files changed, 12 insertions(+), 141 deletions(-) diff --git a/source/classes.tex b/source/classes.tex index 3110a48318..9ec3133300 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -1092,13 +1092,6 @@ and, if the class is not abstract\iref{class.abstract}, its virtual base classes are called its \term{potentially constructed subobjects}. -\pnum -A defaulted special member function is -\indextext{member function!constexpr-compatible}% -\defnx{constexpr-compatible}{constexpr-compatible!defaulted special member function} -if the corresponding implicitly-declared special member function -would be a constexpr function. - \rSec2[class.ctor]{Constructors}% \rSec3[class.ctor.general]{General}% @@ -1314,7 +1307,7 @@ If that user-written default constructor would be ill-formed, the program is ill-formed. If that user-written default constructor would satisfy the requirements -of a constexpr constructor\iref{dcl.constexpr}, the implicitly-defined +of a constexpr function\iref{dcl.constexpr}, the implicitly-defined default constructor is \keyword{constexpr}. Before the defaulted default constructor for a class is implicitly defined, @@ -1611,7 +1604,7 @@ its odr-use\iref{term.odr.use,class.temporary}. \end{note} If the implicitly-defined constructor would satisfy the requirements of a -constexpr constructor\iref{dcl.constexpr}, the implicitly-defined +constexpr function\iref{dcl.constexpr}, the implicitly-defined constructor is \keyword{constexpr}. \pnum @@ -1911,20 +1904,7 @@ to assign to an object of its class type), when it is needed for constant evaluation\iref{expr.const}, or when it is explicitly defaulted after its first declaration. -The implicitly-defined copy/move assignment operator is \keyword{constexpr} if -\begin{itemize} -\item -\tcode{X} is a literal type, and - -\item -the assignment operator selected to copy/move each direct base class subobject -is a constexpr function, and - -\item -for each non-static data member of \tcode{X} that is of class type (or array -thereof), the assignment operator selected to copy/move that member is a -constexpr function. -\end{itemize} +The implicitly-defined copy/move assignment operator is \keyword{constexpr}. \pnum Before the defaulted copy/move assignment operator for a class is @@ -2132,7 +2112,7 @@ \pnum A defaulted destructor is a constexpr destructor -if it satisfies the requirements for a constexpr destructor\iref{dcl.constexpr}. +if it satisfies the requirements for a constexpr function\iref{dcl.constexpr}. \pnum A destructor @@ -6503,35 +6483,6 @@ \tcode{a @ b} is a valid expression. \end{itemize} -\pnum -A defaulted comparison function is -\indextext{operator!comparison!constexpr-compatible}% -\defnx{constexpr-compatible}{constexpr-compatible!defaulted comparison operator} -if it -satisfies the requirements for a constexpr function\iref{dcl.constexpr} and -no overload resolution -performed when determining whether to delete the function -results in a usable candidate that is a non-constexpr function. -\begin{note} -This includes the overload resolutions performed: - -\begin{itemize} -\item -for an \tcode{operator<=>} whose return type is not \keyword{auto}, -when determining whether a synthesized three-way comparison is defined, - -\item -for an \tcode{operator<=>} whose return type is \keyword{auto} or -for an \tcode{operator==}, -for a comparison between an element of the expanded list of -subobjects and itself, or - -\item -for a secondary comparison operator \tcode{@}, -for the expression \tcode{x @ y}. -\end{itemize} -\end{note} - \pnum If the \grammarterm{member-specification} does not explicitly declare diff --git a/source/declarations.tex b/source/declarations.tex index 3cd7812e32..8e0bd83f4a 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -770,12 +770,6 @@ The definition of a constexpr function shall satisfy the following requirements: \begin{itemize} -\item -its return type (if any) shall be a literal type; - -\item -each of its parameter types shall be a literal type; - \item it shall not be a coroutine\iref{dcl.fct.def.coroutine}; @@ -816,78 +810,6 @@ \end{codeblock} \end{example} -\pnum -\indextext{specifier!\idxcode{constexpr}!constructor}% -The definition of a constexpr constructor -whose \grammarterm{function-body} is not \tcode{= delete} -shall additionally satisfy the following requirements: -\begin{itemize} - -\item -for a non-delegating constructor, every constructor selected to initialize non-static -data members and base class subobjects shall be a constexpr constructor; - -\item -for a delegating constructor, the target constructor shall be a constexpr -constructor. -\end{itemize} - -\begin{example} -\begin{codeblock} -struct Length { - constexpr explicit Length(int i = 0) : val(i) { } -private: - int val; -}; -\end{codeblock} -\end{example} - -\pnum -The definition of a constexpr destructor -whose \grammarterm{function-body} is not \tcode{= delete} -shall additionally satisfy the following requirement: -\begin{itemize} -\item - for every subobject of class type or - (possibly multi-dimensional) array thereof, - that class type shall have a constexpr destructor. -\end{itemize} - -\pnum -For a constexpr function or constexpr constructor -that is neither defaulted nor a template, -if no argument values exist such that -an invocation of the function or constructor could be an evaluated subexpression of a core -constant expression\iref{expr.const}, or, -for a constructor, an evaluated subexpression of -the initialization full-expression of some constant-initialized object\iref{basic.start.static}, -the program is ill-formed, no diagnostic required. -\begin{example} -\begin{codeblock} -constexpr int f(bool b) - { return b ? throw 0 : 0; } // OK -constexpr int f() { return f(true); } // ill-formed, no diagnostic required - -struct B { - constexpr B(int x) : i(0) { } // \tcode{x} is unused - int i; -}; - -int global; - -struct D : B { - constexpr D() : B(global) { } // ill-formed, no diagnostic required - // lvalue-to-rvalue conversion on non-constant \tcode{global} -}; - -constexpr int f(int x) { - static int n = x; - return n + x; // ill-formed, no diagnostic required - // all calls reach the static variable declaration -} -\end{codeblock} -\end{example} - \pnum If the instantiated template specialization of a constexpr function template @@ -896,10 +818,7 @@ function, that specialization is still a constexpr function, even though a call to such a function cannot appear in a constant -expression. If no specialization of the template would satisfy the -requirements for a constexpr function -when considered as a non-template function, the template is -ill-formed, no diagnostic required. +expression. \pnum An invocation of a constexpr function in a given context @@ -919,6 +838,10 @@ This can indirectly cause calls to \tcode{std::is_constant_evaluated} within an invocation of the function to produce a different value. \end{note} +\begin{note} +It is possible to write a constexpr function for which +no invocation satisfies the requirements of a core constant expression. +\end{note} \pnum The \keyword{constexpr} and \keyword{consteval} specifiers have no @@ -6249,18 +6172,15 @@ \end{itemize} \pnum -An explicitly-defaulted function that is not defined as deleted may be declared -\keyword{constexpr} or \keyword{consteval} only -if it is constexpr-compatible\iref{special,class.compare.default}. A function explicitly defaulted on its first declaration is implicitly inline\iref{dcl.inline}, -and is implicitly constexpr\iref{dcl.constexpr} if it is constexpr-compatible. +and is implicitly constexpr\iref{dcl.constexpr} +if it satisfies the requirements for a constexpr function. \pnum \begin{example} \begin{codeblock} struct S { - constexpr S() = default; // error: implicit \tcode{S()} is not \keyword{constexpr} S(int a = 0) = default; // error: default argument void operator=(const S&) = default; // error: non-matching return type ~S() noexcept(false) = default; // OK, despite mismatched exception specification diff --git a/source/preprocessor.tex b/source/preprocessor.tex index 1362638193..6dabe092d6 100644 --- a/source/preprocessor.tex +++ b/source/preprocessor.tex @@ -1760,7 +1760,7 @@ \defnxname{cpp_char8_t} & \tcode{201811L} \\ \rowsep \defnxname{cpp_concepts} & \tcode{202002L} \\ \rowsep \defnxname{cpp_conditional_explicit} & \tcode{201806L} \\ \rowsep -\defnxname{cpp_constexpr} & \tcode{202110L} \\ \rowsep +\defnxname{cpp_constexpr} & \tcode{202207L} \\ \rowsep \defnxname{cpp_constexpr_dynamic_alloc} & \tcode{201907L} \\ \rowsep \defnxname{cpp_constexpr_in_decltype} & \tcode{201711L} \\ \rowsep \defnxname{cpp_consteval} & \tcode{201811L} \\ \rowsep From bd97fe7617e78731755758abd1ba13355f7bef6e Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Tue, 26 Jul 2022 22:51:50 +0200 Subject: [PATCH 142/430] P2266R3 Simpler implicit move --- source/classes.tex | 65 ++++++++++++++-------------------------- source/compatibility.tex | 13 ++++++++ source/declarations.tex | 6 ++++ source/expressions.tex | 35 ++++++++++++++++++++-- source/preprocessor.tex | 1 + 5 files changed, 76 insertions(+), 44 deletions(-) diff --git a/source/classes.tex b/source/classes.tex index 9ec3133300..409e40fde9 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -6330,45 +6330,6 @@ move construction from the object with automatic storage duration to \tcode{t2} that is elided. \end{example} -\pnum -An \defnadj{implicitly movable}{entity} is -a variable of automatic storage duration -that is either a non-volatile object or -an rvalue reference to a non-volatile object type. -In the following copy-initialization contexts, -a move operation is first considered before attempting a copy operation: -\begin{itemize} -\item If the \grammarterm{expression} in a \tcode{return}\iref{stmt.return} or -\keyword{co_return}\iref{stmt.return.coroutine} statement -is a (possibly parenthesized) \grammarterm{id-expression} -that names an implicitly movable entity declared in the body -or \grammarterm{parameter-declaration-clause} of the innermost enclosing -function or \grammarterm{lambda-expression}, or - -\item if the operand of a \grammarterm{throw-expression}\iref{expr.throw} -is a (possibly parenthesized) \grammarterm{id-expression} -that names an implicitly movable entity -that belongs to a scope that does not contain the \grammarterm{compound-statement} -of the innermost \grammarterm{try-block} or \grammarterm{function-try-block} -(if any) -whose \grammarterm{compound-statement} or \grammarterm{ctor-initializer} -contains the \grammarterm{throw-expression}, -\end{itemize} -overload resolution to select the constructor -for the copy or the \tcode{return_value} overload to call -is first performed as if the expression or operand were an rvalue. -If the first overload resolution fails or was not performed, -overload resolution is performed again, -considering the expression or operand as an lvalue. -\begin{note} -This two-stage overload resolution is performed regardless -of whether copy elision will occur. It determines the constructor -or the \tcode{return_value} overload to be called if -elision is not performed, and the selected constructor -or \tcode{return_value} overload must be accessible even if -the call is elided. -\end{note} - \pnum \begin{example} \begin{codeblock} @@ -6395,9 +6356,29 @@ Weird(Weird&); }; -Weird g() { - Weird w; - return w; // OK, first overload resolution fails, second overload resolution selects \tcode{Weird(Weird\&)} +Weird g(bool b) { + static Weird w1; + Weird w2; + if (b) + return w1; // OK, uses \tcode{Weird(Weird\&)} + else + return w2; // error: \tcode{w2} in this context is an xvalue +} + +int& h(bool b, int i) { + static int s; + if (b) + return s; // OK + else + return i; // error: \tcode{i} is an xvalue +} + +decltype(auto) h2(Thing t) { + return t; // OK, \tcode{t} is an xvalue and \tcode{h2}'s return type is \tcode{Thing} +} + +decltype(auto) h3(Thing t) { + return (t); // OK, \tcode{(t)} is an xvalue and \tcode{h3}'s return type is \tcode{Thing\&\&} } \end{codeblock} \end{example} diff --git a/source/compatibility.tex b/source/compatibility.tex index 736962bffa..35d9feb29f 100644 --- a/source/compatibility.tex +++ b/source/compatibility.tex @@ -42,6 +42,19 @@ \rSec2[diff.cpp20.expr]{\ref{expr}: expressions} +\diffref{expr.prim.id.unqual} +\change +Change move-eligible \grammarterm{id-expression}s from lvalues to xvalues. +\rationale +Simplify the rules for implicit move. +\effect +Valid \CppXX{} code that relies on a returned \grammarterm{id-expression}'s +being an lvalue may change behavior or fail to compile. For example: +\begin{codeblock} +decltype(auto) f(int&& x) { return (x); } // returns \tcode{int\&\&}; previously returned \tcode{int\&} +int& g(int&& x) { return x; } // ill-formed; previously well-formed +\end{codeblock} + \diffref{expr.sub} \change Change the meaning of comma in subscript expressions. diff --git a/source/declarations.tex b/source/declarations.tex index 8e0bd83f4a..27b1fa751a 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -1959,6 +1959,8 @@ decltype(auto) x6d = { 1, 2 }; // error: \tcode{\{ 1, 2 \}} is not an expression auto *x7a = &i; // \tcode{decltype(x7a)} is \tcode{int*} decltype(auto)*x7d = &i; // error: declared type is not plain \tcode{decltype(auto)} +auto f1(int x) -> decltype((x)) { return (x); } // return type is \tcode{int\&} +auto f2(int x) -> decltype(auto) { return (x); } // return type is \tcode{int\&\&} \end{codeblock} \end{example} @@ -5538,6 +5540,10 @@ \item if the reference is an rvalue reference, the initializer expression shall not be an lvalue. +\begin{note} +This can be affected by +whether the initializer expression is move-eligible\iref{expr.prim.id.unqual}. +\end{note} \end{itemize} \begin{example} diff --git a/source/expressions.tex b/source/expressions.tex index 07fad83978..1f7fe30a5f 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -186,6 +186,8 @@ \begin{note} An expression is an xvalue if it is: \begin{itemize} +\item a move-eligible \grammarterm{id-expression}\iref{expr.prim.id.unqual}, + \item the result of calling a function, whether implicitly or explicitly, whose return type is an rvalue reference to object type\iref{expr.call}, @@ -1482,9 +1484,10 @@ The type will be adjusted as described in \ref{expr.type} if it is cv-qualified or is a reference type. \end{note} -The expression is an lvalue +The expression is an xvalue if it is move-eligible (see below); +an lvalue if the entity is a function, variable, structured binding\iref{dcl.struct.bind}, data member, or -template parameter object +template parameter object; and a prvalue otherwise\iref{basic.lval}; it is a bit-field if the identifier designates a bit-field. \begin{example} @@ -1514,6 +1517,34 @@ \end{codeblock} \end{example} +\pnum +An \defnadj{implicitly movable}{entity} is +a variable of automatic storage duration +that is either a non-volatile object or +an rvalue reference to a non-volatile object type. +In the following contexts, +an \grammarterm{id-expression} is \defn{move-eligible}: +\begin{itemize} +\item +If the \grammarterm{id-expression} (possibly parenthesized) +is the operand of a \tcode{return}\iref{stmt.return} or +\keyword{co_return}\iref{stmt.return.coroutine} statement, +and names an implicitly movable entity declared in the body +or \grammarterm{parameter-declaration-clause} of the innermost enclosing +function or \grammarterm{lambda-expression}, or +\item +if the \grammarterm{id-expression} (possibly parenthesized) +is the operand of a \grammarterm{throw-expression}\iref{expr.throw}, +and names an implicitly movable entity +that belongs to a scope that does not contain the \grammarterm{compound-statement} +of the innermost +\grammarterm{lambda-expression}, +\grammarterm{try-block}, or +\grammarterm{function-try-block} (if any) +whose \grammarterm{compound-statement} or \grammarterm{ctor-initializer} +contains the \grammarterm{throw-expression}. +\end{itemize} + \rSec3[expr.prim.id.qual]{Qualified names} \indextext{operator!scope resolution}% diff --git a/source/preprocessor.tex b/source/preprocessor.tex index 6dabe092d6..775055f57e 100644 --- a/source/preprocessor.tex +++ b/source/preprocessor.tex @@ -1781,6 +1781,7 @@ \defnxname{cpp_impl_coroutine} & \tcode{201902L} \\ \rowsep \defnxname{cpp_impl_destroying_delete} & \tcode{201806L} \\ \rowsep \defnxname{cpp_impl_three_way_comparison} & \tcode{201907L} \\ \rowsep +\defnxname{cpp_implicit_move} & \tcode{202207L} \\ \rowsep \defnxname{cpp_inheriting_constructors} & \tcode{201511L} \\ \rowsep \defnxname{cpp_init_captures} & \tcode{201803L} \\ \rowsep \defnxname{cpp_initializer_lists} & \tcode{200806L} \\ \rowsep From 5f48a6e19fb083a91d941d568370dd65ed500868 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Wed, 27 Jul 2022 01:01:26 +0200 Subject: [PATCH 143/430] P2071R2 Named universal character escapes --- source/lex.tex | 144 +++++++++++++++++++++++++++++++++++++++- source/preprocessor.tex | 1 + 2 files changed, 143 insertions(+), 2 deletions(-) diff --git a/source/lex.tex b/source/lex.tex index 7fb88c4f94..2c7fed4d5b 100644 --- a/source/lex.tex +++ b/source/lex.tex @@ -288,6 +288,25 @@ The \grammarterm{universal-character-name} construct provides a way to name other characters. +\begin{bnf} +\nontermdef{n-char} \textnormal{one of}\br + \terminal{A B C D E F G H I J K L M N O P Q R S T U V W X Y Z}\br + \terminal{0 1 2 3 4 5 6 7 8 9}\br + \textnormal{\unicode{002d}{hyphen-minus}}\br + \textnormal{\unicode{0020}{space}} +\end{bnf} + +\begin{bnf} +\nontermdef{n-char-sequence}\br + n-char\br + n-char-sequence n-char +\end{bnf} + +\begin{bnf} +\nontermdef{named-universal-character}\br + \terminal{\textbackslash N\{} n-char-sequence \terminal{\}} +\end{bnf} + \begin{bnf} \nontermdef{hex-quad}\br hexadecimal-digit hexadecimal-digit hexadecimal-digit hexadecimal-digit @@ -303,15 +322,136 @@ \nontermdef{universal-character-name}\br \terminal{\textbackslash u} hex-quad\br \terminal{\textbackslash U} hex-quad hex-quad\br - \terminal{\textbackslash u\{} simple-hexadecimal-digit-sequence \terminal{\}} + \terminal{\textbackslash u\{} simple-hexadecimal-digit-sequence \terminal{\}}\br + named-universal-character \end{bnf} +\pnum A \grammarterm{universal-character-name} +of the form \tcode{\textbackslash u} \grammarterm{hex-quad} or +\tcode{\textbackslash U} \grammarterm{hex-quad} \grammarterm{hex-quad} designates the character in the translation character set whose UCS scalar value is the hexadecimal number represented by the sequence of \grammarterm{hexadecimal-digit}s in the \grammarterm{universal-character-name}. The program is ill-formed if that number is not a UCS scalar value. + +\pnum +A \grammarterm{universal-character-name} +that is a \grammarterm{named-universal-character} +designates the character named by its \grammarterm{n-char-sequence}. +A character is so named if the \grammarterm{n-char-sequence} is equal to +\begin{itemize} +\item +the associated character name or associated character name alias +specified in ISO/IEC 10646 subclause ``Code charts and lists of character names'' +or +\item +the control code alias given in \tref{lex.charset.ucn}. +\begin{note} +The aliases in \tref{lex.charset.ucn} are provided for control characters +which otherwise have no associated character name or character name alias. +These names are derived from +the Unicode Character Database's \tcode{NameAliases.txt}. +For historical reasons, control characters are formally unnamed. +\end{note} +\end{itemize} +\begin{note} +None of the associated character names, +associated character name aliases, or +control code aliases +have leading or trailing spaces. +\end{note} + +\begin{multicolfloattable}{Control code aliases}{lex.charset.ucn}{ll} +\unicode{0000}{null} \\ +\unicode{0001}{start of heading} \\ +\unicode{0002}{start of text} \\ +\unicode{0003}{end of text} \\ +\unicode{0004}{end of transmission} \\ +\unicode{0005}{enquiry} \\ +\unicode{0006}{acknowledge} \\ +\unicode{0007}{alert} \\ +\unicode{0008}{backspace} \\ +\unicode{0009}{character tabulation} \\ +\unicode{0009}{horizontal tabulation} \\ +\unicode{000a}{line feed} \\ +\unicode{000a}{new line} \\ +\unicode{000a}{end of line} \\ +\unicode{000b}{line tabulation} \\ +\unicode{000b}{vertical tabulation} \\ +\unicode{000c}{form feed} \\ +\unicode{000d}{carriage return} \\ +\unicode{000e}{shift out} \\ +\unicode{000e}{locking-shift one} \\ +\unicode{000f}{shift in} \\ +\unicode{000f}{locking-shift zero} \\ +\unicode{0010}{data link escape} \\ +\unicode{0011}{device control one} \\ +\unicode{0012}{device control two} \\ +\unicode{0013}{device control three} \\ +\unicode{0014}{device control four} \\ +\unicode{0015}{negative acknowledge} \\ +\unicode{0016}{synchronous idle} \\ +\unicode{0017}{end of transmission block} \\ +\unicode{0018}{cancel} \\ +\unicode{0019}{end of medium} \\ +\unicode{001a}{substitute} \\ +\unicode{001b}{escape} \\ +\unicode{001c}{information separator four} \\ +\unicode{001c}{file separator} \\ +\unicode{001d}{information separator three} \\ +\unicode{001d}{group separator} \\ +\unicode{001e}{information separator two} \\ +\unicode{001e}{record separator} \\ +\unicode{001f}{information separator one} \\ +\unicode{001f}{unit separator} \\ +\columnbreak +\unicode{007f}{delete} \\ +\unicode{0082}{break permitted here} \\ +\unicode{0083}{no break here} \\ +\unicode{0084}{index} \\ +\unicode{0085}{next line} \\ +\unicode{0086}{start of selected area} \\ +\unicode{0087}{end of selected area} \\ +\unicode{0088}{character tabulation set} \\ +\unicode{0088}{horizontal tabulation set} \\ +\unicode{0089}{character tabulation with justification} \\ +\unicode{0089}{horizontal tabulation with justification} \\ +\unicode{008a}{line tabulation set} \\ +\unicode{008a}{vertical tabulation set} \\ +\unicode{008b}{partial line forward} \\ +\unicode{008b}{partial line down} \\ +\unicode{008c}{partial line backward} \\ +\unicode{008c}{partial line up} \\ +\unicode{008d}{reverse line feed} \\ +\unicode{008d}{reverse index} \\ +\unicode{008e}{single shift two} \\ +\unicode{008e}{single shift-2} \\ +\unicode{008f}{single shift three} \\ +\unicode{008f}{single shift-3} \\ +\unicode{0090}{device control string} \\ +\unicode{0091}{private use one} \\ +\unicode{0091}{private use-1} \\ +\unicode{0092}{private use two} \\ +\unicode{0092}{private use-2} \\ +\unicode{0093}{set transmit state} \\ +\unicode{0094}{cancel character} \\ +\unicode{0095}{message waiting} \\ +\unicode{0096}{start of guarded area} \\ +\unicode{0096}{start of protected area} \\ +\unicode{0097}{end of guarded area} \\ +\unicode{0097}{end of protected area} \\ +\unicode{0098}{start of string} \\ +\unicode{009a}{single character introducer} \\ +\unicode{009b}{control sequence introducer} \\ +\unicode{009c}{string terminator} \\ +\unicode{009d}{operating system command} \\ +\unicode{009e}{privacy message} \\ +\unicode{009f}{application program command} \\ +\end{multicolfloattable} + +\pnum If a \grammarterm{universal-character-name} outside the \grammarterm{c-char-sequence}, \grammarterm{s-char-sequence}, or \grammarterm{r-char-sequence} of @@ -1345,7 +1485,7 @@ \begin{bnf} \nontermdef{conditional-escape-sequence-char}\br - \textnormal{any member of the basic character set that is not an} octal-digit\textnormal{, a} simple-escape-sequence-char\textnormal{, or the characters \terminal{o}, \terminal{u}, \terminal{U}, or \terminal{x}} + \textnormal{any member of the basic character set that is not an} octal-digit\textnormal{, a} simple-escape-sequence-char\textnormal{, or the characters \terminal{N}, \terminal{o}, \terminal{u}, \terminal{U}, or \terminal{x}} \end{bnf} \pnum diff --git a/source/preprocessor.tex b/source/preprocessor.tex index 775055f57e..190f7dc1eb 100644 --- a/source/preprocessor.tex +++ b/source/preprocessor.tex @@ -1789,6 +1789,7 @@ \defnxname{cpp_lambdas} & \tcode{200907L} \\ \rowsep \defnxname{cpp_modules} & \tcode{201907L} \\ \rowsep \defnxname{cpp_multidimensional_subscript} & \tcode{202110L} \\ \rowsep +\defnxname{cpp_named_character_escapes} & \tcode{202207L} \\ \rowsep \defnxname{cpp_namespace_attributes} & \tcode{201411L} \\ \rowsep \defnxname{cpp_noexcept_function_type} & \tcode{201510L} \\ \rowsep \defnxname{cpp_nontype_template_args} & \tcode{201911L} \\ \rowsep From f9cb3dbcc6cf10632aa453b179d927d1b6be459d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Fri, 5 Aug 2022 23:07:37 +0100 Subject: [PATCH 144/430] [lex.charset] Add delimited form \u{...} of universal character name The adoption of P2290R3 "Delimited escape sequences" via CWG Motion 8 added another form of universal character name, which we now need to list as well. --- source/lex.tex | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/lex.tex b/source/lex.tex index 2c7fed4d5b..afc0772746 100644 --- a/source/lex.tex +++ b/source/lex.tex @@ -328,8 +328,9 @@ \pnum A \grammarterm{universal-character-name} -of the form \tcode{\textbackslash u} \grammarterm{hex-quad} or -\tcode{\textbackslash U} \grammarterm{hex-quad} \grammarterm{hex-quad} +of the form \tcode{\textbackslash u} \grammarterm{hex-quad}, +\tcode{\textbackslash U} \grammarterm{hex-quad} \grammarterm{hex-quad}, or +\tcode{\textbackslash u\{\grammarterm{simple-hexadecimal-digit-sequence}\}} designates the character in the translation character set whose UCS scalar value is the hexadecimal number represented by the sequence of \grammarterm{hexadecimal-digit}s From 41e426500e28b397f3fab3b473c23da502a33518 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Wed, 27 Jul 2022 18:10:44 +0200 Subject: [PATCH 145/430] P1169R4 static operator() --- source/expressions.tex | 29 ++++++++++++++++++++++++----- source/overloading.tex | 34 +++++++++++++--------------------- source/preprocessor.tex | 1 + source/threads.tex | 12 ++++++++++-- source/utilities.tex | 12 ++++++++++-- 5 files changed, 58 insertions(+), 30 deletions(-) diff --git a/source/expressions.tex b/source/expressions.tex index 1f7fe30a5f..bf90ce7bd7 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -1725,7 +1725,8 @@ \nontermdef{lambda-specifier}\br \keyword{consteval}\br \keyword{constexpr}\br - \keyword{mutable} + \keyword{mutable}\br + \keyword{static} \end{bnf} \begin{bnf} @@ -1776,7 +1777,11 @@ If the \grammarterm{lambda-declarator} contains an explicit object parameter\iref{dcl.fct}, then no \grammarterm{lambda-specifier} in the \grammarterm{lambda-specifier-seq} -shall be \keyword{mutable}. +shall be \keyword{mutable} or \keyword{static}. +The \grammarterm{lambda-specifier-seq} shall not contain +both \keyword{mutable} and \keyword{static}. +If the \grammarterm{lambda-specifier-seq} contains \keyword{static}, +there shall be no \grammarterm{lambda-capture}. \begin{note} The trailing \grammarterm{requires-clause} is described in \ref{dcl.decl}. \end{note} @@ -1923,7 +1928,13 @@ \end{example} \pnum -The function call operator or operator template is declared +The function call operator or operator template is +a static member function or static member function template\iref{class.static.mfct} +if the \grammarterm{lambda-expression}'s +\grammarterm{parameter-declaration-clause} is followed by \keyword{static}. +Otherwise, it is +a non-static member function or member function template\iref{class.mfct.non.static} +that is declared \keyword{const}\iref{class.mfct.non.static} if and only if the \grammarterm{lambda-expression}'s \grammarterm{parameter-declaration-clause} is not followed by \keyword{mutable} and @@ -2019,7 +2030,10 @@ The conversion is to ``pointer to \keyword{noexcept} function'' if the function call operator has a non-throwing exception specification. -The value returned by this conversion function +If the function call operator is a static member function, +then the value returned by this conversion function is +the address of the function call operator. +Otherwise, the value returned by this conversion function is the address of a function \tcode{F} that, when invoked, has the same effect as invoking the closure type's function call operator on a default-constructed instance of the closure type. @@ -2090,7 +2104,12 @@ \end{example} \pnum -The value returned by any given specialization of this conversion function +If the function call operator template is a static member function template, +then the value returned by +any given specialization of this conversion function template is +the address of the corresponding function call operator template specialization. +Otherwise, +the value returned by any given specialization of this conversion function template is the address of a function \tcode{F} that, when invoked, has the same effect as invoking the generic lambda's corresponding function call operator template specialization on a default-constructed instance of the closure type. diff --git a/source/overloading.tex b/source/overloading.tex index 18f26832e7..f970139fe5 100644 --- a/source/overloading.tex +++ b/source/overloading.tex @@ -1595,31 +1595,14 @@ \pnum \indextext{conversion!overload resolution and}% -Define $\text{ICS}^i(\tcode{F})$ as follows: -\begin{itemize} -\item -If \tcode{F} is a static member function, -$\text{ICS}^1(\tcode{F})$ is defined such that -$\text{ICS}^1(\tcode{F})$ is neither better nor worse than -$\text{ICS}^1(\tcode{G})$ for any function \tcode{G}, -and, symmetrically, $\text{ICS}^1(\tcode{G})$ is neither better nor worse than -$\text{ICS}^1(\tcode{F})$; -\begin{footnote} -If a function is a static member function, this -definition means that the first argument, the implied object argument, -has no effect in the determination of whether the function is better -or worse than any other function. -\end{footnote} -otherwise, -\item -let $\text{ICS}^i(\tcode{F})$ denote the implicit conversion sequence that converts +Define $\text{ICS}^i(\tcode{F})$ as +the implicit conversion sequence that converts the $i^\text{th}$ argument in the list to the type of the $i^\text{th}$ parameter of viable function \tcode{F}. \ref{over.best.ics} defines the implicit conversion sequences and \ref{over.ics.rank} defines what it means for one implicit conversion sequence to be a better conversion sequence or worse conversion sequence than another. -\end{itemize} \pnum Given these definitions, @@ -2005,6 +1988,9 @@ only in the description of implicit conversion sequences. \end{note} A derived-to-base conversion has Conversion rank\iref{over.ics.scs}. +When the parameter is the implicit object parameter of a static member function, +the implicit conversion sequence is a standard conversion sequence +that is neither better nor worse than any other standard conversion sequence. \pnum In all contexts, when converting to the implicit object parameter @@ -3122,9 +3108,15 @@ \pnum \indextext{restriction!overloading}% An operator function -shall either be a non-static member function or be a non-member function that +shall either +\begin{itemize} +\item +be a member function or +\item +be a non-member function that has at least one non-object parameter whose type is a class, a reference to a class, an enumeration, or a reference to an enumeration. +\end{itemize} It is not possible to change the precedence, grouping, or number of operands of operators. The meaning of @@ -3310,7 +3302,7 @@ \pnum A \defnadj{function call}{operator function} is a function named \tcode{\keyword{operator}()} -that is a non-static member function with an arbitrary number of parameters. +that is a member function with an arbitrary number of parameters. It may have default arguments. For an expression of the form \begin{ncsimplebnf} diff --git a/source/preprocessor.tex b/source/preprocessor.tex index 190f7dc1eb..46aff75633 100644 --- a/source/preprocessor.tex +++ b/source/preprocessor.tex @@ -1803,6 +1803,7 @@ \defnxname{cpp_size_t_suffix} & \tcode{202011L} \\ \rowsep \defnxname{cpp_sized_deallocation} & \tcode{201309L} \\ \rowsep \defnxname{cpp_static_assert} & \tcode{201411L} \\ \rowsep +\defnxname{cpp_static_call_operator} & \tcode{202207L} \\ \rowsep \defnxname{cpp_structured_bindings} & \tcode{201606L} \\ \rowsep \defnxname{cpp_template_template_args} & \tcode{201611L} \\ \rowsep \defnxname{cpp_threadsafe_static_init} & \tcode{200806L} \\ \rowsep diff --git a/source/threads.tex b/source/threads.tex index f87cdc3884..58909c97cd 100644 --- a/source/threads.tex +++ b/source/threads.tex @@ -11318,10 +11318,18 @@ \pnum \constraints \tcode{\&F::operator()} is well-formed when -treated as an unevaluated operand\iref{term.unevaluated.operand} and +treated as an unevaluated operand\iref{term.unevaluated.operand} and either +\begin{itemize} +\item +\tcode{F::operator()} is a non-static member function and \tcode{decltype(\brk{}\&F::operator())} is of the form \tcode{R(G::*)(A...)}~\cv{}~\tcode{\opt{\&}~\opt{noexcept}} -for a class type \tcode{G}. +for a class type \tcode{G}, or +\item +\tcode{F::operator()} is a static member function and +\tcode{decltype(\&F::operator())} is of the form +\tcode{R(*)(A...) \opt{noexcept}}. +\end{itemize} \pnum \remarks diff --git a/source/utilities.tex b/source/utilities.tex index f3bf151ea4..994bcc7c43 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -11675,10 +11675,18 @@ \begin{itemdescr} \pnum \constraints -\tcode{\&F::operator()} is well-formed when treated as an unevaluated operand and +\tcode{\&F::operator()} is well-formed when treated as an unevaluated operand and either +\begin{itemize} +\item +\tcode{F::operator()} is a non-static member function and \tcode{decltype(\brk{}\&F::operator())} is of the form \tcode{R(G::*)(A...)}~\cv{}~\tcode{\opt{\&}~\opt{noexcept}} -for a class type \tcode{G}. +for a class type \tcode{G}, or +\item +\tcode{F::operator()} is a static member function and +\tcode{decltype(\&F::operator())} is of the form +\tcode{R(*)(A...) \opt{noexcept}}. +\end{itemize} \pnum \remarks From 32d8f9cb98be311096f914b7c73f0bb773878ec3 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Wed, 27 Jul 2022 22:34:07 +0200 Subject: [PATCH 146/430] P2280R4 Using unknown pointers and references in constant expressions --- source/expressions.tex | 105 ++++++++++++++++++++++++++++++++--------- 1 file changed, 84 insertions(+), 21 deletions(-) diff --git a/source/expressions.tex b/source/expressions.tex index bf90ce7bd7..04d2da8ce5 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -7289,9 +7289,15 @@ machine\iref{intro.execution}, would evaluate one of the following: \begin{itemize} \item -\keyword{this}\iref{expr.prim.this}, except in a constexpr -function\iref{dcl.constexpr} that is being evaluated as part -of $E$; +\keyword{this}\iref{expr.prim.this}, except +\begin{itemize} +\item +in a constexpr function\iref{dcl.constexpr} +that is being evaluated as part of $E$ or +\item +when appearing as the \grammarterm{postfix-expression} of +an implicit or explicit class member access expression\iref{expr.ref}; +\end{itemize} \item a control flow that passes through @@ -7316,11 +7322,7 @@ \item an invocation of a virtual function\iref{class.virtual} -for an object unless - \begin{itemize} - \item the object is usable in constant expressions or - \item its lifetime began within the evaluation of $E$; - \end{itemize} +for an object whose dynamic type is constexpr-unknown; \item an expression that would exceed the implementation-defined @@ -7364,18 +7366,6 @@ for a union whose active member (if any) is mutable, unless the lifetime of the union object began within the evaluation of $E$; -\item -an \grammarterm{id-expression} that refers to a variable or -data member of reference type -unless the reference has a preceding initialization and either -\begin{itemize} - \item - it is usable in constant expressions or - - \item - its lifetime began within the evaluation of $E$; -\end{itemize} - \item in a \grammarterm{lambda-expression}, a reference to \keyword{this} or to a variable with @@ -7467,7 +7457,10 @@ a \grammarterm{throw-expression}\iref{expr.throw}; \item -a \keyword{dynamic_cast}\iref{expr.dynamic.cast} or \keyword{typeid}\iref{expr.typeid} expression +a \keyword{dynamic_cast}\iref{expr.dynamic.cast} or +\keyword{typeid}\iref{expr.typeid} expression +on a glvalue that refers to an object +whose dynamic type is constexpr-unknown or that would throw an exception; \item @@ -7549,6 +7542,71 @@ the evaluation of the underlying constructor call disqualifies $E$ from being a core constant expression. +\pnum +During the evaluation of an expression $E$ as a core constant expression, +all \grammarterm{id-expression}s and uses of \tcode{*\keyword{this}} +that refer to an object or reference +whose lifetime did not begin with the evaluation of $E$ +are treated as referring to a specific instance of that object or reference +whose lifetime and that of all subobjects (including all union members) +includes the entire constant evaluation. +For such an object that is not usable in constant expressions, +the dynamic type of the object is \defn{constexpr-unknown}. +For such a reference that is not usable in constant expressions, +the reference is treated as binding to +an unspecified object of the referenced type +whose lifetime and that of all subobjects includes +the entire constant evaluation and whose dynamic type is constexpr-unknown. +\begin{example} +\begin{codeblock} +template +constexpr size_t array_size(T (&)[N]) { + return N; +} + +void use_array(int const (&gold_medal_mel)[2]) { + constexpr auto gold = array_size(gold_medal_mel); // OK +} + +constexpr auto olympic_mile() { + const int ledecky = 1500; + return []{ return ledecky; }; +} +static_assert(olympic_mile()() == 1500); // OK + +struct Swim { + constexpr int phelps() { return 28; } + virtual constexpr int lochte() { return 12; } + int coughlin = 12; +}; + +constexpr int how_many(Swim& swam) { + Swim* p = &swam; + return (p + 1 - 1)->phelps(); +} + +void splash(Swim& swam) { + static_assert(swam.phelps() == 28); // OK + static_assert((&swam)->phelps() == 28); // OK + Swim* pswam = &swam; + static_assert(pswam->phelps() == 28); // error: lvalue-to-rvalue conversion on a pointer + // not usable in constant expressions + static_assert(how_many(swam) == 28); // OK + static_assert(Swim().lochte() == 12); // OK + static_assert(swam.lochte() == 12); // error: invoking virtual function on reference + // with constexpr-unknown dynamic type + static_assert(swam.coughlin == 12); // error: lvalue-to-rvalue conversion on an object + // not usable in constant expressions +} + +extern Swim dc; +extern Swim& trident; + +constexpr auto& sandeno = typeid(dc); // OK, can only be \tcode{typeid(Swim)} +constexpr auto& gallagher = typeid(trident); // error: constexpr-unknown dynamic type +\end{codeblock} +\end{example} + \pnum An object \tcode{a} is said to have \defnadj{constant}{destruction} if: \begin{itemize} @@ -7662,6 +7720,11 @@ object with static storage duration that either is not a temporary object or is a temporary object whose value satisfies the above constraints, or if it is a non-immediate function. +\begin{note} +A glvalue core constant expression +that either refers to or points to an unspecified object +is not a constant expression. +\end{note} \begin{example} \begin{codeblock} consteval int f() { return 42; } From 11c7ab9c2606c6a7d2777c857e118214b9b82546 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Wed, 27 Jul 2022 23:57:29 +0200 Subject: [PATCH 147/430] P1467R9 Extended floating-point types and standard names --- source/back.tex | 6 +- source/basic.tex | 157 +++++++++- source/declarations.tex | 6 +- source/expressions.tex | 63 ++-- source/intro.tex | 4 + source/iostreams.tex | 111 +++++++ source/lex.tex | 17 +- source/lib-intro.tex | 1 + source/numerics.tex | 626 +++++++++++++--------------------------- source/overloading.tex | 28 ++ source/preprocessor.tex | 39 +++ source/support.tex | 38 ++- source/threads.tex | 10 +- source/utilities.tex | 76 ++--- source/xrefdelta.tex | 3 + 15 files changed, 659 insertions(+), 526 deletions(-) diff --git a/source/back.tex b/source/back.tex index 0314b1007c..60a20e7d51 100644 --- a/source/back.tex +++ b/source/back.tex @@ -13,8 +13,10 @@ \chapter{Bibliography} \doccite{Information technology --- Language independent arithmetic --- Part 1: Integer and floating point arithmetic} \item - ISO/IEC/IEEE 60559:2011, \doccite{Information technology --- - Microprocessor Systems --- Floating-Point arithmetic} + ISO/IEC TS 18661-3:2015, + \doccite{Information Technology --- + Programming languages, their environments, and system software interfaces --- + Floating-point extensions for C --- Part 3: Interchange and extended types} % Other international standards. \item %%% Format for the following entry is based on that specified at diff --git a/source/basic.tex b/source/basic.tex index 582f7bb2c4..b02fcbf3da 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -4995,15 +4995,23 @@ The types \keyword{float}, \keyword{double}, and \tcode{\keyword{long} \keyword{double}}, and cv-qualified versions\iref{basic.type.qualifier} thereof, +are collectively termed +\defnx{standard floating-point types}{type!floating-point!standard}. +An implementation may also provide additional types +that represent floating-point values and define them (and cv-qualified versions thereof) to be +\defnx{extended floating-point types}{type!floating-point!extended}. +The standard and extended floating-point types are collectively termed \defnx{floating-point types}{type!floating-point}. -The value -representation of floating-point types is \impldef{value representation of -floating-point types}. -\indextext{floating-point type!implementation-defined}% \begin{note} -This document imposes no requirements on the accuracy of -floating-point operations; see also~\ref{support.limits}. +Any additional implementation-specific types representing floating-point values +that are not defined by the implementation to be extended floating-point types +are not considered to be floating-point types, and +this document imposes no requirements on them or +their interactions with floating-point types. \end{note} +Except as specified in \ref{basic.extended.fp}, +the object and value representations and accuracy of operations +of floating-point types is \impldef{representation of floating-point types}. \pnum Integral and floating-point types are collectively @@ -5049,6 +5057,90 @@ same value representation, they are nevertheless different types. \end{note} +\rSec2[basic.extended.fp]{Optional extended floating-point types} + +\pnum +If the implementation supports an extended floating-point type\iref{basic.fundamental} +whose properties are specified by +the ISO/IEC/IEEE 60559 floating-point interchange format binary16, +then the \grammarterm{typedef-name} \tcode{std::float16_t} +is defined in the header \libheaderref{stdfloat} and names such a type, +the macro \mname{STDCPP_FLOAT16_T} is defined\iref{cpp.predefined}, and +the floating-point literal suffixes \tcode{f16} and \tcode{F16} +are supported\iref{lex.fcon}. + +\pnum +If the implementation supports an extended floating-point type +whose properties are specified by +the ISO/IEC/IEEE 60559 floating-point interchange format binary32, +then the \grammarterm{typedef-name} \tcode{std::float32_t} +is defined in the header \libheader{stdfloat} and names such a type, +the macro \mname{STDCPP_FLOAT32_T} is defined, and +the floating-point literal suffixes \tcode{f32} and \tcode{F32} are supported. + +\pnum +If the implementation supports an extended floating-point type +whose properties are specified by +the ISO/IEC/IEEE 60559 floating-point interchange format binary64, +then the \grammarterm{typedef-name} \tcode{std::float64_t} +is defined in the header \libheader{stdfloat} and names such a type, +the macro \mname{STDCPP_FLOAT64_T} is defined, and +the floating-point literal suffixes \tcode{f64} and \tcode{F64} are supported. + +\pnum +If the implementation supports an extended floating-point type +whose properties are specified by +the ISO/IEC/IEEE 60559 floating-point interchange format binary128, +then the \grammarterm{typedef-name} \tcode{std::float128_t} +is defined in the header \libheader{stdfloat} and names such a type, +the macro \mname{STDCPP_FLOAT128_T} is defined, and +the floating-point literal suffixes \tcode{f128} and \tcode{F128} are supported. + +\pnum +If the implementation supports an extended floating-point type +with the properties, as specified by ISO/IEC/IEEE 60559, of +radix ($b$) of 2, +storage width in bits ($k$) of 16, +precision in bits ($p$) of 8, +maximum exponent ($emax$) of 127, and +exponent field width in bits ($w$) of 8, then +the \grammarterm{typedef-name} \tcode{std::bfloat16_t} +is defined in the header \libheader{stdfloat} and names such a type, +the macro \mname{STDCPP_BFLOAT16_T} is defined, and +the floating-point literal suffixes \tcode{bf16} and \tcode{BF16} are supported. + +\pnum +\begin{note} +A summary of the parameters for each type is given in \tref{basic.extended.fp}. +The precision $p$ includes the implicit 1 bit at the beginning of the mantissa, +so the storage used for the mantissa is $p-1$ bits. +ISO/IEC/IEEE 60559 does not assign a name for a type +having the parameters specified for \tcode{std::bfloat16_t}. +\end{note} +\begin{floattable} +{Properties of named extended floating-point types}{basic.extended.fp}{llllll} +\topline +\lhdr{Parameter} & \chdr{\tcode{float16_t}} & \chdr{\tcode{float32_t}} & +\chdr{\tcode{float64_t}} & \chdr{\tcode{float128_t}} & +\rhdr{\tcode{bfloat16_t}} \\ +\capsep +ISO/IEC/IEEE 60559 name & binary16 & binary32 & binary64 & binary128 & \\ +$k$, storage width in bits & 16 & 32 & 64 & 128 & 16 \\ +$p$, precision in bits & 11 & 24 & 53 & 113 & 8 \\ +$emax$, maximum exponent & 15 & 127 & 1023 & 16383 & 127 \\ +$w$, exponent field width in bits & 5 & 8 & 11 & 15 & 8 \\ +\end{floattable} + +\pnum +\recommended +Any names that the implementation provides for +the extended floating-point types described in this subsection +that are in addition to the names defined in the \libheader{stdfloat} header +should be chosen to increase compatibility and interoperability +with the interchange types +\tcode{_Float16}, \tcode{_Float32}, \tcode{_Float64}, and \tcode{_Float128} +defined in ISO/IEC TS 18661-3 and with future versions of the C standard. + \rSec2[basic.compound]{Compound types} \pnum @@ -5337,7 +5429,7 @@ has the top-level cv-qualifier \keyword{volatile}. \end{example} -\rSec2[conv.rank]{Integer conversion rank}% +\rSec2[conv.rank]{Conversion ranks}% \indextext{conversion!integer rank} \pnum @@ -5394,6 +5486,57 @@ conversions\iref{expr.arith.conv}. \end{note} +\pnum +Every floating-point type has a \defnadj{floating-point}{conversion rank} +defined as follows: +\begin{itemize} +\item +The rank of a floating point type \tcode{T} is greater than +the rank of any floating-point type +whose set of values is a proper subset of the set of values of \tcode{T}. +\item +The rank of \tcode{\keyword{long} \keyword{double}} is greater than +the rank of \keyword{double}, +which is greater than the rank of \keyword{float}. +\item +Two extended floating-point types with the same set of values have equal ranks. +\item +An extended floating-point type with the same set of values as +exactly one cv-unqualified standard floating-point type +has a rank equal to the rank of that standard floating-point type. +\item +An extended floating-point type with the same set of values as +more than one cv-unqualified standard floating-point type +has a rank equal to the rank of \keyword{double}. +\end{itemize} +\begin{note} +The conversion ranks of floating-point types \tcode{T1} and \tcode{T2} +are unordered if the set of values of \tcode{T1} is +neither a subset nor a superset of the set of values of \tcode{T2}. +This can happen when one type has both a larger range and a lower precision +than the other. +\end{note} + +\pnum +Floating-point types that have equal floating-point conversion ranks +are ordered by floating-point conversion subrank. +The subrank forms a total order among types with equal ranks. +The types +\tcode{std::float16_t}, +\tcode{std::float32_t}, +\tcode{std::float64_t}, and +\tcode{std::float128_t}\iref{stdfloat.syn} +have a greater conversion subrank than any standard floating-point type +with equal conversion rank. +Otherwise, the conversion subrank order is +\impldef{floating-point conversion subrank}. + +\pnum +\begin{note} +The floating-point conversion rank and subrank are used in +the definition of the usual arithmetic conversions\iref{expr.arith.conv}. +\end{note} + \rSec1[basic.exec]{Program execution} \rSec2[intro.execution]{Sequential execution} diff --git a/source/declarations.tex b/source/declarations.tex index 27b1fa751a..0b2e7d86b1 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -5948,8 +5948,10 @@ \begin{itemize} \item from a floating-point type to an integer type, or -\item from \tcode{long double} to \tcode{double} or \tcode{float}, or from -\tcode{double} to \tcode{float}, except where the source is a constant expression and +\item from a floating-point type \tcode{T} to another floating-point type +whose floating-point conversion rank is neither greater than nor equal to +that of \tcode{T}, +except where the source is a constant expression and the actual value after conversion is within the range of values that can be represented (even if it cannot be represented exactly), or diff --git a/source/expressions.tex b/source/expressions.tex index 04d2da8ce5..71906feade 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -929,7 +929,13 @@ \pnum \indextext{conversion!floating-point}% A prvalue of floating-point type can be converted to a prvalue of -another floating-point type. If the source value can be exactly +another floating-point type +with a greater or equal conversion rank\iref{conv.rank}. +A prvalue of standard floating-point type can be converted to +a prvalue of another standard floating-point type. + +\pnum +If the source value can be exactly represented in the destination type, the result of the conversion is that exact representation. If the source value is between two adjacent destination values, the result of the conversion is an @@ -1114,24 +1120,36 @@ \item If either operand is of scoped enumeration type\iref{dcl.enum}, no conversions are performed; if the other operand does not have the same type, the expression is ill-formed. - -\item If either operand is of type \tcode{\keyword{long} \keyword{double}}, the -other shall be converted to \tcode{\keyword{long} \keyword{double}}. - -\item Otherwise, if either operand is \keyword{double}, the other shall be -converted to \keyword{double}. - -\item Otherwise, if either operand is \keyword{float}, the other shall be -converted to \keyword{float}. - -\item Otherwise, the integral promotions\iref{conv.prom} shall be +\item Otherwise, if either operand is of floating-point type, +the following rules are applied: +\begin{itemize} +\item +If both operands have the same type, no further conversion is needed. +\item +Otherwise, if one of the operands is of a non-floating-point type, +that operand is converted to the type of +the operand with the floating-point type. +\item +Otherwise, if the floating-point conversion ranks\iref{conv.rank} of +the types of the operands are ordered but not equal, +then the operand of the type with the lesser floating-point conversion rank +is converted to the type of the other operand. +\item +Otherwise, if the floating-point conversion ranks of the types of +the operands are equal, +then the operand with the lesser floating-point conversion subrank\iref{conv.rank} +is converted to the type of the other operand. +\item +Otherwise, the expression is ill-formed. +\end{itemize} +\item Otherwise, the integral promotions\iref{conv.prom} are performed on both operands. \begin{footnote} As a consequence, operands of type \keyword{bool}, \keyword{char8_t}, \keyword{char16_t}, \keyword{char32_t}, \keyword{wchar_t}, or an enumerated type are converted to some integral type. \end{footnote} -Then the following rules shall be applied to the promoted operands: +Then the following rules are applied to the promoted operands: \begin{itemize} @@ -1140,20 +1158,20 @@ \item Otherwise, if both operands have signed integer types or both have unsigned integer types, the operand with the type of lesser integer -conversion rank shall be converted to the type of the operand with +conversion rank is converted to the type of the operand with greater rank. \item Otherwise, if the operand that has unsigned integer type has rank greater than or equal to the rank of the type of the other operand, the -operand with signed integer type shall be converted to the type of the +operand with signed integer type is converted to the type of the operand with unsigned integer type. \item Otherwise, if the type of the operand with signed integer type can represent all of the values of the type of the operand with unsigned -integer type, the operand with unsigned integer type shall be converted +integer type, the operand with unsigned integer type is converted to the type of the operand with signed integer type. -\item Otherwise, both operands shall be converted to the unsigned +\item Otherwise, both operands are converted to the unsigned integer type corresponding to the type of the operand with signed integer type. \end{itemize} @@ -4096,6 +4114,17 @@ underlying type of the enumeration\iref{conv.fpint}, and subsequently to the enumeration type. +\pnum +A prvalue of floating-point type can be explicitly converted to +any other floating-point type. +If the source value can be exactly represented in the destination type, +the result of the conversion has that exact representation. +If the source value is between two adjacent destination values, +the result of the conversion is +an \impldef{result of inexact floating-point conversion} choice of +either of those values. +Otherwise, the behavior is undefined. + \pnum \indextext{cast!base class}% \indextext{cast!derived class}% diff --git a/source/intro.tex b/source/intro.tex index 9200f81357..f24ffd011f 100644 --- a/source/intro.tex +++ b/source/intro.tex @@ -33,6 +33,7 @@ For undated references, the latest edition of the referenced document (including any amendments) applies. \begin{itemize} +% ISO documents in numerical order. \item ISO/IEC 2382, \doccite{Information technology --- Vocabulary} \item ISO 8601:2004, \doccite{Data elements and interchange formats --- Information interchange --- Representation of dates and times} @@ -58,9 +59,12 @@ \end{footnote} \doccite{Information technology --- Universal Multiple-Octet Coded Character Set (UCS)} +\item ISO/IEC/IEEE 60559:2020, \doccite{Information technology --- +Microprocessor Systems --- Floating-Point arithmetic} \item ISO 80000-2:2009, \doccite{Quantities and units --- Part 2: Mathematical signs and symbols to be used in the natural sciences and technology} +% Other international standards. \item Ecma International, \doccite{ECMAScript \begin{footnote} ECMAScript\textregistered\ is a registered trademark of Ecma diff --git a/source/iostreams.tex b/source/iostreams.tex index 2cd777e276..ac91f6ed3a 100644 --- a/source/iostreams.tex +++ b/source/iostreams.tex @@ -4216,6 +4216,13 @@ \rSec4[istream.general]{General} +\pnum +When a function is specified +with a type placeholder of \tcode{\placeholder{extended-floating-point-type}}, +the implementation provides overloads +for all cv-unqualified extended floating-point types\iref{basic.fundamental} +in lieu of \tcode{\placeholder{extended-floating-\brk{}point-type}}. + \indexlibraryglobal{basic_istream}% \begin{codeblock} namespace std { @@ -4253,6 +4260,7 @@ basic_istream& operator>>(float& f); basic_istream& operator>>(double& f); basic_istream& operator>>(long double& f); + basic_istream& operator>>(@\placeholder{extended-floating-point-type}@& f); basic_istream& operator>>(void*& p); basic_istream& operator>>(basic_streambuf* sb); @@ -4729,6 +4737,64 @@ \end{codeblock} \end{itemdescr} +\begin{itemdecl} +basic_istream& operator>>(@\placeholder{extended-floating-point-type}@& val); +\end{itemdecl} + +\begin{itemdescr} +\pnum +If +the floating-point conversion rank of \tcode{\placeholder{extended-floating-point-type}} +is not less than or equal to that of \tcode{long double}, +then an invocation of the operator function is conditionally supported +with \impldef{\tcode{operator>>} for large extended floating-point types} +semantics. + +\pnum +Otherwise, let \tcode{FP} be a standard floating-point type: +\begin{itemize} +\item +if the floating-point conversion rank of \tcode{\placeholder{extended-floating-point-type}} +is less than or equal to that of \tcode{float}, +then \tcode{FP} is \tcode{float}, +\item +otherwise, +if the floating-point conversion rank of \tcode{\placeholder{extended-floating-point-type}} +is less than or equal to that of \tcode{double}, +then \tcode{FP} is \tcode{double}, +\item +otherwise, \tcode{FP} is \tcode{long double}. +\end{itemize} + +\pnum +The conversion occurs as if performed by the following code fragment +(using the same notation as for the preceding code fragment): +\begin{codeblock} +using numget = num_get>; +iostate err = ios_base::goodbit; +FP fval; +use_facet(loc).get(*this, 0, *this, err, fval); +if (fval < -numeric_limits<@\placeholder{extended-floating-point-type}@>::max()) { + err |= ios_base::failbit; + val = -numeric_limits<@\placeholder{extended-floating-point-type}@>::max(); +} else if (numeric_limits<@\placeholder{extended-floating-point-type}@>::max() < fval) { + err |= ios_base::failbit; + val = numeric_limits<@\placeholder{extended-floating-point-type}@>::max(); +} else { + val = static_cast<@\placeholder{extended-floating-point-type}@>(fval); +} +setstate(err); +\end{codeblock} +\begin{note} +When the extended floating-point type has +a floating-point conversion rank +that is not equal to the rank of any standard floating-point type, +then double rounding during the conversion can result in inaccurate results. +\tcode{from_chars} can be used in situations +where maximum accuracy is important. +\end{note} +\end{itemdescr} + \rSec4[istream.extractors]{\tcode{basic_istream::operator>>}} \indexlibrarymember{operator>>}{basic_istream}% @@ -5811,6 +5877,12 @@ \rSec4[ostream.general]{General} +\pnum +When a function has +a parameter type \tcode{\placeholder{extended-floating-point-type}}, +the implementation provides overloads +for all cv-unqualified extended floating-point types\iref{basic.fundamental}. + \indexlibraryglobal{basic_ostream}% \begin{codeblock} namespace std { @@ -5848,6 +5920,7 @@ basic_ostream& operator<<(float f); basic_ostream& operator<<(double f); basic_ostream& operator<<(long double f); + basic_ostream& operator<<(@\placeholder{extended-floating-point-type}@ f); basic_ostream& operator<<(const void* p); basic_ostream& operator<<(const volatile void* p); @@ -6427,6 +6500,44 @@ Equivalent to: \tcode{return operator<<(const_cast(p));} \end{itemdescr} +\begin{itemdecl} +basic_ostream& operator<<(@\placeholder{extended-floating-point-type}@ val); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +If the floating-point conversion rank of \tcode{\placeholder{extended-floating-point-type}} +is less than or equal to that of \tcode{double}, +the formatting conversion occurs as if it performed the following code fragment: +\begin{codeblock} +bool failed = use_facet< + num_put> + >(getloc()).put(*this, *this, fill(), + static_cast(val)).failed(); +\end{codeblock} +Otherwise, +if the floating-point conversion rank of \tcode{\placeholder{extended-floating-point-type}} +is less than or equal to that of \tcode{long double}, +the formatting conversion occurs as if it performed the following code fragment: +\begin{codeblock} +bool failed = use_facet< + num_put> + >(getloc()).put(*this, *this, fill(), + static_cast(val)).failed(); +\end{codeblock} +Otherwise, an invocation of the operator function is conditionally supported +with \impldef{\tcode{operator<<} for large extended floating-point types} +semantics. + +If \tcode{failed} is \tcode{true} then does \tcode{setstate(badbit)}, +which may throw an exception, and returns. + +\pnum +\returns +\tcode{*this}. +\end{itemdescr} + \rSec4[ostream.inserters]{\tcode{basic_ostream::operator<<}} \indexlibrarymember{operator<<}{basic_ostream}% diff --git a/source/lex.tex b/source/lex.tex index afc0772746..9c8c403056 100644 --- a/source/lex.tex +++ b/source/lex.tex @@ -1728,7 +1728,7 @@ \begin{bnf} \nontermdef{floating-point-suffix} \textnormal{one of}\br - \terminal{f l F L} + \terminal{f l f16 f32 f64 f128 bf16 F L F16 F32 F64 F128 BF16} \end{bnf} \pnum @@ -1739,8 +1739,16 @@ \indextext{suffix!\idxcode{L}}% \indextext{suffix!\idxcode{l}}% \indextext{literal!\idxcode{long double}}% -The type of a \grammarterm{floating-point-literal} is determined by +The type of +a \grammarterm{floating-point-literal}\iref{basic.fundamental,basic.extended.fp} +is determined by its \grammarterm{floating-point-suffix} as specified in \tref{lex.fcon.type}. +\begin{note} +The floating-point suffixes +\tcode{f16}, \tcode{f32}, \tcode{f64}, \tcode{f128}, \tcode{bf16}, +\tcode{F16}, \tcode{F32}, \tcode{F64}, \tcode{F128}, and \tcode{BF16} +are conditionally-supported. See \ref{basic.extended.fp}. +\end{note} \begin{simpletypetable} {Types of \grammarterm{floating-point-literal}{s}} {lex.fcon.type} @@ -1750,6 +1758,11 @@ none & \keyword{double} \\ \tcode{f} or \tcode{F} & \keyword {float} \\ \tcode{l} or \tcode{L} & \keyword{long} \keyword{double} \\ +\tcode{f16} or \tcode{F16} & \tcode{std::float16_t} \\ +\tcode{f32} or \tcode{F32} & \tcode{std::float32_t} \\ +\tcode{f64} or \tcode{F64} & \tcode{std::float64_t} \\ +\tcode{f128} or \tcode{F128} & \tcode{std::float128_t} \\ +\tcode{bf16} or \tcode{BF16} & \tcode{std::bfloat16_t} \\ \end{simpletypetable} \pnum diff --git a/source/lib-intro.tex b/source/lib-intro.tex index 93e3a47587..3ddadeaf3d 100644 --- a/source/lib-intro.tex +++ b/source/lib-intro.tex @@ -1073,6 +1073,7 @@ \tcode{} \\ \columnbreak \tcode{} \\ +\tcode{} \\ \tcode{} \\ \tcode{} \\ \tcode{} \\ diff --git a/source/numerics.tex b/source/numerics.tex index 8d7df319d7..c940e27b47 100644 --- a/source/numerics.tex +++ b/source/numerics.tex @@ -190,13 +190,11 @@ and numerous functions for representing and manipulating complex numbers. \pnum -The effect of instantiating the template -\tcode{complex} -for any type other than \tcode{float}, \tcode{double}, or \tcode{long double} is unspecified. -The specializations -\tcode{complex}, -\tcode{complex}, and -\tcode{complex} are literal types\iref{term.literal.type}. +The effect of instantiating the template \tcode{complex} for any type +that is not a cv-unqualified floating-point type\iref{basic.fundamental} +is unspecified. +Specializations of \tcode{complex} for cv-unqualified floating-point types +are trivially-copyable literal types\iref{term.literal.type}. \pnum If the result of a function is not mathematically defined or not in @@ -225,11 +223,6 @@ // \ref{complex}, class template \tcode{complex} template class complex; - // \ref{complex.special}, specializations - template<> class complex; - template<> class complex; - template<> class complex; - // \ref{complex.ops}, operators template constexpr complex operator+(const complex&, const complex&); template constexpr complex operator+(const complex&, const T&); @@ -321,8 +314,8 @@ using value_type = T; constexpr complex(const T& re = T(), const T& im = T()); - constexpr complex(const complex&); - template constexpr complex(const complex&); + constexpr complex(const complex&) = default; + template constexpr explicit(@\seebelow@) complex(const complex&); constexpr T real() const; constexpr void real(T); @@ -356,96 +349,6 @@ of a complex number. -\rSec2[complex.special]{Specializations} - -\begin{codeblock} -namespace std { - template<> class complex { - public: - using value_type = float; - - constexpr complex(float re = 0.0f, float im = 0.0f); - constexpr complex(const complex&) = default; - constexpr explicit complex(const complex&); - constexpr explicit complex(const complex&); - - constexpr float real() const; - constexpr void real(float); - constexpr float imag() const; - constexpr void imag(float); - - constexpr complex& operator= (float); - constexpr complex& operator+=(float); - constexpr complex& operator-=(float); - constexpr complex& operator*=(float); - constexpr complex& operator/=(float); - - constexpr complex& operator=(const complex&); - template constexpr complex& operator= (const complex&); - template constexpr complex& operator+=(const complex&); - template constexpr complex& operator-=(const complex&); - template constexpr complex& operator*=(const complex&); - template constexpr complex& operator/=(const complex&); - }; - - template<> class complex { - public: - using value_type = double; - - constexpr complex(double re = 0.0, double im = 0.0); - constexpr complex(const complex&); - constexpr complex(const complex&) = default; - constexpr explicit complex(const complex&); - - constexpr double real() const; - constexpr void real(double); - constexpr double imag() const; - constexpr void imag(double); - - constexpr complex& operator= (double); - constexpr complex& operator+=(double); - constexpr complex& operator-=(double); - constexpr complex& operator*=(double); - constexpr complex& operator/=(double); - - constexpr complex& operator=(const complex&); - template constexpr complex& operator= (const complex&); - template constexpr complex& operator+=(const complex&); - template constexpr complex& operator-=(const complex&); - template constexpr complex& operator*=(const complex&); - template constexpr complex& operator/=(const complex&); - }; - - template<> class complex { - public: - using value_type = long double; - - constexpr complex(long double re = 0.0L, long double im = 0.0L); - constexpr complex(const complex&); - constexpr complex(const complex&); - constexpr complex(const complex&) = default; - - constexpr long double real() const; - constexpr void real(long double); - constexpr long double imag() const; - constexpr void imag(long double); - - constexpr complex& operator= (long double); - constexpr complex& operator+=(long double); - constexpr complex& operator-=(long double); - constexpr complex& operator*=(long double); - constexpr complex& operator/=(long double); - - constexpr complex& operator=(const complex&); - template constexpr complex& operator= (const complex&); - template constexpr complex& operator+=(const complex&); - template constexpr complex& operator-=(const complex&); - template constexpr complex& operator*=(const complex&); - template constexpr complex& operator/=(const complex&); - }; -} -\end{codeblock} - \rSec2[complex.members]{Member functions} \indexlibraryctor{complex}% @@ -459,6 +362,24 @@ \tcode{real() == re \&\& imag() == im} is \tcode{true}. \end{itemdescr} +\indexlibraryctor{complex}% +\begin{itemdecl} +template constexpr explicit(@\seebelow@) complex(const complex& other); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes the real part with \tcode{other.real()} and +the imaginary part with \tcode{other.imag()}. + +\pnum +\remarks +The expression inside \tcode{explicit} evaluates to \tcode{false} +if and only if the floating-point conversion rank of \tcode{T} +is greater than or equal to the floating-point conversion rank of \tcode{X}. +\end{itemdescr} + \indexlibrarymember{real}{complex}% \begin{itemdecl} constexpr T real() const; @@ -1203,28 +1124,22 @@ \indextext{overloads!floating-point}% The additional overloads shall be sufficient to ensure: \begin{itemize} - \item If the argument has type \tcode{long double}, then it is effectively - cast to \tcode{complex}. - \item Otherwise, if the argument has type \tcode{double} or an integer type, - then it is effectively cast to \tcode{complex<\brk{}double>}. - \item Otherwise, if the argument has type \tcode{float}, then it is - effectively cast to \tcode{complex}. +\item +If the argument has a floating-point type \tcode{T}, +then it is effectively cast to \tcode{complex}. +\item +Otherwise, if the argument has integer type, +then it is effectively cast to \tcode{complex}. \end{itemize} \pnum \indexlibraryglobal{pow}% -Function template \tcode{pow} shall have additional overloads sufficient to -ensure, for a call with at least one argument of type \tcode{complex}: -\begin{itemize} - \item If either argument has type \tcode{complex} or type \tcode{long - double}, then both arguments are effectively cast to - \tcode{complex}. - \item Otherwise, if either argument has type \tcode{complex}, \tcode{double}, - or an integer type, then both arguments are effectively cast to - \tcode{complex}. - \item Otherwise, if either argument has type \tcode{complex} or \tcode{float}, - then both arguments are effectively cast to \tcode{complex}. -\end{itemize} +Function template \tcode{pow} has additional overloads sufficient to ensure, +for a call with one argument of type \tcode{complex} and +the other argument of type \tcode{T2} or \tcode{complex}, +both arguments are effectively cast to \tcode{complex>}. +If \tcode{common_type_t} is not well-formed, +then the program is ill-formed. \rSec2[complex.literals]{Suffixes for complex number literals} @@ -9029,171 +8944,115 @@ #define math_errhandling @\seebelow@ namespace std { - float acos(float x); // see \ref{library.c} - double acos(double x); - long double acos(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ acos(@\placeholder{floating-point-type}@ x); float acosf(float x); long double acosl(long double x); - float asin(float x); // see \ref{library.c} - double asin(double x); - long double asin(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ asin(@\placeholder{floating-point-type}@ x); float asinf(float x); long double asinl(long double x); - float atan(float x); // see \ref{library.c} - double atan(double x); - long double atan(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ atan(@\placeholder{floating-point-type}@ x); float atanf(float x); long double atanl(long double x); - float atan2(float y, float x); // see \ref{library.c} - double atan2(double y, double x); - long double atan2(long double y, long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ atan2(@\placeholder{floating-point-type}@ y, @\placeholder{floating-point-type}@ x); float atan2f(float y, float x); long double atan2l(long double y, long double x); - float cos(float x); // see \ref{library.c} - double cos(double x); - long double cos(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ cos(@\placeholder{floating-point-type}@ x); float cosf(float x); long double cosl(long double x); - float sin(float x); // see \ref{library.c} - double sin(double x); - long double sin(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ sin(@\placeholder{floating-point-type}@ x); float sinf(float x); long double sinl(long double x); - float tan(float x); // see \ref{library.c} - double tan(double x); - long double tan(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ tan(@\placeholder{floating-point-type}@ x); float tanf(float x); long double tanl(long double x); - float acosh(float x); // see \ref{library.c} - double acosh(double x); - long double acosh(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ acosh(@\placeholder{floating-point-type}@ x); float acoshf(float x); long double acoshl(long double x); - float asinh(float x); // see \ref{library.c} - double asinh(double x); - long double asinh(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ asinh(@\placeholder{floating-point-type}@ x); float asinhf(float x); long double asinhl(long double x); - float atanh(float x); // see \ref{library.c} - double atanh(double x); - long double atanh(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ atanh(@\placeholder{floating-point-type}@ x); float atanhf(float x); long double atanhl(long double x); - float cosh(float x); // see \ref{library.c} - double cosh(double x); - long double cosh(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ cosh(@\placeholder{floating-point-type}@ x); float coshf(float x); long double coshl(long double x); - float sinh(float x); // see \ref{library.c} - double sinh(double x); - long double sinh(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ sinh(@\placeholder{floating-point-type}@ x); float sinhf(float x); long double sinhl(long double x); - float tanh(float x); // see \ref{library.c} - double tanh(double x); - long double tanh(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ tanh(@\placeholder{floating-point-type}@ x); float tanhf(float x); long double tanhl(long double x); - float exp(float x); // see \ref{library.c} - double exp(double x); - long double exp(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ exp(@\placeholder{floating-point-type}@ x); float expf(float x); long double expl(long double x); - float exp2(float x); // see \ref{library.c} - double exp2(double x); - long double exp2(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ exp2(@\placeholder{floating-point-type}@ x); float exp2f(float x); long double exp2l(long double x); - float expm1(float x); // see \ref{library.c} - double expm1(double x); - long double expm1(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ expm1(@\placeholder{floating-point-type}@ x); float expm1f(float x); long double expm1l(long double x); - constexpr float frexp(float value, int* exp); // see \ref{library.c} - constexpr double frexp(double value, int* exp); - constexpr long double frexp(long double value, int* exp); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ frexp(@\placeholder{floating-point-type}@ value, int* exp); constexpr float frexpf(float value, int* exp); constexpr long double frexpl(long double value, int* exp); - constexpr int ilogb(float x); // see \ref{library.c} - constexpr int ilogb(double x); - constexpr int ilogb(long double x); // see \ref{library.c} + constexpr int ilogb(@\placeholder{floating-point-type}@ x); constexpr int ilogbf(float x); constexpr int ilogbl(long double x); - constexpr float ldexp(float x, int exp); // see \ref{library.c} - constexpr double ldexp(double x, int exp); - constexpr long double ldexp(long double x, int exp); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ ldexp(@\placeholder{floating-point-type}@ x, int exp); constexpr float ldexpf(float x, int exp); constexpr long double ldexpl(long double x, int exp); - float log(float x); // see \ref{library.c} - double log(double x); - long double log(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ log(@\placeholder{floating-point-type}@ x); float logf(float x); long double logl(long double x); - float log10(float x); // see \ref{library.c} - double log10(double x); - long double log10(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ log10(@\placeholder{floating-point-type}@ x); float log10f(float x); long double log10l(long double x); - float log1p(float x); // see \ref{library.c} - double log1p(double x); - long double log1p(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ log1p(@\placeholder{floating-point-type}@ x); float log1pf(float x); long double log1pl(long double x); - float log2(float x); // see \ref{library.c} - double log2(double x); - long double log2(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ log2(@\placeholder{floating-point-type}@ x); float log2f(float x); long double log2l(long double x); - constexpr float logb(float x); // see \ref{library.c} - constexpr double logb(double x); - constexpr long double logb(long double x); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ logb(@\placeholder{floating-point-type}@ x); constexpr float logbf(float x); constexpr long double logbl(long double x); - constexpr float modf(float value, float* iptr); // see \ref{library.c} - constexpr double modf(double value, double* iptr); - constexpr long double modf(long double value, long double* iptr); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ modf(@\placeholder{floating-point-type}@ value, @\placeholder{floating-point-type}@* iptr); constexpr float modff(float value, float* iptr); constexpr long double modfl(long double value, long double* iptr); - constexpr float scalbn(float x, int n); // see \ref{library.c} - constexpr double scalbn(double x, int n); - constexpr long double scalbn(long double x, int n); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ scalbn(@\placeholder{floating-point-type}@ x, int n); constexpr float scalbnf(float x, int n); constexpr long double scalbnl(long double x, int n); - constexpr float scalbln(float x, long int n); // see \ref{library.c} - constexpr double scalbln(double x, long int n); - constexpr long double scalbln(long double x, long int n); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ scalbln(@\placeholder{floating-point-type}@ x, long int n); constexpr float scalblnf(float x, long int n); constexpr long double scalblnl(long double x, long int n); - float cbrt(float x); // see \ref{library.c} - double cbrt(double x); - long double cbrt(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ cbrt(@\placeholder{floating-point-type}@ x); float cbrtf(float x); long double cbrtl(long double x); @@ -9201,144 +9060,97 @@ constexpr int abs(int j); constexpr long int abs(long int j); constexpr long long int abs(long long int j); - constexpr float abs(float j); - constexpr double abs(double j); - constexpr long double abs(long double j); + constexpr @\placeholder{floating-point-type}@ abs(@\placeholder{floating-point-type}@ j); - constexpr float fabs(float x); // see \ref{library.c} - constexpr double fabs(double x); - constexpr long double fabs(long double x); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ fabs(@\placeholder{floating-point-type}@ x); constexpr float fabsf(float x); constexpr long double fabsl(long double x); - float hypot(float x, float y); // see \ref{library.c} - double hypot(double x, double y); - long double hypot(long double x, long double y); // see \ref{library.c} + @\placeholder{floating-point-type}@ hypot(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); float hypotf(float x, float y); long double hypotl(long double x, long double y); // \ref{c.math.hypot3}, three-dimensional hypotenuse - float hypot(float x, float y, float z); - double hypot(double x, double y, double z); - long double hypot(long double x, long double y, long double z); + @\placeholder{floating-point-type}@ hypot(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y, + @\placeholder{floating-point-type}@ z); - float pow(float x, float y); // see \ref{library.c} - double pow(double x, double y); - long double pow(long double x, long double y); // see \ref{library.c} + @\placeholder{floating-point-type}@ pow(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); float powf(float x, float y); long double powl(long double x, long double y); - float sqrt(float x); // see \ref{library.c} - double sqrt(double x); - long double sqrt(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ sqrt(@\placeholder{floating-point-type}@ x); float sqrtf(float x); long double sqrtl(long double x); - float erf(float x); // see \ref{library.c} - double erf(double x); - long double erf(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ erf(@\placeholder{floating-point-type}@ x); float erff(float x); long double erfl(long double x); - float erfc(float x); // see \ref{library.c} - double erfc(double x); - long double erfc(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ erfc(@\placeholder{floating-point-type}@ x); float erfcf(float x); long double erfcl(long double x); - float lgamma(float x); // see \ref{library.c} - double lgamma(double x); - long double lgamma(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ lgamma(@\placeholder{floating-point-type}@ x); float lgammaf(float x); long double lgammal(long double x); - float tgamma(float x); // see \ref{library.c} - double tgamma(double x); - long double tgamma(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ tgamma(@\placeholder{floating-point-type}@ x); float tgammaf(float x); long double tgammal(long double x); - constexpr float ceil(float x); // see \ref{library.c} - constexpr double ceil(double x); - constexpr long double ceil(long double x); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ ceil(@\placeholder{floating-point-type}@ x); constexpr float ceilf(float x); constexpr long double ceill(long double x); - constexpr float floor(float x); // see \ref{library.c} - constexpr double floor(double x); - constexpr long double floor(long double x); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ floor(@\placeholder{floating-point-type}@ x); constexpr float floorf(float x); constexpr long double floorl(long double x); - float nearbyint(float x); // see \ref{library.c} - double nearbyint(double x); - long double nearbyint(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ nearbyint(@\placeholder{floating-point-type}@ x); float nearbyintf(float x); long double nearbyintl(long double x); - float rint(float x); // see \ref{library.c} - double rint(double x); - long double rint(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ rint(@\placeholder{floating-point-type}@ x); float rintf(float x); long double rintl(long double x); - long int lrint(float x); // see \ref{library.c} - long int lrint(double x); - long int lrint(long double x); // see \ref{library.c} + long int lrint(@\placeholder{floating-point-type}@ x); long int lrintf(float x); long int lrintl(long double x); - long long int llrint(float x); // see \ref{library.c} - long long int llrint(double x); - long long int llrint(long double x); // see \ref{library.c} + long long int llrint(@\placeholder{floating-point-type}@ x); long long int llrintf(float x); long long int llrintl(long double x); - constexpr float round(float x); // see \ref{library.c} - constexpr double round(double x); - constexpr long double round(long double x); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ round(@\placeholder{floating-point-type}@ x); constexpr float roundf(float x); constexpr long double roundl(long double x); - constexpr long int lround(float x); // see \ref{library.c} - constexpr long int lround(double x); - constexpr long int lround(long double x); // see \ref{library.c} + constexpr long int lround(@\placeholder{floating-point-type}@ x); constexpr long int lroundf(float x); constexpr long int lroundl(long double x); - constexpr long long int llround(float x); // see \ref{library.c} - constexpr long long int llround(double x); - constexpr long long int llround(long double x); // see \ref{library.c} + constexpr long long int llround(@\placeholder{floating-point-type}@ x); constexpr long long int llroundf(float x); constexpr long long int llroundl(long double x); - constexpr float trunc(float x); // see \ref{library.c} - constexpr double trunc(double x); - constexpr long double trunc(long double x); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ trunc(@\placeholder{floating-point-type}@ x); constexpr float truncf(float x); constexpr long double truncl(long double x); - constexpr float fmod(float x, float y); // see \ref{library.c} - constexpr double fmod(double x, double y); - constexpr long double fmod(long double x, long double y); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ fmod(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); constexpr float fmodf(float x, float y); constexpr long double fmodl(long double x, long double y); - constexpr float remainder(float x, float y); // see \ref{library.c} - constexpr double remainder(double x, double y); - constexpr long double remainder(long double x, long double y); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ remainder(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); constexpr float remainderf(float x, float y); constexpr long double remainderl(long double x, long double y); - constexpr float remquo(float x, float y, int* quo); // see \ref{library.c} - constexpr double remquo(double x, double y, int* quo); - constexpr long double remquo(long double x, long double y, int* quo); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ remquo(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y, int* quo); constexpr float remquof(float x, float y, int* quo); constexpr long double remquol(long double x, long double y, int* quo); - constexpr float copysign(float x, float y); // see \ref{library.c} - constexpr double copysign(double x, double y); - constexpr long double copysign(long double x, long double y); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ copysign(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); constexpr float copysignf(float x, float y); constexpr long double copysignl(long double x, long double y); @@ -9346,202 +9158,156 @@ float nanf(const char* tagp); long double nanl(const char* tagp); - constexpr float nextafter(float x, float y); // see \ref{library.c} - constexpr double nextafter(double x, double y); - constexpr long double nextafter(long double x, long double y); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ nextafter(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); constexpr float nextafterf(float x, float y); constexpr long double nextafterl(long double x, long double y); - constexpr float nexttoward(float x, long double y); // see \ref{library.c} - constexpr double nexttoward(double x, long double y); - constexpr long double nexttoward(long double x, long double y); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ nexttoward(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); constexpr float nexttowardf(float x, long double y); constexpr long double nexttowardl(long double x, long double y); - constexpr float fdim(float x, float y); // see \ref{library.c} - constexpr double fdim(double x, double y); - constexpr long double fdim(long double x, long double y); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ fdim(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); constexpr float fdimf(float x, float y); constexpr long double fdiml(long double x, long double y); - constexpr float fmax(float x, float y); // see \ref{library.c} - constexpr double fmax(double x, double y); - constexpr long double fmax(long double x, long double y); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ fmax(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); constexpr float fmaxf(float x, float y); constexpr long double fmaxl(long double x, long double y); - constexpr float fmin(float x, float y); // see \ref{library.c} - constexpr double fmin(double x, double y); - constexpr long double fmin(long double x, long double y); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ fmin(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); constexpr float fminf(float x, float y); constexpr long double fminl(long double x, long double y); - constexpr float fma(float x, float y, float z); // see \ref{library.c} - constexpr double fma(double x, double y, double z); - constexpr long double fma(long double x, long double y, long double z); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ fma(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y, + @\placeholder{floating-point-type}@ z); constexpr float fmaf(float x, float y, float z); constexpr long double fmal(long double x, long double y, long double z); // \ref{c.math.lerp}, linear interpolation - constexpr float lerp(float a, float b, float t) noexcept; - constexpr double lerp(double a, double b, double t) noexcept; - constexpr long double lerp(long double a, long double b, long double t) noexcept; + constexpr @\placeholder{floating-point-type}@ lerp(@\placeholder{floating-point-type}@ a, @\placeholder{floating-point-type}@ b, + @\placeholder{floating-point-type}@ t) noexcept; // \ref{c.math.fpclass}, classification / comparison functions - constexpr int fpclassify(float x); - constexpr int fpclassify(double x); - constexpr int fpclassify(long double x); - - constexpr bool isfinite(float x); - constexpr bool isfinite(double x); - constexpr bool isfinite(long double x); - - constexpr bool isinf(float x); - constexpr bool isinf(double x); - constexpr bool isinf(long double x); - - constexpr bool isnan(float x); - constexpr bool isnan(double x); - constexpr bool isnan(long double x); - - constexpr bool isnormal(float x); - constexpr bool isnormal(double x); - constexpr bool isnormal(long double x); - - constexpr bool signbit(float x); - constexpr bool signbit(double x); - constexpr bool signbit(long double x); - - constexpr bool isgreater(float x, float y); - constexpr bool isgreater(double x, double y); - constexpr bool isgreater(long double x, long double y); - - constexpr bool isgreaterequal(float x, float y); - constexpr bool isgreaterequal(double x, double y); - constexpr bool isgreaterequal(long double x, long double y); - - constexpr bool isless(float x, float y); - constexpr bool isless(double x, double y); - constexpr bool isless(long double x, long double y); - - constexpr bool islessequal(float x, float y); - constexpr bool islessequal(double x, double y); - constexpr bool islessequal(long double x, long double y); - - constexpr bool islessgreater(float x, float y); - constexpr bool islessgreater(double x, double y); - constexpr bool islessgreater(long double x, long double y); - - constexpr bool isunordered(float x, float y); - constexpr bool isunordered(double x, double y); - constexpr bool isunordered(long double x, long double y); + constexpr int fpclassify(@\placeholder{floating-point-type}@ x); + constexpr bool isfinite(@\placeholder{floating-point-type}@ x); + constexpr bool isinf(@\placeholder{floating-point-type}@ x); + constexpr bool isnan(@\placeholder{floating-point-type}@ x); + constexpr bool isnormal(@\placeholder{floating-point-type}@ x); + constexpr bool signbit(@\placeholder{floating-point-type}@ x); + constexpr bool isgreater(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); + constexpr bool isgreaterequal(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); + constexpr bool isless(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); + constexpr bool islessequal(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); + constexpr bool islessgreater(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); + constexpr bool isunordered(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); // \ref{sf.cmath}, mathematical special functions // \ref{sf.cmath.assoc.laguerre}, associated Laguerre polynomials - double assoc_laguerre(unsigned n, unsigned m, double x); + @\placeholder{floating-point-type}@ assoc_laguerre(unsigned n, unsigned m, @\placeholder{floating-point-type}@ x); float assoc_laguerref(unsigned n, unsigned m, float x); long double assoc_laguerrel(unsigned n, unsigned m, long double x); // \ref{sf.cmath.assoc.legendre}, associated Legendre functions - double assoc_legendre(unsigned l, unsigned m, double x); + @\placeholder{floating-point-type}@ assoc_legendre(unsigned l, unsigned m, @\placeholder{floating-point-type}@ x); float assoc_legendref(unsigned l, unsigned m, float x); long double assoc_legendrel(unsigned l, unsigned m, long double x); // \ref{sf.cmath.beta}, beta function - double beta(double x, double y); + @\placeholder{floating-point-type}@ beta(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); float betaf(float x, float y); long double betal(long double x, long double y); // \ref{sf.cmath.comp.ellint.1}, complete elliptic integral of the first kind - double comp_ellint_1(double k); + @\placeholder{floating-point-type}@ comp_ellint_1(@\placeholder{floating-point-type}@ k); float comp_ellint_1f(float k); long double comp_ellint_1l(long double k); // \ref{sf.cmath.comp.ellint.2}, complete elliptic integral of the second kind - double comp_ellint_2(double k); + @\placeholder{floating-point-type}@ comp_ellint_2(@\placeholder{floating-point-type}@ k); float comp_ellint_2f(float k); long double comp_ellint_2l(long double k); // \ref{sf.cmath.comp.ellint.3}, complete elliptic integral of the third kind - double comp_ellint_3(double k, double nu); + @\placeholder{floating-point-type}@ comp_ellint_3(@\placeholder{floating-point-type}@ k, @\placeholder{floating-point-type}@ nu); float comp_ellint_3f(float k, float nu); long double comp_ellint_3l(long double k, long double nu); // \ref{sf.cmath.cyl.bessel.i}, regular modified cylindrical Bessel functions - double cyl_bessel_i(double nu, double x); + @\placeholder{floating-point-type}@ cyl_bessel_i(@\placeholder{floating-point-type}@ nu, @\placeholder{floating-point-type}@ x); float cyl_bessel_if(float nu, float x); long double cyl_bessel_il(long double nu, long double x); // \ref{sf.cmath.cyl.bessel.j}, cylindrical Bessel functions of the first kind - double cyl_bessel_j(double nu, double x); + @\placeholder{floating-point-type}@ cyl_bessel_j(@\placeholder{floating-point-type}@ nu, @\placeholder{floating-point-type}@ x); float cyl_bessel_jf(float nu, float x); long double cyl_bessel_jl(long double nu, long double x); // \ref{sf.cmath.cyl.bessel.k}, irregular modified cylindrical Bessel functions - double cyl_bessel_k(double nu, double x); + @\placeholder{floating-point-type}@ cyl_bessel_k(@\placeholder{floating-point-type}@ nu, @\placeholder{floating-point-type}@ x); float cyl_bessel_kf(float nu, float x); long double cyl_bessel_kl(long double nu, long double x); - // \ref{sf.cmath.cyl.neumann}, cylindrical Neumann functions; + // \ref{sf.cmath.cyl.neumann}, cylindrical Neumann functions // cylindrical Bessel functions of the second kind - double cyl_neumann(double nu, double x); + @\placeholder{floating-point-type}@ cyl_neumann(@\placeholder{floating-point-type}@ nu, @\placeholder{floating-point-type}@ x); float cyl_neumannf(float nu, float x); long double cyl_neumannl(long double nu, long double x); // \ref{sf.cmath.ellint.1}, incomplete elliptic integral of the first kind - double ellint_1(double k, double phi); + @\placeholder{floating-point-type}@ ellint_1(@\placeholder{floating-point-type}@ k, @\placeholder{floating-point-type}@ phi); float ellint_1f(float k, float phi); long double ellint_1l(long double k, long double phi); // \ref{sf.cmath.ellint.2}, incomplete elliptic integral of the second kind - double ellint_2(double k, double phi); + @\placeholder{floating-point-type}@ ellint_2(@\placeholder{floating-point-type}@ k, @\placeholder{floating-point-type}@ phi); float ellint_2f(float k, float phi); long double ellint_2l(long double k, long double phi); // \ref{sf.cmath.ellint.3}, incomplete elliptic integral of the third kind - double ellint_3(double k, double nu, double phi); + @\placeholder{floating-point-type}@ ellint_3(@\placeholder{floating-point-type}@ k, @\placeholder{floating-point-type}@ nu, + @\placeholder{floating-point-type}@ phi); float ellint_3f(float k, float nu, float phi); long double ellint_3l(long double k, long double nu, long double phi); // \ref{sf.cmath.expint}, exponential integral - double expint(double x); + @\placeholder{floating-point-type}@ expint(@\placeholder{floating-point-type}@ x); float expintf(float x); long double expintl(long double x); // \ref{sf.cmath.hermite}, Hermite polynomials - double hermite(unsigned n, double x); + @\placeholder{floating-point-type}@ hermite(unsigned n, @\placeholder{floating-point-type}@ x); float hermitef(unsigned n, float x); long double hermitel(unsigned n, long double x); // \ref{sf.cmath.laguerre}, Laguerre polynomials - double laguerre(unsigned n, double x); + @\placeholder{floating-point-type}@ laguerre(unsigned n, @\placeholder{floating-point-type}@ x); float laguerref(unsigned n, float x); long double laguerrel(unsigned n, long double x); // \ref{sf.cmath.legendre}, Legendre polynomials - double legendre(unsigned l, double x); + @\placeholder{floating-point-type}@ legendre(unsigned l, @\placeholder{floating-point-type}@ x); float legendref(unsigned l, float x); long double legendrel(unsigned l, long double x); // \ref{sf.cmath.riemann.zeta}, Riemann zeta function - double riemann_zeta(double x); + @\placeholder{floating-point-type}@ riemann_zeta(@\placeholder{floating-point-type}@ x); float riemann_zetaf(float x); long double riemann_zetal(long double x); // \ref{sf.cmath.sph.bessel}, spherical Bessel functions of the first kind - double sph_bessel(unsigned n, double x); + @\placeholder{floating-point-type}@ sph_bessel(unsigned n, @\placeholder{floating-point-type}@ x); float sph_besself(unsigned n, float x); long double sph_bessell(unsigned n, long double x); // \ref{sf.cmath.sph.legendre}, spherical associated Legendre functions - double sph_legendre(unsigned l, unsigned m, double theta); + @\placeholder{floating-point-type}@ sph_legendre(unsigned l, unsigned m, @\placeholder{floating-point-type}@ theta); float sph_legendref(unsigned l, unsigned m, float theta); long double sph_legendrel(unsigned l, unsigned m, long double theta); // \ref{sf.cmath.sph.neumann}, spherical Neumann functions; // spherical Bessel functions of the second kind - double sph_neumann(unsigned n, double x); + @\placeholder{floating-point-type}@ sph_neumann(unsigned n, @\placeholder{floating-point-type}@ x); float sph_neumannf(unsigned n, float x); long double sph_neumannl(unsigned n, long double x); } @@ -9560,33 +9326,30 @@ \end{note} \pnum -For each set of overloaded functions within \libheader{cmath}, -with the exception of \tcode{abs}, -there shall be additional overloads sufficient to ensure: -\begin{itemize} - \item If any argument of arithmetic type - corresponding to a \tcode{double} parameter - has type \tcode{long double}, - then all arguments of arithmetic type\iref{basic.fundamental} - corresponding to \tcode{double} parameters - are effectively cast to \tcode{long double}. - \item Otherwise, if any argument of arithmetic type - corresponding to a \tcode{double} parameter - has type \tcode{double} - or an integer type, - then all arguments of arithmetic type - corresponding to \tcode{double} parameters - are effectively cast to \tcode{double}. - \item -\begin{note} -Otherwise, all arguments of arithmetic type -corresponding to \tcode{double} parameters -have type \tcode{float}. -\end{note} -\end{itemize} -\begin{note} -\tcode{abs} is exempted from these rules in order to stay compatible with C. -\end{note} +For each function +with at least one parameter of type \placeholder{floating-point-type}, +the implementation provides +an overload for each cv-unqualified floating-point type\iref{basic.fundamental} +where all uses of \placeholder{floating-point-type} in the function signature +are replaced with that floating-point type. + +\pnum +For each function +with at least one parameter of type \placeholder{floating-point-type} +other than \tcode{abs}, +the implementation also provides additional overloads sufficient to ensure that, +if every argument corresponding to +a \placeholder{floating-point-type} parameter has arithmetic type, +then every such argument is effectively cast to the floating-point type +with the greatest floating-point conversion rank and +greatest floating-point conversion subrank +among the types of all such arguments, +where arguments of integer type are considered to have +the same floating-point conversion rank as \tcode{double}. +If no such floating-point type with the greatest rank and subrank exists, +then overload resolution does not result in +a usable candidate\iref{over.match.general} +from the overloads provided by the implementation. \xrefc{7.12} @@ -9604,22 +9367,18 @@ constexpr int abs(int j); constexpr long int abs(long int j); constexpr long long int abs(long long int j); -constexpr float abs(float j); -constexpr double abs(double j); -constexpr long double abs(long double j); \end{itemdecl} \begin{itemdescr} \pnum \effects -The \tcode{abs} +These functions have the semantics specified in the C standard library -for the functions \tcode{abs}, \tcode{labs}, \tcode{llabs}, -\tcode{fabsf}, \tcode{fabs}, and \tcode{fabsl}. +for the functions \tcode{abs}, \tcode{labs}, and \tcode{llabs}, respectively. \pnum \remarks -If \tcode{abs()} is called with an argument of type \tcode{X} +If \tcode{abs} is called with an argument of type \tcode{X} for which \tcode{is_unsigned_v} is \tcode{true} and if \tcode{X} cannot be converted to \tcode{int} by integral promotion\iref{conv.prom}, the program is ill-formed. @@ -9628,15 +9387,23 @@ \end{note} \end{itemdescr} +\begin{itemdecl} +constexpr @\placeholder{floating-point-type}@ abs(@\placeholder{floating-point-type}@ x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +The absolute value of \tcode{x}. +\end{itemdescr} + \xrefc{7.12.7.2, 7.22.6.1} \rSec2[c.math.hypot3]{Three-dimensional hypotenuse} \indexlibrary{\idxcode{hypot}!3-argument form}% \begin{itemdecl} -float hypot(float x, float y, float z); -double hypot(double x, double y, double z); -long double hypot(long double x, long double y, long double z); +@\placeholder{floating-point-type}@ hypot(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y, double z); \end{itemdecl} \begin{itemdescr} @@ -9649,9 +9416,8 @@ \indexlibraryglobal{lerp}% \begin{itemdecl} -constexpr float lerp(float a, float b, float t) noexcept; -constexpr double lerp(double a, double b, double t) noexcept; -constexpr long double lerp(long double a, long double b, long double t) noexcept; +constexpr @\placeholder{floating-point-type}@ lerp(@\placeholder{floating-point-type}@ a, @\placeholder{floating-point-type}@ b, + @\placeholder{floating-point-type}@ t) noexcept; \end{itemdecl} \begin{itemdescr} \pnum @@ -9683,7 +9449,6 @@ \pnum The classification / comparison functions behave the same as the C macros with the corresponding names defined in the C standard library. -Each function is overloaded for the three floating-point types. \xrefc{7.12.3, 7.12.4} @@ -9748,7 +9513,7 @@ \indextext{Laguerre polynomials!$\mathsf{L}_n^m$}% \indextext{L nm@$\mathsf{L}_n^m$ (associated Laguerre polynomials)}% \begin{itemdecl} -double assoc_laguerre(unsigned n, unsigned m, double x); +@\placeholder{floating-point-type}@ assoc_laguerre(unsigned n, unsigned m, @\placeholder{floating-point-type}@ x); float assoc_laguerref(unsigned n, unsigned m, float x); long double assoc_laguerrel(unsigned n, unsigned m, long double x); \end{itemdecl} @@ -9785,7 +9550,7 @@ \indextext{Legendre polynomials!$\mathsf{P}_\ell^m$}% \indextext{P lm@$\mathsf{P}_\ell^m$ (associated Legendre polynomials)}% \begin{itemdecl} -double assoc_legendre(unsigned l, unsigned m, double x); +@\placeholder{floating-point-type}@ assoc_legendre(unsigned l, unsigned m, @\placeholder{floating-point-type}@ x); float assoc_legendref(unsigned l, unsigned m, float x); long double assoc_legendrel(unsigned l, unsigned m, long double x); \end{itemdecl} @@ -9823,7 +9588,7 @@ \indextext{Eulerian integral of the first kind|see{beta functions $\mathsf{B}$}}% \indextext{beta functions $\mathsf{B}$}% \begin{itemdecl} -double beta(double x, double y); +@\placeholder{floating-point-type}@ beta(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); float betaf(float x, float y); long double betal(long double x, long double y); \end{itemdecl} @@ -9852,7 +9617,7 @@ \indextext{elliptic integrals!complete $\mathsf{K}$}% \indextext{K complete@$\mathsf{K}$ (complete elliptic integrals)}% \begin{itemdecl} -double comp_ellint_1(double k); +@\placeholder{floating-point-type}@ comp_ellint_1(@\placeholder{floating-point-type}@ k); float comp_ellint_1f(float k); long double comp_ellint_1l(long double k); \end{itemdecl} @@ -9882,7 +9647,7 @@ \indextext{elliptic integrals!complete $\mathsf{E}$}% \indextext{E complete@$\mathsf{E}$ (complete elliptic integrals)}% \begin{itemdecl} -double comp_ellint_2(double k); +@\placeholder{floating-point-type}@ comp_ellint_2(@\placeholder{floating-point-type}@ k); float comp_ellint_2f(float k); long double comp_ellint_2l(long double k); \end{itemdecl} @@ -9912,7 +9677,7 @@ \indextext{elliptic integrals!complete $\mathsf{\Pi}$}% \indextext{Pi complete@$\mathsf{\Pi}$ (complete elliptic integrals)}% \begin{itemdecl} -double comp_ellint_3(double k, double nu); +@\placeholder{floating-point-type}@ comp_ellint_3(@\placeholder{floating-point-type}@ k, @\placeholder{floating-point-type}@ nu); float comp_ellint_3f(float k, float nu); long double comp_ellint_3l(long double k, long double nu); \end{itemdecl} @@ -9943,7 +9708,7 @@ \indextext{Bessel functions!$\mathsf{I}_\nu$}% \indextext{I nu@$\mathsf{I}_\nu$ (Bessell functions)}% \begin{itemdecl} -double cyl_bessel_i(double nu, double x); +@\placeholder{floating-point-type}@ cyl_bessel_i(@\placeholder{floating-point-type}@ nu, @\placeholder{floating-point-type}@ x); float cyl_bessel_if(float nu, float x); long double cyl_bessel_il(long double nu, long double x); \end{itemdecl} @@ -9983,7 +9748,7 @@ \indextext{Bessel functions!$\mathsf{J}_\nu$}% \indextext{J nu@$\mathsf{J}_\nu$ (Bessell functions)}% \begin{itemdecl} -double cyl_bessel_j(double nu, double x); +@\placeholder{floating-point-type}@ cyl_bessel_j(@\placeholder{floating-point-type}@ nu, @\placeholder{floating-point-type}@ x); float cyl_bessel_jf(float nu, float x); long double cyl_bessel_jl(long double nu, long double x); \end{itemdecl} @@ -10020,7 +9785,7 @@ \indextext{Bessel functions!$\mathsf{K}_\nu$}% \indextext{K nu@$\mathsf{K}_\nu$ (Bessell functions)}% \begin{itemdecl} -double cyl_bessel_k(double nu, double x); +@\placeholder{floating-point-type}@ cyl_bessel_k(@\placeholder{floating-point-type}@ nu, @\placeholder{floating-point-type}@ x); float cyl_bessel_kf(float nu, float x); long double cyl_bessel_kl(long double nu, long double x); \end{itemdecl} @@ -10081,7 +9846,7 @@ \indextext{Neumann functions!$\mathsf{N}_\nu$}% \indextext{N nu@$\mathsf{N}_\nu$ (Neumann functions)}% \begin{itemdecl} -double cyl_neumann(double nu, double x); +@\placeholder{floating-point-type}@ cyl_neumann(@\placeholder{floating-point-type}@ nu, @\placeholder{floating-point-type}@ x); float cyl_neumannf(float nu, float x); long double cyl_neumannl(long double nu, long double x); \end{itemdecl} @@ -10135,7 +9900,7 @@ \indextext{elliptic integrals!incomplete $\mathsf{F}$}% \indextext{F incomplete@$\mathsf{F}$ (incomplete elliptic integrals)}% \begin{itemdecl} -double ellint_1(double k, double phi); +@\placeholder{floating-point-type}@ ellint_1(@\placeholder{floating-point-type}@ k, @\placeholder{floating-point-type}@ phi); float ellint_1f(float k, float phi); long double ellint_1l(long double k, long double phi); \end{itemdecl} @@ -10165,7 +9930,7 @@ \indextext{elliptic integrals!incomplete $\mathsf{E}$}% \indextext{E incomplete@$\mathsf{E}$ (incomplete elliptic integrals)}% \begin{itemdecl} -double ellint_2(double k, double phi); +@\placeholder{floating-point-type}@ ellint_2(@\placeholder{floating-point-type}@ k, @\placeholder{floating-point-type}@ phi); float ellint_2f(float k, float phi); long double ellint_2l(long double k, long double phi); \end{itemdecl} @@ -10194,7 +9959,8 @@ \indextext{elliptic integrals!incomplete $\mathsf{\Pi}$}% \indextext{Pi incomplete@$\mathsf{\Pi}$ (incomplete elliptic integrals)}% \begin{itemdecl} -double ellint_3(double k, double nu, double phi); +@\placeholder{floating-point-type}@ ellint_3(@\placeholder{floating-point-type}@ k, @\placeholder{floating-point-type}@ nu, + @\placeholder{floating-point-type}@ phi); float ellint_3f(float k, float nu, float phi); long double ellint_3l(long double k, long double nu, long double phi); \end{itemdecl} @@ -10225,7 +9991,7 @@ \indextext{exponential integrals $\mathsf{Ei}$}% \indextext{Ei@$\mathsf{Ei}$ (exponential integrals)}% \begin{itemdecl} -double expint(double x); +@\placeholder{floating-point-type}@ expint(@\placeholder{floating-point-type}@ x); float expintf(float x); long double expintl(long double x); \end{itemdecl} @@ -10258,7 +10024,7 @@ \indextext{Hermite polynomials $\mathsf{H}_n$}% \indextext{H n@$\mathsf{H}_n$ (Hermite polynomials)}% \begin{itemdecl} -double hermite(unsigned n, double x); +@\placeholder{floating-point-type}@ hermite(unsigned n, @\placeholder{floating-point-type}@ x); float hermitef(unsigned n, float x); long double hermitel(unsigned n, long double x); \end{itemdecl} @@ -10296,7 +10062,7 @@ \indextext{Laguerre polynomials!$\mathsf{L}_n$}% \indextext{L n@$\mathsf{L}_n$ (Laguerre polynomials)}% \begin{itemdecl} -double laguerre(unsigned n, double x); +@\placeholder{floating-point-type}@ laguerre(unsigned n, @\placeholder{floating-point-type}@ x); float laguerref(unsigned n, float x); long double laguerrel(unsigned n, long double x); \end{itemdecl} @@ -10331,7 +10097,7 @@ \indextext{Legendre polynomials!$\mathsf{P}_\ell$}% \indextext{P l@$\mathsf{P}_\ell$ (Legendre polynomials)}% \begin{itemdecl} -double legendre(unsigned l, double x); +@\placeholder{floating-point-type}@ legendre(unsigned l, @\placeholder{floating-point-type}@ x); float legendref(unsigned l, float x); long double legendrel(unsigned l, long double x); \end{itemdecl} @@ -10366,7 +10132,7 @@ \indexlibraryglobal{riemann_zetal}% \indextext{zeta functions $\zeta$}% \begin{itemdecl} -double riemann_zeta(double x); +@\placeholder{floating-point-type}@ riemann_zeta(@\placeholder{floating-point-type}@ x); float riemann_zetaf(float x); long double riemann_zetal(long double x); \end{itemdecl} @@ -10415,7 +10181,7 @@ \indextext{Bessel functions!$\mathsf{j}_n$}% \indextext{j n@$\mathsf{j}_n$ (spherical Bessel functions)}% \begin{itemdecl} -double sph_bessel(unsigned n, double x); +@\placeholder{floating-point-type}@ sph_bessel(unsigned n, @\placeholder{floating-point-type}@ x); float sph_besself(unsigned n, float x); long double sph_bessell(unsigned n, long double x); \end{itemdecl} @@ -10453,7 +10219,7 @@ \indextext{Legendre functions $\mathsf{Y}_\ell^m$}% \indextext{Y lm@$\mathsf{Y}_\ell^m$ (spherical associated Legendre functions)}% \begin{itemdecl} -double sph_legendre(unsigned l, unsigned m, double theta); +@\placeholder{floating-point-type}@ sph_legendre(unsigned l, unsigned m, @\placeholder{floating-point-type}@ theta); float sph_legendref(unsigned l, unsigned m, float theta); long double sph_legendrel(unsigned l, unsigned m, long double theta); \end{itemdecl} @@ -10497,7 +10263,7 @@ \indextext{Neumann functions!$\mathsf{n}_n$}% \indextext{n n spherical@$\mathsf{n}_n$ (spherical Neumann functions)}% \begin{itemdecl} -double sph_neumann(unsigned n, double x); +@\placeholder{floating-point-type}@ sph_neumann(unsigned n, @\placeholder{floating-point-type}@ x); float sph_neumannf(unsigned n, float x); long double sph_neumannl(unsigned n, long double x); \end{itemdecl} diff --git a/source/overloading.tex b/source/overloading.tex index f970139fe5..0354d739e4 100644 --- a/source/overloading.tex +++ b/source/overloading.tex @@ -2706,6 +2706,34 @@ A conversion that promotes an enumeration whose underlying type is fixed to its underlying type is better than one that promotes to the promoted underlying type, if the two are different. +\item +A conversion in either direction +between floating-point type \tcode{FP1} and floating-point type \tcode{FP2} +is better than a conversion in the same direction +between \tcode{FP1} and arithmetic type \tcode{T3} if +\begin{itemize} +\item +the floating-point conversion rank\iref{conv.rank} of \tcode{FP1} +is equal to the rank of \tcode{FP2}, and +\item +\tcode{T3} is not a floating-point type, or +\tcode{T3} is a floating-point type +whose rank is not equal to the rank of \tcode{FP1}, or +the floating-point conversion subrank\iref{conv.rank} of \tcode{FP2} +is greater than the subrank of \tcode{T3}. +\begin{example} +\begin{codeblock} +int f(std::float32_t); +int f(std::float64_t); +int f(long long); +float x; +std::float16_t y; +int i = f(x); // calls \tcode{f(std::float32_t)} on implementations where + // \tcode{float} and \tcode{std::float32_t} have equal conversion ranks +int j = f(y); // error: ambiguous, no equal conversion rank +\end{codeblock} +\end{example} +\end{itemize} \item If class diff --git a/source/preprocessor.tex b/source/preprocessor.tex index 46aff75633..bbe740de9f 100644 --- a/source/preprocessor.tex +++ b/source/preprocessor.tex @@ -1728,6 +1728,45 @@ \tcode{operator new(std::size_t, std::align_val_t)}, etc.\iref{expr.new}. \end{note} +\item +\indextext{__stdcpp_float16_t__@\mname{STDCPP_FLOAT16_T}}% +\mname{STDCPP_FLOAT16_T}\\ +Defined as the integer literal \tcode{1} +if and only if the implementation supports +the ISO/IEC/IEEE 60559 floating-point interchange format binary16 +as an extended floating-point type\iref{basic.extended.fp}. + +\item +\indextext{__stdcpp_float32_t__@\mname{STDCPP_FLOAT32_T}}% +\mname{STDCPP_FLOAT32_T}\\ +Defined as the integer literal \tcode{1} +if and only if the implementation supports +the ISO/IEC/IEEE 60559 floating-point interchange format binary32 +as an extended floating-point type. + +\item +\indextext{__stdcpp_float64_t__@\mname{STDCPP_FLOAT64_T}}% +\mname{STDCPP_FLOAT64_T}\\ +Defined as the integer literal \tcode{1} +if and only if the implementation supports +the ISO/IEC/IEEE 60559 floating-point interchange format binary64 +as an extended floating-point type. + +\item +\indextext{__stdcpp_float16_t__@\mname{STDCPP_FLOAT128_T}}% +\mname{STDCPP_FLOAT128_T}\\ +Defined as the integer literal \tcode{1} +if and only if the implementation supports +the ISO/IEC/IEEE 60559 floating-point interchange format binary128 +as an extended floating-point type. + +\item +\indextext{__stdcpp_float16_t__@\mname{STDCPP_BFLOAT16_T}}% +\mname{STDCPP_BFLOAT16_T}\\ +Defined as the integer literal \tcode{1} +if and only if the implementation supports an extended floating-point type +with the properties described in \ref{basic.extended.fp}. + \item \indextext{__time__@\mname{TIME}}% \mname{TIME}\\ diff --git a/source/support.tex b/source/support.tex index 40ceef1aae..0669f6e555 100644 --- a/source/support.tex +++ b/source/support.tex @@ -27,6 +27,7 @@ \ref{support.limits} & Implementation properties & \tcode{}, \tcode{}, \tcode{}, \tcode{} \\ \rowsep \ref{cstdint} & Integer types & \tcode{} \\ \rowsep +\ref{stdfloat.syn} & Header \libheader{stdfloat} synopsis & \tcode{} \\ \rowsep \ref{support.start.term} & Start and termination & \tcode{} \\ \rowsep \ref{support.dynamic} & Dynamic memory management & \tcode{} \\ \rowsep \ref{support.rtti} & Type identification & \tcode{} \\ \rowsep @@ -222,9 +223,7 @@ constexpr int abs(int j); constexpr long int abs(long int j); constexpr long long int abs(long long int j); - constexpr float abs(float j); - constexpr double abs(double j); - constexpr long double abs(long double j); + constexpr @\placeholder{floating-point-type}@ abs(@\placeholder{floating-point-type}@ j); constexpr long int labs(long int j); constexpr long long int llabs(long long int j); @@ -1436,11 +1435,15 @@ \begin{itemdescr} \pnum -\tcode{true} if and only if the type adheres to ISO/IEC/IEEE -60559. +\tcode{true} if and only if the type adheres to ISO/IEC/IEEE 60559. \begin{footnote} -ISO/IEC/IEEE 60559:2011 is the same as IEEE 754-2008. +ISO/IEC/IEEE 60559:2020 is the same as IEEE 754-2019. \end{footnote} +\begin{note} +The value is \tcode{true} for the types +\tcode{float16_t}, \tcode{float32_t}, \tcode{float64_t}, or \tcode{float128_t}, +if present\iref{basic.extended.fp}. +\end{note} \pnum Meaningful for all floating-point types. @@ -1965,6 +1968,29 @@ respectively. \end{note} +\rSec1[stdfloat.syn]{Header \tcode{} synopsis} + +\indexheader{stdfloat}% +\begin{codeblock} +namespace std { + #if defined(__STDCPP_FLOAT16_T__) + using float16_t = @\UNSP{\impldef{type of \tcode{std::float16_t}}}@; // see \ref{basic.extended.fp} + #endif + #if defined(__STDCPP_FLOAT32_T__) + using float32_t = @\UNSP{\impldef{type of \tcode{std::float32_t}}}@; // see \ref{basic.extended.fp} + #endif + #if defined(__STDCPP_FLOAT64_T__) + using float64_t = @\UNSP{\impldef{type of \tcode{std::float64_t}}}@; // see \ref{basic.extended.fp} + #endif + #if defined(__STDCPP_FLOAT128_T__) + using float128_t = @\UNSP{\impldef{type of \tcode{std::float128_t}}}@; // see \ref{basic.extended.fp} + #endif + #if defined(__STDCPP_BFLOAT16_T__) + using bfloat16_t = @\UNSP{\impldef{type of \tcode{std::bfloat16_t}}}@; // see \ref{basic.extended.fp} + #endif +} +\end{codeblock} + \rSec1[support.start.term]{Startup and termination} \pnum diff --git a/source/threads.tex b/source/threads.tex index 58909c97cd..16de6eba03 100644 --- a/source/threads.tex +++ b/source/threads.tex @@ -3296,10 +3296,7 @@ \pnum \indexlibrary{\idxcode{atomic_ref<\placeholder{floating-point}>}}% There are specializations of the \tcode{atomic_ref} class template -for the floating-point types -\tcode{float}, -\tcode{double}, and -\tcode{long double}. +for all cv-unqualified floating-point types. For each such type \tcode{\placeholder{floating-point}}, the specialization \tcode{atomic_ref<\placeholder{floating-\-point}>} provides additional atomic operations appropriate to floating-point types. @@ -4348,10 +4345,7 @@ \indexlibrary{\idxcode{atomic<\placeholder{floating-point}>}}% \pnum There are specializations of the \tcode{atomic} -class template for the floating-point types -\tcode{float}, -\tcode{double}, and -\tcode{long double}. +class template for all cv-unqualified floating-point types. For each such type \tcode{\placeholdernc{floating-point}}, the specialization \tcode{atomic<\placeholder{floating-point}>} provides additional atomic operations appropriate to floating-point types. diff --git a/source/utilities.tex b/source/utilities.tex index 994bcc7c43..39ab1f815e 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -13019,6 +13019,18 @@ \rSec2[charconv.syn]{Header \tcode{} synopsis} +\pnum +When a function is specified +with a type placeholder of \tcode{\placeholder{integer-type}}, +the implementation provides overloads +for all cv-unqualified signed and unsigned integer types and \tcode{char} +in lieu of \tcode{\placeholder{integer-type}}. +When a function is specified +with a type placeholder of \tcode{\placeholder{floating-point-type}}, +the implementation provides overloads +for all cv-unqualified floating-point types\iref{basic.fundamental} +in lieu of \tcode{\placeholder{floating-point-type}}. + \indexheader{charconv}% \begin{codeblock} @% @@ -13047,22 +13059,12 @@ friend bool operator==(const to_chars_result&, const to_chars_result&) = default; }; - to_chars_result to_chars(char* first, char* last, @\seebelow@ value, int base = 10); + to_chars_result to_chars(char* first, char* last, @\placeholder{integer-type}@ value, int base = 10); to_chars_result to_chars(char* first, char* last, bool value, int base = 10) = delete; - to_chars_result to_chars(char* first, char* last, float value); - to_chars_result to_chars(char* first, char* last, double value); - to_chars_result to_chars(char* first, char* last, long double value); - - to_chars_result to_chars(char* first, char* last, float value, chars_format fmt); - to_chars_result to_chars(char* first, char* last, double value, chars_format fmt); - to_chars_result to_chars(char* first, char* last, long double value, chars_format fmt); - - to_chars_result to_chars(char* first, char* last, float value, - chars_format fmt, int precision); - to_chars_result to_chars(char* first, char* last, double value, - chars_format fmt, int precision); - to_chars_result to_chars(char* first, char* last, long double value, + to_chars_result to_chars(char* first, char* last, @\placeholder{floating-point-type}@ value); + to_chars_result to_chars(char* first, char* last, @\placeholder{floating-point-type}@ value, chars_format fmt); + to_chars_result to_chars(char* first, char* last, @\placeholder{floating-point-type}@ value, chars_format fmt, int precision); @% \indexlibraryglobal{from_chars_result}% @@ -13077,13 +13079,9 @@ }; from_chars_result from_chars(const char* first, const char* last, - @\seebelow@& value, int base = 10); + @\placeholder{integer-type}@& value, int base = 10); - from_chars_result from_chars(const char* first, const char* last, float& value, - chars_format fmt = chars_format::general); - from_chars_result from_chars(const char* first, const char* last, double& value, - chars_format fmt = chars_format::general); - from_chars_result from_chars(const char* first, const char* last, long double& value, + from_chars_result from_chars(const char* first, const char* last, @\placeholder{floating-point-type}@& value, chars_format fmt = chars_format::general); } \end{codeblock} @@ -13150,7 +13148,7 @@ \indexlibraryglobal{to_chars}% \begin{itemdecl} -to_chars_result to_chars(char* first, char* last, @\seebelow@ value, int base = 10); +to_chars_result to_chars(char* first, char* last, @\placeholder{integer-type}@ value, int base = 10); \end{itemdecl} \begin{itemdescr} @@ -13171,20 +13169,11 @@ \pnum \throws Nothing. - -\pnum -\remarks -The implementation shall provide overloads -for all signed and unsigned integer types -and \tcode{char} -as the type of the parameter \tcode{value}. \end{itemdescr} \indexlibraryglobal{to_chars}% \begin{itemdecl} -to_chars_result to_chars(char* first, char* last, float value); -to_chars_result to_chars(char* first, char* last, double value); -to_chars_result to_chars(char* first, char* last, long double value); +to_chars_result to_chars(char* first, char* last, @\placeholder{floating-point-type}@ value); \end{itemdecl} \begin{itemdescr} @@ -13205,9 +13194,7 @@ \indexlibraryglobal{to_chars}% \begin{itemdecl} -to_chars_result to_chars(char* first, char* last, float value, chars_format fmt); -to_chars_result to_chars(char* first, char* last, double value, chars_format fmt); -to_chars_result to_chars(char* first, char* last, long double value, chars_format fmt); +to_chars_result to_chars(char* first, char* last, @\placeholder{floating-point-type}@ value, chars_format fmt); \end{itemdecl} \begin{itemdescr} @@ -13229,11 +13216,7 @@ \indexlibraryglobal{to_chars}% \begin{itemdecl} -to_chars_result to_chars(char* first, char* last, float value, - chars_format fmt, int precision); -to_chars_result to_chars(char* first, char* last, double value, - chars_format fmt, int precision); -to_chars_result to_chars(char* first, char* last, long double value, +to_chars_result to_chars(char* first, char* last, @\placeholder{floating-point-type}@ value, chars_format fmt, int precision); \end{itemdecl} @@ -13297,7 +13280,7 @@ \indexlibraryglobal{from_chars}% \begin{itemdecl} from_chars_result from_chars(const char* first, const char* last, - @\seebelow@&@\itcorr[-1]@ value, int base = 10); + @\placeholder{integer-type}@&@\itcorr[-1]@ value, int base = 10); \end{itemdecl} \begin{itemdescr} @@ -13320,22 +13303,11 @@ \pnum \throws Nothing. - -\pnum -\remarks -The implementation shall provide overloads -for all signed and unsigned integer types -and \tcode{char} -as the referenced type of the parameter \tcode{value}. \end{itemdescr} \indexlibraryglobal{from_chars}% \begin{itemdecl} -from_chars_result from_chars(const char* first, const char* last, float& value, - chars_format fmt = chars_format::general); -from_chars_result from_chars(const char* first, const char* last, double& value, - chars_format fmt = chars_format::general); -from_chars_result from_chars(const char* first, const char* last, long double& value, +from_chars_result from_chars(const char* first, const char* last, @\placeholder{floating-point-type}@& value, chars_format fmt = chars_format::general); \end{itemdecl} diff --git a/source/xrefdelta.tex b/source/xrefdelta.tex index 719ca93f9c..9677de5fb1 100644 --- a/source/xrefdelta.tex +++ b/source/xrefdelta.tex @@ -96,5 +96,8 @@ \movedxref{defns.direct-non-list-init}{defns.direct.non.list.init} \movedxref{defns.expression-equivalent}{defns.expression.equivalent} +% P1467R9 Extended floating-point types and standard names +\movedxref{complex.special}{complex.members} + % Deprecated features. %\deprxref{old.label} (if moved to depr.old.label, otherwise use \movedxref) From 9aa76a2fed287fcfaa69e38875dd53b3ab692bf9 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sun, 7 Aug 2022 08:47:43 +0200 Subject: [PATCH 148/430] [numeric.limits.members] Fix English phrasing in footnote --- source/support.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/support.tex b/source/support.tex index 0669f6e555..f3a481d2bd 100644 --- a/source/support.tex +++ b/source/support.tex @@ -1440,7 +1440,7 @@ ISO/IEC/IEEE 60559:2020 is the same as IEEE 754-2019. \end{footnote} \begin{note} -The value is \tcode{true} for the types +The value is \tcode{true} for any of the types \tcode{float16_t}, \tcode{float32_t}, \tcode{float64_t}, or \tcode{float128_t}, if present\iref{basic.extended.fp}. \end{note} From b4d366d4075f8ce8d2007b436b3b0e29999da6a9 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Thu, 28 Jul 2022 00:22:29 -0700 Subject: [PATCH 149/430] P2582R1 Wording for class template argument deduction from inherited constructors --- source/overloading.tex | 75 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/source/overloading.tex b/source/overloading.tex index 0354d739e4..5066e5c430 100644 --- a/source/overloading.tex +++ b/source/overloading.tex @@ -1274,6 +1274,69 @@ the trailing sequence of parameters corresponding to a trailing aggregate element that is a pack expansion (if any) is replaced by a single parameter of the form $\tcode{T}_n \tcode{...}$. +In addition, +if \tcode{C} is defined and +inherits constructors\iref{namespace.udecl} +from a direct base class denoted in the \grammarterm{base-specifier-list} +by a \grammarterm{class-or-decltype} \tcode{B}, +let \tcode{A} be an alias template +whose template parameter list is that of \tcode{C} and +whose \grammarterm{defining-type-id} is \tcode{B}. +%% FIXME: the following sentence is very hard to follow; rewrite! +If \tcode{A} is a deducible template\iref{dcl.type.simple}, +the set contains the guides of \tcode{A} +with the return type \tcode{R} of each guide +replaced with \tcode{typename CC::type} given a class template +\begin{codeblock} +template class CC; +\end{codeblock} +whose primary template is not defined and +with a single partial specialization +whose template parameter list is that of \tcode{A} and +whose template argument list is a specialization of \tcode{A} with +the template argument list of \tcode{A}\iref{temp.dep.type} +having a member typedef \tcode{type} designating a template specialization with +the template argument list of \tcode{A} but +with \tcode{C} as the template. +\begin{note} +Equivalently, +the template parameter list of the specialization is that of \tcode{C}, +the template argument list of the specialization is \tcode{B}, and +the member typedef names \tcode{C} with the template argument list of \tcode{C}. +\end{note} + +\pnum +\begin{example} +\begin{codeblock} +template struct B { + B(T); +}; +template struct C : public B { + using B::B; +}; +template struct D : public B {}; + +C c(42); // OK, deduces \tcode{C} +D d(42); // error: deduction failed, no inherited deduction guides +B(int) -> B; +C c2(42); // OK, deduces \tcode{C} + +template struct E : public B { + using B::B; +}; + +E e(42); // error: deduction failed, arguments of \tcode{E} cannot be deduced from introduced guides + +template struct F { + F(T, U, V); +}; +template struct G : F { + using G::F::F; +} + +G g(true, 'a', 1); // OK, deduces \tcode{G} +\end{codeblock} +\end{example} \pnum When resolving a placeholder for a deduced class type\iref{dcl.type.simple} @@ -1741,6 +1804,18 @@ \end{example} or, if not that +\item +\tcode{F1} and \tcode{F2} are generated +from class template argument deduction\iref{over.match.class.deduct} +for a class \tcode{D}, and +\tcode{F2} is generated +from inheriting constructors from a base class of \tcode{D} +while \tcode{F1} is not, and +for each explicit function argument, +the corresponding parameters of \tcode{F1} and \tcode{F2} +are either both ellipses or have the same type, +or, if not that, + \item \tcode{F1} is generated from a \grammarterm{deduction-guide}\iref{over.match.class.deduct} From 4e93a29f7ed1a0055b4cc745328a4109df31b451 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 28 Jul 2022 21:27:16 +0200 Subject: [PATCH 150/430] P1774R8 Portable assumptions --- source/declarations.tex | 37 +++++++++++++++++++++++++++++++++++++ source/expressions.tex | 31 ++++++++++++++++++++++++------- 2 files changed, 61 insertions(+), 7 deletions(-) diff --git a/source/declarations.tex b/source/declarations.tex index 0b2e7d86b1..a903060bfd 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -8529,6 +8529,43 @@ \end{codeblock} \end{example} +\rSec2[dcl.attr.assume]{Assumption attribute} + +The \grammarterm{attribute-token} \tcode{assume} may be applied to a null statement; +such a statement is an \defn{assumption}. +An \grammarterm{attribute-argument-clause} shall be present and +shall have the form: +\begin{ncsimplebnf} +\terminal{(} conditional-expression \terminal{)} +\end{ncsimplebnf} +The expression is contextually converted to \tcode{bool}\iref{conv.general}. +The expression is not evaluated. +If the converted expression would evaluate to \tcode{true} +at the point where the assumption appears, +the assumption has no effect. +Otherwise, the behavior is undefined. +\begin{note} +The expression is potentially evaluated\iref{basic.def.odr}. +The use of assumptions is intended to allow implementations +to analyze the form of the expression and +deduce information used to optimize the program. +Implementations are not required to deduce +any information from any particular assumption. +\end{note} +\begin{example} +\begin{codeblock} +int divide_by_32(int x) { + [[assume(x >= 0)]]; + return x/32; // The instructions produced for the division + // may omit handling of negative values. +} +int f(int y) { + [[assume(++y == 43)]]; // \tcode{y} is not incremented + return y; // statement may be replaced with \tcode{return 42;} +} +\end{codeblock} +\end{example} + \rSec2[dcl.attr.depend]{Carries dependency attribute}% \indextext{attribute!carries dependency} diff --git a/source/expressions.tex b/source/expressions.tex index 71906feade..49fdf39fe2 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -7359,7 +7359,8 @@ \item an operation that would have undefined behavior -as specified in \ref{intro} through \ref{cpp}; +as specified in \ref{intro} through \ref{cpp}, +excluding \ref{dcl.attr.assume}; \begin{footnote} This includes, for example, signed integer overflow\iref{expr.pre}, certain @@ -7506,12 +7507,28 @@ a \keyword{goto} statement\iref{stmt.goto}. \end{itemize} -If $E$ satisfies the constraints of a core constant expression, but -evaluation of $E$ would evaluate an operation that has undefined behavior -as specified in \ref{library} through \ref{\lastlibchapter}, or -an invocation of the \tcode{va_start} macro\iref{cstdarg.syn}, -it is unspecified whether $E$ is a core constant expression. - +It is unspecified whether $E$ is a core constant expression +if $E$ satisfies the constraints of a core constant expression, but +evaluation of $E$ would evaluate +\begin{itemize} +\item +an operation that has undefined behavior +as specified in \ref{library} through \ref{\lastlibchapter}, +\item +an invocation of the \tcode{va_start} macro\iref{cstdarg.syn}, or +\item +a statement with an assumption\iref{dcl.attr.assume} +whose converted \grammarterm{conditional-expression}, +if evaluated where the assumption appears, +would not disqualify $E$ from being a core constant expression and +would not evaluate to \tcode{true}. +\begin{note} +$E$ is not disqualified from being a core constant expression +if the hypothetical evaluation of +the converted \grammarterm{conditional-expression} +would disqualify $E$ from being a core constant expression. +\end{note} +\end{itemize} \begin{example} \begin{codeblock} int x; // not constant From 44c17ecec1b713cd4fb614fa508c780120f2fa8b Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 28 Jul 2022 22:22:44 +0200 Subject: [PATCH 151/430] P2295R6 Support for UTF-8 as a portable source file encoding --- source/compatibility.tex | 4 ++-- source/lex.tex | 27 +++++++++++++++++++++++---- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/source/compatibility.tex b/source/compatibility.tex index 35d9feb29f..73db751357 100644 --- a/source/compatibility.tex +++ b/source/compatibility.tex @@ -893,8 +893,8 @@ Valid \CppXIV{} code that uses trigraphs may not be valid or may have different semantics in this revision of \Cpp{}. Implementations may choose to translate trigraphs as specified in \CppXIV{} if they appear outside of a raw -string literal, as part of the \impldef{mapping physical source file characters -to translation character set} mapping from physical source file characters to +string literal, as part of the \impldef{mapping input source file characters +to translation character set} mapping from input source file characters to the translation character set. \diffref{lex.ppnumber} diff --git a/source/lex.tex b/source/lex.tex index 9c8c403056..3763160cc1 100644 --- a/source/lex.tex +++ b/source/lex.tex @@ -67,14 +67,33 @@ \item \indextext{character!source file}% \indextext{character set!basic source}% -Physical source file characters are mapped, in an +An implementation shall support input files +that are a sequence of UTF-8 code units (UTF-8 files). +It may also support +an \impldef{supported input files} set of other kinds of input files, and, +if so, the kind of an input file is determined in +an \impldef{determination of kind of input file} manner +that includes a means of designating input files as UTF-8 files, +independent of their content. +\begin{note} +In other words, +recognizing the \unicode{feff}{byte order mark} is not sufficient. +\end{note} +If an input file is determined to be a UTF-8 file, +then it shall be a well-formed UTF-8 code unit sequence and +it is decoded to produce a sequence of UCS scalar values +that constitutes the sequence of elements of the translation character set. + +For any other kind of input file supported by the implementation, +characters are mapped, in an \impldef{mapping physical source file characters to translation character set} manner, -to the translation character set\iref{lex.charset} +to a sequence of translation character set elements\iref{lex.charset} (introducing new-line characters for end-of-line indicators). -The set of physical source file characters accepted is \impldef{physical source file -characters}. + \item \indextext{line splicing}% +If the first translation character is \unicode{feff}{byte order mark}, +it is deleted. Each sequence of a backslash character (\textbackslash) immediately followed by zero or more whitespace characters other than new-line followed by From d7e138ea5915818e5a6da2c00e88d3636d5a5dbe Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Thu, 28 Jul 2022 14:00:20 -0700 Subject: [PATCH 152/430] P2513R3 char8_t Compatibility and Portability Fix --- source/compatibility.tex | 31 +++++++++++++++++++++++++++++++ source/declarations.tex | 11 +++++++++-- source/preprocessor.tex | 2 +- 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/source/compatibility.tex b/source/compatibility.tex index 73db751357..ab1ca5cd5d 100644 --- a/source/compatibility.tex +++ b/source/compatibility.tex @@ -40,6 +40,37 @@ \end{codeblock} \end{example} +\rSec2[diff.cpp20.dcl]{\ref{dcl.dcl}: declarations} + +\diffref{dcl.init.string} +\change +UTF-8 string literals may initialize arrays of \keyword{char} or +\tcode{\keyword{unsigned} \keyword{char}}. +\rationale +Compatibility with previously written code that conformed to previous versions of this document. +\effect +Arrays of \keyword{char} or \tcode{\keyword{unsigned} \keyword{char}} +may now be initialized with a UTF-8 string literal. +This can affect initialization that includes arrays +that are directly initialized within class types, typically aggregates. + +Example: +\begin{codeblock} +struct A { + char8_t s[10]; +}; +struct B { + char s[10]; +}; + +void f(A); +void f(B); + +int main() { + f({u8""}); // ambiguous +} +\end{codeblock} + \rSec2[diff.cpp20.expr]{\ref{expr}: expressions} \diffref{expr.prim.id.unqual} diff --git a/source/declarations.tex b/source/declarations.tex index a903060bfd..8bb280b91c 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -5286,7 +5286,7 @@ \keyword{char16_t} array, \keyword{char32_t} array, or \keyword{wchar_t} array -can be initialized by +may be initialized by an ordinary string literal, UTF-8 string literal, UTF-16 string literal, @@ -5294,11 +5294,18 @@ wide string literal, respectively, or by an appropriately-typed \grammarterm{string-literal} enclosed in braces\iref{lex.string}. +Additionally, an array of \keyword{char} or +\tcode{\keyword{unsigned} \keyword{char}} +may be initialized by +a UTF-8 string literal, or by +such a string literal enclosed in braces. \indextext{initialization!character array}% Successive characters of the value of the \grammarterm{string-literal} -initialize the elements of the array. +initialize the elements of the array, +with an integral conversion\iref{conv.integral} +if necessary for the source and destination value. \begin{example} \begin{codeblock} char msg[] = "Syntax error on line %s\n"; diff --git a/source/preprocessor.tex b/source/preprocessor.tex index bbe740de9f..378ea30c81 100644 --- a/source/preprocessor.tex +++ b/source/preprocessor.tex @@ -1796,7 +1796,7 @@ \defnxname{cpp_attributes} & \tcode{200809L} \\ \rowsep \defnxname{cpp_binary_literals} & \tcode{201304L} \\ \rowsep \defnxname{cpp_capture_star_this} & \tcode{201603L} \\ \rowsep -\defnxname{cpp_char8_t} & \tcode{201811L} \\ \rowsep +\defnxname{cpp_char8_t} & \tcode{202207L} \\ \rowsep \defnxname{cpp_concepts} & \tcode{202002L} \\ \rowsep \defnxname{cpp_conditional_explicit} & \tcode{201806L} \\ \rowsep \defnxname{cpp_constexpr} & \tcode{202207L} \\ \rowsep From 93c7b47bd372b10c22ac101c3cbcc4daa793a725 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 28 Jul 2022 22:28:32 +0200 Subject: [PATCH 153/430] P2460R2 Relax requirements on wchar_t to match existing practices --- source/basic.tex | 3 --- source/lib-intro.tex | 2 ++ 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/source/basic.tex b/source/basic.tex index b02fcbf3da..9f3222757f 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -4923,9 +4923,6 @@ Type \keyword{wchar_t} is a distinct type that has an \impldef{underlying type of \tcode{wchar_t}} signed or unsigned integer type as its underlying type. -The values of type \keyword{wchar_t} can represent -distinct codes for all members of the largest extended character set -specified among the supported locales\iref{locale}. \pnum \indextext{\idxcode{char8_t}|see{type, \tcode{char8_t}}}% diff --git a/source/lib-intro.tex b/source/lib-intro.tex index 3ddadeaf3d..555f81b7d5 100644 --- a/source/lib-intro.tex +++ b/source/lib-intro.tex @@ -698,6 +698,8 @@ are supersets of the basic literal character set\iref{lex.charset}. The encodings of the execution character sets and the sets of additional elements (if any) are locale-specific. +Each element of the execution wide-character set is encoded as +a single code unit representable by a value of type \keyword{wchar_t}. \begin{note} The encodings of the execution character sets can be unrelated to any literal encoding. From 6e754f37fd6cfb32202d89a95776e82b5a33b2b0 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 28 Jul 2022 22:44:00 +0200 Subject: [PATCH 154/430] P2579R0 Mitigation strategies for P2036 "Changing scope for lambda trailing-return-type" --- source/basic.tex | 6 ++++++ source/expressions.tex | 38 +++++++++++++++++++++----------------- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/source/basic.tex b/source/basic.tex index 9f3222757f..ad85305be3 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -1286,6 +1286,12 @@ its scope extends to the end of the \grammarterm{deduction-guide}. \end{itemize} +\rSec2[basic.scope.lambda]{Lambda scope} + +A \grammarterm{lambda-expression} \tcode{E} introduces a \defnadj{lambda}{scope} +that starts immediately after the \grammarterm{lambda-introducer} of \tcode{E} +and extends to the end of the \grammarterm{compound-statement} of \tcode{E}. + \rSec2[basic.scope.namespace]{Namespace scope} \pnum diff --git a/source/expressions.tex b/source/expressions.tex index 49fdf39fe2..bbae186efd 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -1473,10 +1473,11 @@ If naming the entity from outside of an unevaluated operand within $S$ would refer to an entity captured by copy in some intervening \grammarterm{lambda-expression}, -then let $E$ be the innermost such \grammarterm{lambda-expression}, and: +then let $E$ be the innermost such \grammarterm{lambda-expression}. \begin{itemize} \item -If $P$ is in $E$'s function parameter scope +If there is such a \grammarterm{lambda-expression} and +if $P$ is in $E$'s function parameter scope but not its \grammarterm{parameter-declaration-clause}, then the type of the expression is the type of a class member access expression\iref{expr.ref} @@ -1488,11 +1489,11 @@ the type of such an identifier will typically be \keyword{const} qualified. \end{note} \item -Otherwise (if $P$ either precedes $E$'s function parameter scope or +Otherwise (if there is no such \grammarterm{lambda-expression} or +if $P$ either precedes $E$'s function parameter scope or is in $E$'s \grammarterm{parameter-declaration-clause}), -the program is ill-formed. +the type of the expression is the type of the result. \end{itemize} -Otherwise, the type of the expression is the type of the result. \begin{note} If the entity is a template parameter object for a template parameter of type \tcode{T}\iref{temp.param}, @@ -1521,15 +1522,14 @@ return y2; }; - [=]{}; // error: \tcode{x} refers to local entity but precedes the - // lambda's function parameter scope - [=](decltype((x)) y){}; // error: \tcode{x} refers to local entity but is in the lambda's - // \grammarterm{parameter-declaration-clause} + [=](decltype((x)) y){ + decltype((x)) z = x; // OK, \tcode{y} has type \tcode{float\&}, \tcode{z} has type \tcode{float const\&} + }; [=]{ - []{}; // OK, \tcode{x} is in the outer lambda's function parameter scope [](decltype((x)) y){}; // OK, lambda takes a parameter of type \tcode{float const\&} - [x=1](decltype((x)) z){}; // error: \tcode{x} refers to \grammarterm{init-capture} but is in the lambda's - // \grammarterm{parameter-declaration-clause} + [x=1](decltype((x)) z){ + decltype((x)) z = x; // OK, \tcode{y} has type \tcode{int\&}, \tcode{z} has type \tcode{int const\&} + }; }; } \end{codeblock} @@ -2310,22 +2310,26 @@ is said to be \defn{explicitly captured}. \pnum -If an \grammarterm{identifier} in a \grammarterm{simple-capture} appears +If an \grammarterm{identifier} in a \grammarterm{capture} appears as the \grammarterm{declarator-id} of a parameter of -the \grammarterm{lambda-declarator}{'s} \grammarterm{parameter-declaration-clause}, +the \grammarterm{lambda-declarator}'s \grammarterm{parameter-declaration-clause} +or as the name of a template parameter of +the \grammarterm{lambda-expression}'s \grammarterm{template-parameter-list}, the program is ill-formed. \begin{example} \begin{codeblock} void f() { int x = 0; - auto g = [x](int x) { return 0; }; // error: parameter and \grammarterm{simple-capture} have the same name + auto g = [x](int x) { return 0; }; // error: parameter and \grammarterm{capture} have the same name + auto h = [y = 0](y) { return 0; }; // error: template parameter and \grammarterm{capture} + // have the same name } \end{codeblock} \end{example} \pnum -An \grammarterm{init-capture} inhabits the function parameter scope of -the \grammarterm{lambda-expression}'s \grammarterm{parameter-declaration-clause}. +An \grammarterm{init-capture} inhabits +the lambda scope of the \grammarterm{lambda-expression}. An \grammarterm{init-capture} without ellipsis behaves as if it declares and explicitly captures a variable of the form ``\keyword{auto} \grammarterm{init-capture} \tcode{;}'', except that: From 047248791efb3d01349c34dada1481218029d47c Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Jul 2022 17:32:11 -0700 Subject: [PATCH 155/430] LWG3564 transform_view::iterator::value_type and iterator_category should use const F& --- source/ranges.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index c1b1795099..108e945d0f 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -4430,7 +4430,7 @@ using iterator_concept = @\seebelownc@; using iterator_category = @\seebelownc@; // not always present using value_type = - remove_cvref_t>>; + remove_cvref_t&, range_reference_t<@\exposid{Base}@>>>; using difference_type = range_difference_t<@\exposid{Base}@>; @\exposid{iterator}@() requires @\libconcept{default_initializable}@> = default; @@ -4514,7 +4514,7 @@ \tcode{iterator_traits>::iterator_category}. \begin{itemize} \item -If \tcode{is_lvalue_reference_v>>} +If \tcode{is_lvalue_reference_v\&, range_reference_t<\linebreak\exposid{Base}>>>} is \tcode{true}, then \begin{itemize} \item From c5b6a5c3827f1726982ef92a9c2e33de4a00fc11 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Jul 2022 17:50:07 -0700 Subject: [PATCH 156/430] LWG3617 function/packaged_task deduction guides and deducing this --- source/threads.tex | 6 ++++-- source/utilities.tex | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/source/threads.tex b/source/threads.tex index 16de6eba03..ce82da2d9b 100644 --- a/source/threads.tex +++ b/source/threads.tex @@ -11316,9 +11316,11 @@ \begin{itemize} \item \tcode{F::operator()} is a non-static member function and -\tcode{decltype(\brk{}\&F::operator())} is of the form +\tcode{decltype(\brk{}\&F::operator())} is either of the form \tcode{R(G::*)(A...)}~\cv{}~\tcode{\opt{\&}~\opt{noexcept}} -for a class type \tcode{G}, or +or of the form +\tcode{R(*)(G, A...)~\opt{noexcept}} +for a type \tcode{G}, or \item \tcode{F::operator()} is a static member function and \tcode{decltype(\&F::operator())} is of the form diff --git a/source/utilities.tex b/source/utilities.tex index 39ab1f815e..0c1675b040 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -11679,9 +11679,11 @@ \begin{itemize} \item \tcode{F::operator()} is a non-static member function and -\tcode{decltype(\brk{}\&F::operator())} is of the form +\tcode{decltype(\brk{}\&F::operator())} is either of the form \tcode{R(G::*)(A...)}~\cv{}~\tcode{\opt{\&}~\opt{noexcept}} -for a class type \tcode{G}, or +or of the form +\tcode{R(*)(G, A...)~\opt{noexcept}} +for a type \tcode{G}, or \item \tcode{F::operator()} is a static member function and \tcode{decltype(\&F::operator())} is of the form From 53c83cfe56bae547c4fce7c1a5a0e324818e7d37 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Jul 2022 17:52:16 -0700 Subject: [PATCH 157/430] LWG3656 Inconsistent bit operations returning a count --- source/utilities.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/utilities.tex b/source/utilities.tex index 0c1675b040..32e2090138 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -15518,7 +15518,7 @@ template constexpr T bit_floor(T x) noexcept; template - constexpr T bit_width(T x) noexcept; + constexpr int bit_width(T x) noexcept; // \ref{bit.rotate}, rotating template @@ -15702,7 +15702,7 @@ \indexlibraryglobal{bit_width}% \begin{itemdecl} template - constexpr T bit_width(T x) noexcept; + constexpr int bit_width(T x) noexcept; \end{itemdecl} \begin{itemdescr} From c61c1b6284041c528a619fedb9097c0ff0a53301 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Jul 2022 18:02:02 -0700 Subject: [PATCH 158/430] LWG3659 Consider ATOMIC_FLAG_INIT undeprecation --- source/future.tex | 24 ------------------------ source/threads.tex | 22 ++++++++++++++++++++++ source/xrefdelta.tex | 3 +++ 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/source/future.tex b/source/future.tex index 609e7cfceb..2f13822f8f 100644 --- a/source/future.tex +++ b/source/future.tex @@ -2639,8 +2639,6 @@ void atomic_init(atomic*, typename atomic::value_type) noexcept; #define ATOMIC_VAR_INIT(value) @\seebelow@ - - #define ATOMIC_FLAG_INIT @\seebelow@ } \end{codeblock} @@ -2709,25 +2707,3 @@ \end{codeblock} \end{example} \end{itemdescr} - -\rSec2[depr.atomics.flag]{Flag type and operations} - -\indexlibraryglobal{ATOMIC_FLAG_INIT}% -\begin{itemdecl} -#define ATOMIC_FLAG_INIT @\seebelow@ -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks -The macro \tcode{ATOMIC_FLAG_INIT} is defined in such a way that -it can be used to initialize an object of type \tcode{atomic_flag} -to the clear state. -The macro can be used in the form: -\begin{codeblock} -atomic_flag guard = ATOMIC_FLAG_INIT; -\end{codeblock} -It is unspecified whether the macro can be used -in other initialization contexts. -For a complete static-duration object, that initialization shall be static. -\end{itemdescr} diff --git a/source/threads.tex b/source/threads.tex index ce82da2d9b..e9988ec37f 100644 --- a/source/threads.tex +++ b/source/threads.tex @@ -2298,6 +2298,7 @@ void atomic_flag_notify_one(atomic_flag*) noexcept; void atomic_flag_notify_all(volatile atomic_flag*) noexcept; void atomic_flag_notify_all(atomic_flag*) noexcept; + #define ATOMIC_FLAG_INIT @\seebelow@ // \ref{atomics.fences}, fences extern "C" void atomic_thread_fence(memory_order) noexcept; @@ -5651,6 +5652,26 @@ This function is an atomic notifying operation\iref{atomics.wait}. \end{itemdescr} +\indexlibraryglobal{ATOMIC_FLAG_INIT}% +\begin{itemdecl} +#define ATOMIC_FLAG_INIT @\seebelow@ +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks +The macro \tcode{ATOMIC_FLAG_INIT} is defined in such a way that +it can be used to initialize an object of type \tcode{atomic_flag} +to the clear state. +The macro can be used in the form: +\begin{codeblock} +atomic_flag guard = ATOMIC_FLAG_INIT; +\end{codeblock} +It is unspecified whether the macro can be used +in other initialization contexts. +For a complete static-duration object, that initialization shall be static. +\end{itemdescr} + \rSec2[atomics.fences]{Fences} \pnum @@ -5827,6 +5848,7 @@ using std::@\libglobal{atomic_flag_test_and_set_explicit}@; // \seebelow using std::@\libglobal{atomic_flag_clear}@; // \seebelow using std::@\libglobal{atomic_flag_clear_explicit}@; // \seebelow +#define ATOMIC_FLAG_INIT @\seebelow@ using std::@\libglobal{atomic_thread_fence}@; // \seebelow using std::@\libglobal{atomic_signal_fence}@; // \seebelow diff --git a/source/xrefdelta.tex b/source/xrefdelta.tex index 9677de5fb1..8c6dd51293 100644 --- a/source/xrefdelta.tex +++ b/source/xrefdelta.tex @@ -99,5 +99,8 @@ % P1467R9 Extended floating-point types and standard names \movedxref{complex.special}{complex.members} +% LWG3659 Consider ATOMIC_FLAG_INIT undeprecation +\removedxref{depr.atomics.flag} + % Deprecated features. %\deprxref{old.label} (if moved to depr.old.label, otherwise use \movedxref) From 6fbded2b5079afbff6af3a6e2f828541bb4477e8 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Jul 2022 18:11:01 -0700 Subject: [PATCH 159/430] LWG3670 Cpp17InputIterators don't have integer-class difference types --- source/ranges.tex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index 108e945d0f..a8352fdb65 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -2767,7 +2767,8 @@ W @\exposid{value_}@ = W(); // \expos public: using iterator_concept = @\seebelow@; - using iterator_category = input_iterator_tag; // present only if \tcode{W} models \libconcept{incrementable} + using iterator_category = input_iterator_tag; // present only if \tcode{W} models \libconcept{incrementable} and + // \tcode{\placeholdernc{IOTA-DIFF-T}(W)} is an integral type using value_type = W; using difference_type = @\placeholdernc{IOTA-DIFF-T}@(W); From 50f1e241b042549394950195f8494917d0692478 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Jul 2022 18:21:00 -0700 Subject: [PATCH 160/430] LWG3671 atomic_fetch_xor missing from stdatomic.h --- source/threads.tex | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/threads.tex b/source/threads.tex index e9988ec37f..020915bf95 100644 --- a/source/threads.tex +++ b/source/threads.tex @@ -5840,10 +5840,12 @@ using std::@\libglobal{atomic_fetch_add_explicit}@; // \seebelow using std::@\libglobal{atomic_fetch_sub}@; // \seebelow using std::@\libglobal{atomic_fetch_sub_explicit}@; // \seebelow -using std::@\libglobal{atomic_fetch_or}@; // \seebelow -using std::@\libglobal{atomic_fetch_or_explicit}@; // \seebelow using std::@\libglobal{atomic_fetch_and}@; // \seebelow using std::@\libglobal{atomic_fetch_and_explicit}@; // \seebelow +using std::@\libglobal{atomic_fetch_or}@; // \seebelow +using std::@\libglobal{atomic_fetch_or_explicit}@; // \seebelow +using std::@\libglobal{atomic_fetch_xor}@; // \seebelow +using std::@\libglobal{atomic_fetch_xor_explicit}@; // \seebelow using std::@\libglobal{atomic_flag_test_and_set}@; // \seebelow using std::@\libglobal{atomic_flag_test_and_set_explicit}@; // \seebelow using std::@\libglobal{atomic_flag_clear}@; // \seebelow From 0df9a20af999f12479d9bf65fbd714407bdfe1fe Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Jul 2022 18:24:25 -0700 Subject: [PATCH 161/430] LWG3672 common_iterator::operator->() should return by value --- source/iterators.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/iterators.tex b/source/iterators.tex index 0b49fb07bc..9c9606b0ae 100644 --- a/source/iterators.tex +++ b/source/iterators.tex @@ -4796,7 +4796,7 @@ constexpr decltype(auto) operator*(); constexpr decltype(auto) operator*() const requires @\exposconcept{dereferenceable}@; - constexpr decltype(auto) operator->() const + constexpr auto operator->() const requires @\seebelow@; constexpr common_iterator& operator++(); @@ -4964,7 +4964,7 @@ \indexlibrarymember{operator->}{common_iterator}% \begin{itemdecl} -constexpr decltype(auto) operator->() const +constexpr auto operator->() const requires @\seebelow@; \end{itemdecl} From da4456dde74b4f5dfd5899cec4f74e1a0f0e90dd Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Jul 2022 18:27:26 -0700 Subject: [PATCH 162/430] LWG3683 operator== for polymorphic_allocator cannot deduce template argument in common cases --- source/memory.tex | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/memory.tex b/source/memory.tex index 349c18b115..8491e64339 100644 --- a/source/memory.tex +++ b/source/memory.tex @@ -5442,6 +5442,12 @@ polymorphic_allocator select_on_container_copy_construction() const; memory_resource* resource() const; + + // friends + friend bool operator==(const polymorphic_allocator& a, + const polymorphic_allocator& b) noexcept { + return *a.resource() == *b.resource(); + } }; } \end{codeblock} From 29f66da4515576f0bf2cc3c3868e6afbb3e25d5f Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Jul 2022 18:29:17 -0700 Subject: [PATCH 163/430] LWG3687 expected move constructor should move --- source/utilities.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/utilities.tex b/source/utilities.tex index 32e2090138..e18b6b2e80 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -8268,7 +8268,7 @@ Otherwise, if \tcode{rhs.has_value()} is \tcode{true}, destroys \exposid{unex} and sets \exposid{has_val} to \tcode{true}. \item -Otherwise, equivalent to \tcode{\exposid{unex} = rhs.error()}. +Otherwise, equivalent to \tcode{\exposid{unex} = std::move(rhs.error())}. \end{itemize} \pnum From 76a86b85bf91c1afcd8b04e5a69e5257c2ceea44 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Jul 2022 18:38:22 -0700 Subject: [PATCH 164/430] LWG3692 zip_view::iterator's operator<=> is overconstrained --- source/ranges.tex | 58 ++--------------------------------------------- 1 file changed, 2 insertions(+), 56 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index a8352fdb65..3e6b849d09 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -8742,17 +8742,8 @@ friend constexpr bool operator==(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) requires (@\libconcept{equality_comparable}@>> && ...); - friend constexpr bool operator<(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) - requires @\exposconcept{all-random-access}@; - friend constexpr bool operator>(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) - requires @\exposconcept{all-random-access}@; - friend constexpr bool operator<=(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) - requires @\exposconcept{all-random-access}@; - friend constexpr bool operator>=(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) - requires @\exposconcept{all-random-access}@; friend constexpr auto operator<=>(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) - requires @\exposconcept{all-random-access}@ && - (@\libconcept{three_way_comparable}@>> && ...); + requires @\exposconcept{all-random-access}@; friend constexpr @\exposid{iterator}@ operator+(const @\exposid{iterator}@& i, difference_type n) requires @\exposconcept{all-random-access}@; @@ -8974,54 +8965,9 @@ \end{itemize} \end{itemdescr} -\begin{itemdecl} -friend constexpr bool operator<(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) - requires @\exposconcept{all-random-access}@; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{x.\exposid{current_} < y.\exposid{current_}}. -\end{itemdescr} - -\begin{itemdecl} -friend constexpr bool operator>(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) - requires @\exposconcept{all-random-access}@; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: \tcode{return y < x;} -\end{itemdescr} - -\begin{itemdecl} -friend constexpr bool operator<=(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) - requires @\exposconcept{all-random-access}@; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: \tcode{return !(y < x);} -\end{itemdescr} - -\begin{itemdecl} -friend constexpr bool operator>=(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) - requires @\exposconcept{all-random-access}@; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: \tcode{return !(x < y);} -\end{itemdescr} - \begin{itemdecl} friend constexpr auto operator<=>(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) - requires @\exposconcept{all-random-access}@ && - (@\libconcept{three_way_comparable}@>> && ...); + requires @\exposconcept{all-random-access}@; \end{itemdecl} \begin{itemdescr} From 62e3587d33966bac05f818fddcd3797d340b0a62 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Jul 2022 18:41:06 -0700 Subject: [PATCH 165/430] LWG3701 Make formatter, charT> requirement explicit --- source/utilities.tex | 1 + 1 file changed, 1 insertion(+) diff --git a/source/utilities.tex b/source/utilities.tex index e18b6b2e80..c131219fff 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -14648,6 +14648,7 @@ \begin{codeblock} template<> struct formatter; template<> struct formatter; +template struct formatter; template struct formatter; template struct formatter, charT>; From d29b963648c48de3184787281325d6e814140e11 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Jul 2022 18:45:29 -0700 Subject: [PATCH 166/430] LWG3702 Should zip_transform_view::iterator remove operator>; - friend constexpr bool operator<(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) - requires @\libconcept{random_access_range}@<@\exposid{Base}@>; - friend constexpr bool operator>(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) - requires @\libconcept{random_access_range}@<@\exposid{Base}@>; - friend constexpr bool operator<=(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) - requires @\libconcept{random_access_range}@<@\exposid{Base}@>; - friend constexpr bool operator>=(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) - requires @\libconcept{random_access_range}@<@\exposid{Base}@>; friend constexpr auto operator<=>(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) - requires @\libconcept{random_access_range}@<@\exposid{Base}@> && @\libconcept{three_way_comparable}@<@\exposid{ziperator}@>; + requires @\libconcept{random_access_range}@<@\exposid{Base}@>; friend constexpr @\exposid{iterator}@ operator+(const @\exposid{iterator}@& i, difference_type n) requires @\libconcept{random_access_range}@<@\exposid{Base}@>; @@ -9587,16 +9579,8 @@ \begin{itemdecl} friend constexpr bool operator==(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) requires @\libconcept{equality_comparable}@<@\exposid{ziperator}@>; -friend constexpr bool operator<(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) - requires @\libconcept{random_access_range}@<@\exposid{Base}@>; -friend constexpr bool operator>(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) - requires @\libconcept{random_access_range}@<@\exposid{Base}@>; -friend constexpr bool operator<=(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) - requires @\libconcept{random_access_range}@<@\exposid{Base}@>; -friend constexpr bool operator>=(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) - requires @\libconcept{random_access_range}@<@\exposid{Base}@>; friend constexpr auto operator<=>(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) - requires @\libconcept{random_access_range}@<@\exposid{Base}@> && @\libconcept{three_way_comparable}@<@\exposid{ziperator}@>; + requires @\libconcept{random_access_range}@<@\exposid{Base}@>; \end{itemdecl} \begin{itemdescr} From 62fe2a0689653ff2a89da0285edb1a0ba01a8b82 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Jul 2022 18:55:59 -0700 Subject: [PATCH 167/430] LWG3703 Missing requirements for expected requires is_void --- source/utilities.tex | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/source/utilities.tex b/source/utilities.tex index c131219fff..4bb00cb94f 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -6933,11 +6933,7 @@ Implementations are not permitted to use additional storage, such as dynamic memory, to allocate the object of type \tcode{T} or the object of type \tcode{E}. -These objects are allocated in a region of the \tcode{expected} storage -suitably aligned for the types \tcode{T} and \tcode{E}. -Members \exposid{has_val}, \exposid{val}, and \exposid{unex} -are provided for exposition only. -\exposid{has_val} indicates whether the \tcode{expected} object +Member \exposid{has_val} indicates whether the \tcode{expected} object contains an object of type \tcode{T}. \pnum @@ -7977,6 +7973,21 @@ }; \end{codeblock} +\pnum +Any object of type \tcode{expected} either +represents a value of type \tcode{T}, or +contains a value of type \tcode{E} within its own storage. +Implementations are not permitted to use additional storage, +such as dynamic memory, to allocate the object of type \tcode{E}. +Member \exposid{has_val} indicates whether the \tcode{expected} object +represents a value of type \tcode{T}. + +\pnum +A program that instantiates +the definition of the template \tcode{expected} with +a type for the \tcode{E} parameter that +is not a valid template argument for \tcode{unexpected} is ill-formed. + \pnum \tcode{E} shall meet the requirements of \oldconcept{Destructible} (\tref{cpp17.destructible}). From a7cbca78450f81ce7702b01e017e4a1f17e98fe9 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Jul 2022 19:02:11 -0700 Subject: [PATCH 168/430] LWG3704 LWG 2059 added overloads that might be ill-formed for sets --- source/containers.tex | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index bf2b4b012c..72cabef394 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -10515,7 +10515,8 @@ insert_return_type insert(node_type&& nh); iterator insert(const_iterator hint, node_type&& nh); - iterator erase(iterator position); + iterator erase(iterator position) + requires (!@\libconcept{same_as}@); iterator erase(const_iterator position); size_type erase(const key_type& x); template size_type erase(K&& x); @@ -10827,7 +10828,8 @@ iterator insert(node_type&& nh); iterator insert(const_iterator hint, node_type&& nh); - iterator erase(iterator position); + iterator erase(iterator position) + requires (!@\libconcept{same_as}@); iterator erase(const_iterator position); size_type erase(const key_type& x); template size_type erase(K&& x); @@ -12359,7 +12361,8 @@ insert_return_type insert(node_type&& nh); iterator insert(const_iterator hint, node_type&& nh); - iterator erase(iterator position); + iterator erase(iterator position) + requires (!@\libconcept{same_as}@); iterator erase(const_iterator position); size_type erase(const key_type& k); template size_type erase(K&& x); @@ -12732,7 +12735,8 @@ iterator insert(node_type&& nh); iterator insert(const_iterator hint, node_type&& nh); - iterator erase(iterator position); + iterator erase(iterator position) + requires (!@\libconcept{same_as}@); iterator erase(const_iterator position); size_type erase(const key_type& k); template size_type erase(K&& x); From f8f6265f6b72678ed95901db776561db9642eda0 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Jul 2022 19:17:54 -0700 Subject: [PATCH 169/430] LWG3705 Hashability shouldn't depend on basic_string's allocator --- source/strings.tex | 41 ++++++++++++----------------------------- 1 file changed, 12 insertions(+), 29 deletions(-) diff --git a/source/strings.tex b/source/strings.tex index 8e9ae733a0..ad2a4aeee8 100644 --- a/source/strings.tex +++ b/source/strings.tex @@ -1972,16 +1972,11 @@ // \ref{basic.string.hash}, hash support template struct hash; - template<> struct hash; - template<> struct hash; - template<> struct hash; - template<> struct hash; - template<> struct hash; - template<> struct hash; - template<> struct hash; - template<> struct hash; - template<> struct hash; - template<> struct hash; + template struct hash, A>>; + template struct hash, A>>; + template struct hash, A>>; + template struct hash, A>>; + template struct hash, A>>; inline namespace literals { inline namespace string_literals { @@ -5290,25 +5285,13 @@ \rSec2[basic.string.hash]{Hash support} -\indexlibrarymember{hash}{string}% -\indexlibrarymember{hash}{u16string}% -\indexlibrarymember{hash}{u32string}% -\indexlibrarymember{hash}{wstring}% -\indexlibrarymember{hash}{pmr::string}% -\indexlibrarymember{hash}{pmr::u16string}% -\indexlibrarymember{hash}{pmr::u32string}% -\indexlibrarymember{hash}{pmr::wstring}% -\begin{itemdecl} -template<> struct hash; -template<> struct hash; -template<> struct hash; -template<> struct hash; -template<> struct hash; -template<> struct hash; -template<> struct hash; -template<> struct hash; -template<> struct hash; -template<> struct hash; +\indexlibrarymember{hash}{basic_string}% +\begin{itemdecl} +template struct hash, A>>; +template struct hash, A>>; +template struct hash, A>>; +template struct hash, A>>; +template struct hash, A>>; \end{itemdecl} \begin{itemdescr} From 7ecb746a0c41c60e4117da644e7d1ebe70b2f3cd Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Jul 2022 19:25:58 -0700 Subject: [PATCH 170/430] LWG3707 chunk_view::outer-iterator::value_type::size should return unsigned type --- source/ranges.tex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index dbbaff6822..0417a4cb02 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -11198,7 +11198,8 @@ \effects Equivalent to: \begin{codeblock} -return ranges::min(@\exposid{parent_}@->@\exposid{remainder_}@, ranges::end(@\exposid{parent_}@->@\exposid{base_}@) - *@\exposid{parent_}@->@\exposid{current_}@); +return @\exposid{to-unsigned-like}@(ranges::min(@\exposid{parent_}@->@\exposid{remainder_}@, + ranges::end(@\exposid{parent_}@->@\exposid{base_}@) - *@\exposid{parent_}@->@\exposid{current_}@)); \end{codeblock} \end{itemdescr} From d6a68e3622a40a52154a6e23bc42e4de1215c03d Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Jul 2022 19:27:47 -0700 Subject: [PATCH 171/430] LWG3708 take_while_view::sentinel's conversion constructor should move --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index 0417a4cb02..eec7445251 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -5323,7 +5323,7 @@ \begin{itemdescr} \pnum \effects -Initializes \exposid{end_} with \tcode{s.\exposid{end_}} and +Initializes \exposid{end_} with \tcode{std::move(s.\exposid{end_})} and \exposid{pred_} with \tcode{s.\exposid{pred_}}. \end{itemdescr} From 60fa43a5959aee254033440771a02a875993cc82 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Jul 2022 19:30:47 -0700 Subject: [PATCH 172/430] LWG3709 LWG-3703 was underly ambitious --- source/utilities.tex | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/source/utilities.tex b/source/utilities.tex index 4bb00cb94f..8b632563dc 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -2905,13 +2905,13 @@ it means that an object of type \tcode{T}, referred to as the optional object's \defnx{contained value}{contained value!\idxcode{optional}}, is allocated within the storage of the optional object. Implementations are not permitted to use additional storage, such as dynamic memory, to allocate its contained value. -The contained value shall be allocated in a region of the \tcode{optional} storage suitably aligned for the type \tcode{T}. 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 -Member \tcode{val} is provided for exposition only. When an \tcode{optional} object contains a value, \tcode{val} points to the contained value. +When an \tcode{optional} object contains a value, +member \tcode{val} points to the contained value. \pnum \tcode{T} shall be a type @@ -4635,8 +4635,6 @@ \tcode{variant} object. Implementations are not permitted to use additional storage, such as dynamic memory, to allocate the contained value. -The contained value shall be allocated in a region of the \tcode{variant} -storage suitably aligned for all types in \tcode{Types}. \pnum All types in \tcode{Types} shall meet From d7a01d97fc63b692df1d4aa2f8b5266236daa5b7 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Jul 2022 19:32:09 -0700 Subject: [PATCH 173/430] LWG3710 The end of chunk_view for input ranges can be const --- source/ranges.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index eec7445251..672671a0f3 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -10939,7 +10939,7 @@ constexpr V base() && { return std::move(@\exposid{base_}@); } constexpr @\exposid{outer-iterator}@ begin(); - constexpr default_sentinel_t end() noexcept; + constexpr default_sentinel_t end() const noexcept; constexpr auto size() requires @\libconcept{sized_range}@; constexpr auto size() const requires @\libconcept{sized_range}@; @@ -10981,7 +10981,7 @@ \end{itemdescr} \begin{itemdecl} -constexpr default_sentinel_t end() noexcept; +constexpr default_sentinel_t end() const noexcept; \end{itemdecl} \begin{itemdescr} From 0416e7ec335257c0d9b2fb1e31d5383dc58aaddf Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Jul 2022 19:35:07 -0700 Subject: [PATCH 174/430] LWG3711 Missing preconditions for slide_view constructor --- source/ranges.tex | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/ranges.tex b/source/ranges.tex index 672671a0f3..456fa8c3e8 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -11919,6 +11919,10 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\expects +\tcode{n > 0} is \tcode{true}. + \pnum \effects Initializes \exposid{base_} with \tcode{std::move(base)} and From ab54e00acb64d630cad43b41bf2d97f1fa4de9e1 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Jul 2022 19:40:17 -0700 Subject: [PATCH 175/430] LWG3712 chunk_view and slide_view should not be default_initializable --- source/ranges.tex | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index 456fa8c3e8..5ae9e88043 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -10919,8 +10919,8 @@ template<@\libconcept{view}@ V> requires @\libconcept{input_range}@ class chunk_view : public view_interface> { - V @\exposid{base_}@ = V(); // \expos - range_difference_t @\exposid{n_}@ = 0; // \expos + V @\exposid{base_}@; // \expos + range_difference_t @\exposid{n_}@; // \expos range_difference_t @\exposid{remainder_}@ = 0; // \expos @\exposid{non-propagating-cache}@> @\exposid{current_}@; // \expos @@ -10932,7 +10932,6 @@ class @\exposid{inner-iterator}@; // \expos public: - chunk_view() requires @\libconcept{default_initializable}@ = default; constexpr explicit chunk_view(V base, range_difference_t n); constexpr V base() const & requires @\libconcept{copy_constructible}@ { return @\exposid{base_}@; } @@ -11351,14 +11350,13 @@ template<@\libconcept{view}@ V> requires @\libconcept{forward_range}@ class chunk_view : public view_interface> { - V @\exposid{base_}@ = V(); // \expos - range_difference_t @\exposid{n_}@ = 0; // \expos + V @\exposid{base_}@; // \expos + range_difference_t @\exposid{n_}@; // \expos // \ref{range.chunk.fwd.iter}, class template \tcode{chunk_view::\exposid{iterator}} template class @\exposid{iterator}@; // \expos public: - chunk_view() requires @\libconcept{default_initializable}@ = default; constexpr explicit chunk_view(V base, range_difference_t n); constexpr V base() const & requires @\libconcept{copy_constructible}@ { return @\exposid{base_}@; } @@ -11884,8 +11882,8 @@ template<@\libconcept{forward_range}@ V> requires @\libconcept{view}@ class slide_view : public view_interface> { - V @\exposid{base_}@ = V(); // \expos - range_difference_t @\exposid{n_}@ = 0; // \expos + V @\exposid{base_}@; // \expos + range_difference_t @\exposid{n_}@; // \expos // \ref{range.slide.iterator}, class template \tcode{slide_view::\exposid{iterator}} template class @\exposid{iterator}@; // \expos @@ -11894,7 +11892,6 @@ class @\exposid{sentinel}@; // \expos public: - slide_view() requires @\libconcept{default_initializable}@ = default; constexpr explicit slide_view(V base, range_difference_t n); constexpr auto begin() From d6d435a867fb2a5c884a84a61f969cf9e999ba00 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Jul 2022 19:57:29 -0700 Subject: [PATCH 176/430] LWG3713 Sorted with respect to comparator (only) [alg.sorting.general] Add index for definition of a sequence sorted with respect to a comparator and projection --- source/algorithms.tex | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source/algorithms.tex b/source/algorithms.tex index fbe42e26fa..04cb156bc8 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -6206,6 +6206,7 @@ \end{note} \pnum +\indexdefn{sequence!sorted!with respect to a comparator and projection}% A sequence is \term{sorted with respect to a \tcode{comp} and \tcode{proj}} for a comparator and projection \tcode{comp} and \tcode{proj} if for every iterator \tcode{i} pointing to the sequence and @@ -6217,6 +6218,13 @@ \end{codeblock} is \tcode{false}. +\pnum +\indexdefn{sequence!sorted!with respect to a comparator}% +A sequence is \term{sorted with respect to a comparator} \tcode{comp} +for a comparator \tcode{comp} +if it is sorted with respect to +\tcode{comp} and \tcode{identity\{\}} (the identity projection). + \pnum A sequence \range{start}{finish} is \term{partitioned with respect to an expression} \tcode{f(e)} From 81b066eff19b8b07bba3af9d18ee46c2e9101917 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Jul 2022 20:11:47 -0700 Subject: [PATCH 177/430] LWG3715 view_interface::empty is overconstrained --- source/ranges.tex | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index 5ae9e88043..ead1940263 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -1537,11 +1537,17 @@ } public: - constexpr bool empty() requires @\libconcept{forward_range}@ { - return ranges::begin(@\exposid{derived}@()) == ranges::end(@\exposid{derived}@()); + constexpr bool empty() requires @\libconcept{sized_range}@ || @\libconcept{forward_range}@ { + if constexpr (@\libconcept{sized_range}@) + return ranges::size(@\exposid{derived}@()) == 0; + else + return ranges::begin(@\exposid{derived}@()) == ranges::end(@\exposid{derived}@()); } - constexpr bool empty() const requires @\libconcept{forward_range}@ { - return ranges::begin(@\exposid{derived}@()) == ranges::end(@\exposid{derived}@()); + constexpr bool empty() const requires @\libconcept{sized_range}@ || @\libconcept{forward_range}@ { + if constexpr (@\libconcept{sized_range}@) + return ranges::size(@\exposid{derived}@()) == 0; + else + return ranges::begin(@\exposid{derived}@()) == ranges::end(@\exposid{derived}@()); } constexpr explicit operator bool() From 8d06220f21a833fb55c059a429fe30ad6a1db983 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Jul 2022 20:19:36 -0700 Subject: [PATCH 178/430] LWG3719 Directory iterators should be usable with default sentinel --- source/iostreams.tex | 8 ++++++++ source/regex.tex | 2 ++ 2 files changed, 10 insertions(+) diff --git a/source/iostreams.tex b/source/iostreams.tex index ac91f6ed3a..51e6fb05af 100644 --- a/source/iostreams.tex +++ b/source/iostreams.tex @@ -15757,6 +15757,10 @@ directory_iterator& operator++(); directory_iterator& increment(error_code& ec); + bool operator==(default_sentinel_t) const noexcept { + return *this == directory_iterator(); + } + // other members as required by \ref{input.iterators}, input iterators }; } @@ -16003,6 +16007,10 @@ void pop(error_code& ec); void disable_recursion_pending(); + bool operator==(default_sentinel_t) const noexcept { + return *this == recursive_directory_iterator(); + } + // other members as required by \ref{input.iterators}, input iterators }; } diff --git a/source/regex.tex b/source/regex.tex index 5ee8aa28ed..963a3d0630 100644 --- a/source/regex.tex +++ b/source/regex.tex @@ -3228,6 +3228,7 @@ regex_iterator(const regex_iterator&); regex_iterator& operator=(const regex_iterator&); bool operator==(const regex_iterator&) const; + bool operator==(default_sentinel_t) const { return *this == regex_iterator(); } const value_type& operator*() const; const value_type* operator->() const; regex_iterator& operator++(); @@ -3533,6 +3534,7 @@ regex_token_iterator(const regex_token_iterator&); regex_token_iterator& operator=(const regex_token_iterator&); bool operator==(const regex_token_iterator&) const; + bool operator==(default_sentinel_t) const { return *this == regex_token_iterator(); } const value_type& operator*() const; const value_type* operator->() const; regex_token_iterator& operator++(); From c519b70b0e1c5d8184fab85df0833582ab5e23d0 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Jul 2022 20:21:33 -0700 Subject: [PATCH 179/430] LWG3721 Allow an arg-id with a value of zero for width in std-format-spec --- source/utilities.tex | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/source/utilities.tex b/source/utilities.tex index 8b632563dc..642efdf2c9 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -13833,9 +13833,7 @@ a \fmtgrammarterm{width} or \fmtgrammarterm{precision}, the value of the corresponding formatting argument is used in its place. If the corresponding formatting argument is not of integral type, or -its value is -negative for \fmtgrammarterm{precision} or -non-positive for \fmtgrammarterm{width}, +its value is negative, an exception of type \tcode{format_error} is thrown. \pnum From cdd04d631e629215336fc120b43ce4cc76892f6d Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Jul 2022 20:26:15 -0700 Subject: [PATCH 180/430] LWG3724 decay-copy should be constrained --- source/lib-intro.tex | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/source/lib-intro.tex b/source/lib-intro.tex index 555f81b7d5..4dbbdcd82b 100644 --- a/source/lib-intro.tex +++ b/source/lib-intro.tex @@ -492,9 +492,11 @@ \indexlibrary{decay-copy@\tcode{\placeholder{decay-copy}}}% \begin{codeblock} namespace std { - template constexpr decay_t @\placeholdernc{decay-copy}@(T&& v) - noexcept(is_nothrow_convertible_v>) // \expos - { return std::forward(v); } + template + requires @\libconcept{convertible_to}@> + constexpr decay_t @\placeholdernc{decay-copy}@(T&& v) + noexcept(is_nothrow_convertible_v>) // \expos + { return std::forward(v); } constexpr auto @\placeholdernc{synth-three-way}@ = [](const T& t, const U& u) From 4b97cb9349fbacf76c5dabef5e7288f221654c36 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sat, 16 Jul 2022 19:53:50 +0200 Subject: [PATCH 181/430] P0009R18 mdspan Editorial changes: - Rephrase "may" in notes. - Give expression `sizeof...(OtherSizeTypes)` a name (`N`) to simplify the presentation. - Change "for all rank index `r`" to "for every rank index `r`". - Drop some extraneous parentheses. - Spell non-type template parameter `Args`, not `args`. --- source/containers.tex | 2435 ++++++++++++++++++++++++++++++++++++++++- source/lib-intro.tex | 1 + source/support.tex | 1 + 3 files changed, 2436 insertions(+), 1 deletion(-) diff --git a/source/containers.tex b/source/containers.tex index 72cabef394..d4b68e12aa 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -27,7 +27,7 @@ \tcode{}, \tcode{} \\ \rowsep \ref{container.adaptors} & Container adaptors & \tcode{}, \tcode{} \\ \rowsep -\ref{views} & Views & \tcode{} \\ +\ref{views} & Views & \tcode{}, \tcode{} \\ \end{libsumtab} @@ -14302,6 +14302,8 @@ \pnum The header \libheader{span} defines the view \tcode{span}. +The header \libheader{mdspan} defines the class template \tcode{mdspan} and +other facilities for interacting with these multidimensional views. \rSec2[span.syn]{Header \tcode{} synopsis}% @@ -15036,3 +15038,2434 @@ Equivalent to: \tcode{return R\{reinterpret_cast(s.data()), s.size_bytes()\};} where \tcode{R} is the return type. \end{itemdescr} + +\rSec2[mdspan.syn]{Header \tcode{} synopsis} + +\indexheader{mdspan}% +\begin{codeblock} +namespace std { + // \ref{mdspan.extents}, class template \tcode{extents} + template + class extents; + + // \ref{mdspan.extents.dextents}, alias template \tcode{dextents} + template + using dextents = @\seebelow@; + + // \ref{mdspan.layout}, layout mapping + struct layout_left; + struct layout_right; + struct layout_stride; + + // \ref{mdspan.accessor.default}, class template \tcode{default_accessor} + template + class default_accessor; + + // \ref{mdspan.mdspan}, class template \tcode{mdspan} + template> + class mdspan; +} +\end{codeblock} + +\rSec2[mdspan.overview]{Overview} + +\pnum +A \defnadj{multidimensional}{index space} is +a Cartesian product of integer intervals. +Each interval can be represented by a half-open range $[L_i, U_i)$, +where $L_i$ and $U_i$ are the lower and upper bounds of +the $i^\text{th}$ dimension. +The \defn{rank} of a multidimensional index space is +the number of intervals it represents. +The \defn{size} of a multidimensional index space is +the product of $U_i - L_i$ for each dimension $i$ +if its rank is greater than 0, and 1 otherwise. + +\pnum +A pack of integers \tcode{idx} is +a \defnadj{multidimensional}{index} in a multidimensional index space $S$ +(or representation thereof) if both of the following are true: +\begin{itemize} +\item +\tcode{sizeof...(idx)} is equal to the rank of $S$, and +\item +for all $i$ in the range $[0, \text{rank of $S$})$, +the $i^\text{th}$ value of \tcode{idx} is an integer +in the interval $[L_i, U_i)$ of $S$. +\end{itemize} + +\pnum +An integer $r$ is a \defn{rank index} of an index space $S$ +if $r$ is in the range $[0, \text{rank of $S$})$. + +\rSec2[mdspan.extents]{Class template \tcode{extents}} + +\rSec3[mdspan.extents.overview]{Overview} + +The class template \tcode{extents} represents +a multidimensional index space of rank equal to \tcode{sizeof...(Extents)}. +In subclause \iref{views}, +\tcode{extents} is used synonymously with multidimensional index space. + +\begin{codeblock} +namespace std { + template + class @\libglobal{extents}@ { + public: + using size_type = SizeType; + using rank_type = size_t; + + // \ref{mdspan.extents.obs}, observers of the multidimensional index space + static constexpr rank_type rank() noexcept { return sizeof...(Extents); } + static constexpr rank_type rank_dynamic() noexcept { return @\exposid{dynamic-index}@(rank()); } + static constexpr size_t static_extent(rank_type) noexcept; + constexpr size_type extent(rank_type) const noexcept; + + // \ref{mdspan.extents.ctor}, constructors + constexpr extents() noexcept = default; + + template + constexpr explicit(@\seebelow@) + extents(const extents&) noexcept; + template + constexpr explicit extents(OtherSizeTypes...) noexcept; + template + constexpr explicit(N != rank_dynamic()) + extents(span) noexcept; + template + constexpr explicit(N != rank_dynamic()) + extents(const array&) noexcept; + + // \ref{mdspan.extents.cmp}, comparison operators + template + friend constexpr bool operator==(const extents&, + const extents&) noexcept; + + // \ref{mdspan.extents.expo}, exposition-only helpers + constexpr size_t @\exposid{fwd-prod-of-extents}@(rank_type) const noexcept; // \expos + constexpr size_t @\exposid{rev-prod-of-extents}@(rank_type) const noexcept; // \expos + template + static constexpr auto @\exposid{index-cast}@(OtherSizeType&&) noexcept; // \expos + + private: + static constexpr rank_type @\exposid{dynamic-index}@(rank_type) noexcept; // \expos + static constexpr rank_type @\exposid{dynamic-index-inv}@(rank_type) noexcept; // \expos + array @\exposid{dynamic-extents}@{}; // \expos + }; + + template + explicit extents(Integrals...) + -> @\seebelow@; +} +\end{codeblock} + +\pnum +\mandates +\begin{itemize} +\item +\tcode{SizeType} is a signed or unsigned integer type, and +\item +each element of \tcode{Extents} is either equal to \tcode{dynamic_extent}, or +is representable as a value of type \tcode{SizeType}. +\end{itemize} + +\pnum +Each specialization of \tcode{extents} models \libconcept{regular} and +is trivially copyable. + +\pnum +Let $E_r$ be the $r^\text{th}$ element of \tcode{Extents}. +$E_r$ is a \defnadj{dynamic}{extent} if it is equal to \tcode{dynamic_extent}, +otherwise $E_r$ is a \defnadj{static}{extent}. +Let $D_r$ be the value of \tcode{\exposid{dynamic-extents}[\exposid{dynamic-index}($r$)]} +if $E_r$ is a dynamic extent, +otherwise $E_r$. + +\pnum +The $r^\text{th}$ interval of the multidimensional index space +represented by an \tcode{extents} object is $[0, D_r)$. + +\rSec3[mdspan.extents.expo]{Exposition-only helpers} + +\begin{itemdecl} +static constexpr rank_type @\exposid{dynamic-index}@(rank_type i) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{i <= rank()} is \tcode{true}. + +\pnum +\returns +The number of $E_r$ with $r < \tcode{i}$ for which $E_r$ is a dynamic extent. +\end{itemdescr} + +\begin{itemdecl} +static constexpr rank_type @\exposid{dynamic-index-inv}@(rank_type i) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{i < rank_dynamic()} is \tcode{true}. + +\pnum +\returns +The minimum value of $r$ +such that \tcode{\exposid{dynamic-index}($r$ + 1) == i + 1} is \tcode{true}. +\end{itemdescr} + +\begin{itemdecl} +constexpr size_t @\exposid{fwd-prod-of-extents}@(rank_type i) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{i <= rank()} is \tcode{true}. + +\pnum +\returns +If \tcode{i > 0} is \tcode{true}, +the product of \tcode{extent($k$)} for all $k$ in the range $[0, \tcode{i})$, +otherwise \tcode{1}. +\end{itemdescr} + +\begin{itemdecl} +constexpr size_t @\exposid{rev-prod-of-extents}@(rank_type i) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{i < rank()} is \tcode{true}. + +\pnum +\returns +If \tcode{i + 1 < rank()} is \tcode{true}, +the product of \tcode{extent($k$)} +for all $k$ in the range $[\tcode{i + 1}, \tcode{rank()})$, +otherwise \tcode{1}. +\end{itemdescr} + +\begin{itemdecl} +template + static constexpr auto @\exposid{index-cast}@(OtherSizeType&& i) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +\begin{itemize} +\item +If \tcode{OtherSizeType} is an integral type other than \tcode{bool}, +then equivalent to \tcode{return i;}, +\item +otherwise, equivalent to \tcode{return static_cast(i);}. +\end{itemize} +\begin{note} +This function will always return an integral type other than \tcode{bool}. +Since this function's call sites are constrained on +convertibility of \tcode{OtherSizeType} to \tcode{size_type}, +integer-class types can use the \tcode{static_cast} branch +without loss of precision. +\end{note} +\end{itemdescr} + +\rSec3[mdspan.extents.ctor]{Constructors} + +\indexlibraryctor{extents}% +\begin{itemdecl} +template + constexpr explicit(@\seebelow@) + extents(const extents& other) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{sizeof...(OtherExtents) == rank()} is \tcode{true}. +\item +\tcode{((OtherExtents == dynamic_extent || Extents == dynamic_extent || OtherExtents ==\newline Extents) \&\& ...)} is \tcode{true}. +\end{itemize} + +\pnum +\expects +\begin{itemize} +\item +\tcode{other.extent($r$)} equals $E_r$ +for each $r$ for which $E_r$ is a static extent, and +\item +either +\begin{itemize} +\item +\tcode{sizeof...(OtherExtents)} is zero, or +\item +\tcode{other.extent(r)} is representable as +a value of type \tcode{size_type} for every rank index \tcode{r} of \tcode{other}. +\end{itemize} +\end{itemize} + +\pnum +\ensures +\tcode{*this == other} is \tcode{true}. + +\pnum +\remarks +The expression inside \tcode{explicit} is equivalent to: +\begin{codeblock} +(((Extents != dynamic_extent) && (OtherExtents == dynamic_extent)) || ... ) || +(numeric_limits::max() < numeric_limits::max()) +\end{codeblock} +\end{itemdescr} + +\indexlibraryctor{extents}% +\begin{itemdecl} +template + explicit constexpr extents(OtherSizeTypes... exts) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +Let \tcode{N} be \tcode{sizeof...(OtherSizeTypes)}. +\begin{itemize} +\item +\tcode{(is_convertible_v \&\& ...)} is \tcode{true}, +\item +\tcode{(is_nothrow_constructible_v \&\& ...)} is \tcode{true}, and +\item +\tcode{N == rank_dynamic() || N == rank()} is \tcode{true}. +\begin{note} +One can construct \tcode{extents} from just dynamic extents, +which are all the values getting stored, or +from all the extents with a precondition. +\end{note} +\end{itemize} + +\pnum +Let \tcode{exts_arr} be +\begin{codeblock} +array{static_cast(std::move(exts))...} +\end{codeblock} + +\pnum +\expects +\begin{itemize} +\item +If \tcode{sizeof...(OtherSizeTypes) != rank_dynamic()} is \tcode{true}, +\tcode{exts_arr[$r$]} equals $E_r$ +for each $r$ for which $E_r$ is a static extent, and +\item +either +\begin{itemize} +\item +\tcode{sizeof...(exts) == 0} is \tcode{true}, or +\item +each element of \tcode{exts} is nonnegative and +is representable as a value of type \tcode{size_type}. +\end{itemize} +\end{itemize} + +\pnum +\ensures +\tcode{*this == extents(exts_arr)} is \tcode{true}. +\end{itemdescr} + +\indexlibraryctor{extents}% +\begin{itemdecl} +template + constexpr explicit(N != rank_dynamic()) + extents(span exts) noexcept; +template + constexpr explicit(N != rank_dynamic()) + extents(const array& exts) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{is_convertible_v} is \tcode{true}, +\item +\tcode{is_nothrow_constructible_v} is \tcode{true}, and +\item +\tcode{N == rank_dynamic() || N == rank()} is \tcode{true}. +\end{itemize} + +\pnum +\expects +\begin{itemize} +\item +If \tcode{N != rank_dynamic()} is \tcode{true}, +\tcode{exts[$r$]} equals $E_r$ for each $r$ for which $E_r$ is a static extent, and +\item +either +\begin{itemize} +\item +\tcode{N} is zero, or +\item +\tcode{exts[r]} is nonnegative and +is representable as a value of type \tcode{size_type} for every rank index \tcode{r}. +\end{itemize} +\end{itemize} + +\pnum +\effects +\begin{itemize} +\item +If \tcode{N} equals \tcode{dynamic_rank()}, +for all $d$ in the range $[0, \tcode{rank_dynamic()})$, +direct-non-list-initializes \tcode{\exposidnc{dynamic-extent}[$d$]} +with \tcode{as_const(exts[$d$])}. +\item +Otherwise, for all $d$ in the range $[0, \tcode{rank_dynamic()})$, +direct-non-list-initializes \tcode{\exposidnc{dynamic-extent}\brk{}[$d$]} +with \tcode{as_const(exts[\exposidnc{dynamic-index-inv}($d$)])}. +\end{itemize} +\end{itemdescr} + +\indexlibraryctor{extents}% +\begin{itemdecl} +template + explicit extents(Integrals...) -> @\seebelow@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{(is_convertible_v \&\& ...)} is \tcode{true}. + +\pnum +\remarks +The deduced type is \tcode{dextents}. +\end{itemdescr} + +\rSec3[mdspan.extents.obs]{Observers of the multidimensional index space} + +\indexlibrarymember{static_extent}{extents}% +\begin{itemdecl} +static constexpr size_t static_extent(rank_type i) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{i < rank()} is \tcode{true}. + +\pnum +\returns +$E_\tcode{i}$. +\end{itemdescr} + +\indexlibrarymember{extent}{extents}% +\begin{itemdecl} +constexpr size_type extent(rank_type i) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{i < rank()} is \tcode{true}. + +\pnum +\returns +$D_\tcode{i}$. +\end{itemdescr} + +\rSec3[mdspan.extents.cmp]{Comparison operators} + +\indexlibrarymember{operator==}{extents}% +\begin{itemdecl} +template + friend constexpr bool operator==(const extents& lhs, + const extents& rhs) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{lhs.rank()} equals \tcode{rhs.rank()} and +if \tcode{lhs.extent(r)} equals \tcode{rhs.extent(r)} +for every rank index \tcode{r} of \tcode{rhs}, +otherwise \tcode{false}. +\end{itemdescr} + +\rSec3[mdspan.extents.dextents]{Alias template \tcode{dextents}} + +\indexlibraryglobal{dextents}% +\begin{itemdecl} +template + using dextents = @\seebelow@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +A type \tcode{E} that is a specialization of \tcode{extents} +such that \tcode{E::rank() == Rank \&\& E::rank() == E::rank_dynamic()} is \tcode{true}, and +\tcode{E::size_type} denotes \tcode{SizeType}. +\end{itemdescr} + +\rSec2[mdspan.layout]{Layout mapping} + +\rSec3[mdspan.layout.general]{General} + +\pnum +In subclauses \ref{mdspan.layout.reqmts} and \ref{mdspan.layout.policy.reqmts}: + +\begin{itemize} +\item +\tcode{M} denotes a layout mapping class. + +\item +\tcode{m} denotes a (possibly const) value of type \tcode{M}. + +\item +\tcode{i} and \tcode{j} are packs of (possibly const) integers +that are multidimensional indices in \tcode{m.extents()}\iref{mdspan.overview}. +\begin{note} +The type of each element of the packs can be a different integer type. +\end{note} + +\item +\tcode{r} is a (possibly const) rank index of \tcode{typename M::extents_type}. + +\item +$\tcode{d}_r$ is a pack of (possibly const) integers +for which \tcode{sizeof...($\tcode{d}_r$) == M::extents_type::rank()} is \tcode{true}, +the $r^\text{th}$ element is equal to 1, and +all other elements are equal to 0. +\end{itemize} + +\pnum +In subclauses \ref{mdspan.layout.reqmts} through \ref{mdspan.layout.stride}, +let \exposid{is-mapping-of} be the exposition-only variable template defined as follows: +\begin{codeblock} +template +constexpr bool @\exposid{is-mapping-of}@ = // \expos + is_same_v, Mapping>; +\end{codeblock} + +\rSec3[mdspan.layout.reqmts]{Requirements} + +\pnum +A type \tcode{M} meets the \defn{layout mapping} requirements if + +\begin{itemize} +\item +\tcode{M} models \libconcept{copyable} and \libconcept{equality_comparable}, +\item +\tcode{is_nothrow_move_constructible_v} is \tcode{true}, +\item +\tcode{is_nothrow_move_assignable_v} is \tcode{true}, +\item +\tcode{is_nothrow_swappable_v} is \tcode{true}, and +\item +the following types and expressions are well-formed and +have the specified semantics. +\end{itemize} + +\begin{itemdecl} +typename M::extents_type +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +A type that is a specialization of \tcode{extents}. +\end{itemdescr} + +\begin{itemdecl} +typename M::size_type +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{typename M::extents_type::size_type}. +\end{itemdescr} + +\begin{itemdecl} +typename M::rank_type +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{typename M::extents_type::rank_type}. +\end{itemdescr} + +\begin{itemdecl} +typename M::layout_type +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +A type \tcode{MP} that meets +the layout mapping policy requirements\iref{mdspan.layout.policy.reqmts} and +for which \tcode{\exposid{is-mapping-of}} is \tcode{true}. +\end{itemdescr} + +\begin{itemdecl} +m.extents() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{const typename M::extents_type\&} +\end{itemdescr} + +\begin{itemdecl} +m(i...) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{typename M::size_type} + +\pnum +\returns +A nonnegative integer +less than \tcode{numeric_limits::max()} and +less than or equal to \tcode{numeric_limits::max()}. +\end{itemdescr} + +\begin{itemdecl} +m(i...) == m(static_cast(i)...) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{bool} + +\pnum +\returns +\tcode{true} +\end{itemdescr} + +\begin{itemdecl} +m.required_span_size() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{typename M::size_type} + +\pnum +\returns +If the size of the multidimensional index space \tcode{m.extents()} is 0, +then \tcode{0}, +else \tcode{1} plus the maximum value of \tcode{m(i...)} for all \tcode{i}. +\end{itemdescr} + +\begin{itemdecl} +m.is_unique() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{bool} + +\pnum +\returns +\tcode{true} only if +for every \tcode{i} and \tcode{j} where \tcode{(i != j || ...)} is \tcode{true}, +\tcode{m(i...) != m(j...)} is \tcode{true}. +\begin{note} +A mapping can return \tcode{false} even if the condition is met. +For certain layouts, it is possibly not feasible to determine efficiently +whether the layout is unique. +\end{note} +\end{itemdescr} + +\begin{itemdecl} +m.is_contiguous() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{bool} + +\pnum +\returns +\tcode{true} only if +for all $k$ in the range $[0, \tcode{m.required_span_size()})$ +there exists an \tcode{i} such that \tcode{m(i...)} equals \tcode{k}. +\begin{note} +A mapping can return \tcode{false} even if the condition is met. +For certain layouts, it is possibly not feasible to determine efficiently +whether the layout is contiguous. +\end{note} +\end{itemdescr} + +\begin{itemdecl} +m.is_strided() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{bool} + +\pnum +\returns +\tcode{true} only if +for every rank index $r$ of \tcode{m.extents()} there exists an integer $s_r$ +such that, +for all \tcode{i} where $(\tcode{i}+d_r)$ is +a multidimensional index in \tcode{m.extents()}\iref{mdspan.overview}, +\tcode{m((i + $d_r$)...) - m(i...)} equals $s_r$. +\begin{note} +This implies that for a strided layout +$m(i_0, \dotsc, i_k) = m(0, \dotsc, 0) + i_0 \times s_0 + \dotsb + i_k \times s_k$. +\end{note} +\begin{note} +A mapping can return \tcode{false} even if the condition is met. +For certain layouts, it is possibly not feasible to determine efficiently +whether the layout is strided. +\end{note} +\end{itemdescr} + +\begin{itemdecl} +m.stride(r) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{m.is_strided()} is \tcode{true}. + +\pnum +\result +\tcode{typename M::size_type} + +\pnum +\returns +$s_r$ as defined in \tcode{m.is_strided()} above. +\end{itemdescr} + +\begin{itemdecl} +M::is_always_unique() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +A constant expression\iref{expr.const} of type \tcode{bool}. + +\pnum +\returns +\tcode{true} only if \tcode{m.is_unique()} is \tcode{true} +for all possible objects \tcode{m} of type \tcode{M}. +\begin{note} +A mapping can return \tcode{false} even if the above condition is met. +For certain layout mappings, it is possibly not feasible to determine +whether every instance is unique. +\end{note} +\end{itemdescr} + +\begin{itemdecl} +M::is_always_contiguous() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +A constant expression\iref{expr.const} of type \tcode{bool}. + +\pnum +\returns +\tcode{true} only if \tcode{m.is_contiguous()} is \tcode{true} +for all possible objects \tcode{m} of type \tcode{M}. +\begin{note} +A mapping can return \tcode{false} even if the above condition is met. +For certain layout mappings, it is possibly not feasible to determine +whether every instance is contiguous. +\end{note} +\end{itemdescr} + +\begin{itemdecl} +M::is_always_strided() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +A constant expression\iref{expr.const} of type \tcode{bool}. + +\pnum +\returns +\tcode{true} only if \tcode{m.is_strided()} is \tcode{true} +for all possible objects \tcode{m} of type \tcode{M}. +\begin{note} +A mapping can return \tcode{false} even if the above condition is met. +For certain layout mappings, it is possibly not feasible to determine +whether every instance is strided. +\end{note} +\end{itemdescr} + +\rSec3[mdspan.layout.policy.reqmts]{Layout mapping policy requirements} + +\pnum +A type \tcode{MP} meets the \defn{layout mapping policy} requirements +if for a type \tcode{E} that is a specialization of \tcode{extents}, +\tcode{MP::mapping} is valid and denotes a type \tcode{X} +that meets the layout mapping requirements\iref{mdspan.layout.reqmts}, and +for which the \grammarterm{qualified-id} \tcode{X::layout_type} is valid and +denotes the type \tcode{MP} and +the \grammarterm{qualified-id} \tcode{X::extents_type} denotes \tcode{E}. + +\rSec3[mdspan.layout.policy.overview]{Layout mapping policies} + +\begin{codeblock} +namespace std { + struct layout_left { + template + class mapping; + }; + struct layout_right { + template + class mapping; + }; + struct layout_stride { + template + class mapping; + }; +} +\end{codeblock} + +\pnum +Each of \tcode{layout_left}, \tcode{layout_right}, and \tcode{layout_stride} +meets the layout mapping policy requirements and is a trivial type. + +\rSec3[mdspan.layout.left]{Class template \tcode{layout_left::mapping}} + +\rSec4[mdspan.layout.left.overview]{Overview} + +\pnum +\tcode{layout_left} provides a layout mapping +where the leftmost extent has stride 1, and +strides increase left-to-right as the product of extents. + +\begin{codeblock} +namespace std { + template + class layout_left::mapping { + public: + using extents_type = Extents; + using size_type = typename extents_type::size_type; + using rank_type = typename extents_type::rank_type; + using layout_type = layout_left; + + // \ref{mdspan.layout.left.ctor}, constructors + constexpr mapping() noexcept = default; + constexpr mapping(const mapping&) noexcept = default; + constexpr mapping(const extents_type&) noexcept; + template + constexpr explicit(!is_convertible_v) + mapping(const mapping&) noexcept; + template + constexpr explicit(@\seebelow@) + mapping(const layout_right::mapping&) noexcept; + template + explicit(extents_type::rank() > 0) + constexpr mapping(const layout_stride::mapping&); + + constexpr mapping& operator=(const mapping&) noexcept = default; + + // \ref{mdspan.layout.left.obs}, observers + constexpr const extents_type& extents() const noexcept { return @\exposid{extents_}@; } + + constexpr size_type required_span_size() const noexcept; + + template + constexpr size_type operator()(Indices...) const noexcept; + + static constexpr bool is_always_unique() noexcept { return true; } + static constexpr bool is_always_contiguous() noexcept { return true; } + static constexpr bool is_always_strided() noexcept { return true; } + + static constexpr bool is_unique() noexcept { return true; } + static constexpr bool is_contiguous() noexcept { return true; } + static constexpr bool is_strided() noexcept { return true; } + + constexpr size_type stride(rank_type) const noexcept; + + template + friend constexpr bool operator==(const mapping&, const mapping&) noexcept; + + private: + extents_type @\exposid{extents_}@{}; // \expos + }; +} +\end{codeblock} + +\pnum +If \tcode{Extents} is not a specialization of \tcode{extents}, +then the program is ill-formed. + +\pnum +\tcode{layout_left::mapping} is a trivially copyable type +that models \libconcept{regular} for each \tcode{E}. + +\rSec4[mdspan.layout.left.ctor]{Constructors} + +\indexlibraryctor{layout_left::mapping}% +\begin{itemdecl} +constexpr mapping(const extents_type& e) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +The size of the multidimensional index space \tcode{e} +is representable as a value of type \tcode{size_type}\iref{basic.fundamental}. + +\pnum +\effects +Direct-non-list-initializes \exposid{extents_} with \tcode{e}. +\end{itemdescr} + +\indexlibraryctor{layout_left::mapping}% +\begin{itemdecl} +template + constexpr explicit(!is_convertible_v) + mapping(const mapping& other) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_constructible_v} is \tcode{true}. + +\pnum +\expects +\tcode{other.required_span_size()} is representable as +a value of type \tcode{size_type}\iref{basic.fundamental}. + +\pnum +\effects +Direct-non-list-initializes \exposid{extents_} with \tcode{other.extents()}. +\end{itemdescr} + +\indexlibraryctor{layout_left::mapping}% +\begin{itemdecl} +template + constexpr explicit(!is_convertible_v) + mapping(const layout_right::mapping& other) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{extents_type::rank() <= 1} is \tcode{true}, and +\item +\tcode{is_constructible_v} is \tcode{true}. +\end{itemize} + +\pnum +\expects +\tcode{other.required_span_size()} is representable as +a value of type \tcode{size_type}\iref{basic.fundamental}. + +\pnum +\effects +Direct-non-list-initializes \exposid{extents_} with \tcode{other.extents()}. +\end{itemdescr} + +\indexlibraryctor{layout_left::mapping}% +\begin{itemdecl} +template + constexpr explicit(extents_type::rank() > 0) + mapping(const layout_stride::mapping& other); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_constructible_v} is \tcode{true}. + +\pnum +\expects +\begin{itemize} +\item +If \tcode{extents_type::rank() > 0} is \tcode{true}, +then for all $r$ in the range $[0, \tcode{extents_type::rank()})$, +\tcode{other.stride($r$)} equals +\tcode{extents().\exposid{fwd-prod-of-extents}($r$)}, and +\item +\tcode{other.required_span_size()} is representable as +a value of type \tcode{size_type}\iref{basic.fundamental}. +\end{itemize} + +\pnum +\effects +Direct-non-list-initializes \exposid{extents_} with \tcode{other.extents()}. +\end{itemdescr} + +\rSec4[mdspan.layout.left.obs]{Observers} + +\indexlibrarymember{required_span_size}{layout_left::mapping}% +\begin{itemdecl} +constexpr size_type required_span_size() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{extents().\exposid{fwd-prod-of-extents}(extents_type::rank())}. +\end{itemdescr} + +\indexlibrarymember{operator()}{layout_left::mapping}% +\begin{itemdecl} +template + constexpr size_type operator()(Indices... i) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{sizeof...(Indices) == extents_type::rank()} is \tcode{true}, +\item +\tcode{(is_convertible_v \&\& ...)} is \tcode{true}, and +\item +\tcode{(is_nothrow_constructible_v \&\& ...)} is \tcode{true}. +\end{itemize} + +\pnum +\expects +\tcode{extents_type::\exposid{index-cast}(i)} is +a multidimensional index in \exposid{extents_}\iref{mdspan.overview}. + +\pnum +\effects +Let \tcode{P} be a parameter pack such that +\begin{codeblock} +is_same_v, index_sequence> +\end{codeblock} +is \tcode{true}. +Equivalent to: +\begin{codeblock} +return ((static_cast(i) * stride(P)) + ... + 0); +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{stride}{layout_left::mapping}% +\begin{itemdecl} +constexpr size_type stride(rank_type i) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{extents_type::rank() > 0} is \tcode{true}. + +\pnum +\expects +\tcode{i < extents_type::rank()} is \tcode{true}. + +\pnum +\returns +\tcode{extents().\exposid{fwd-prod-of-extents}(i)}. +\end{itemdescr} + +\indexlibrarymember{operator==}{layout_left::mapping}% +\begin{itemdecl} +template + friend constexpr bool operator==(const mapping& x, const mapping& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{extents_type::rank() == OtherExtents::rank()} is \tcode{true}. + +\pnum +\effects +Equivalent to: \tcode{return x.extents() == y.extents();} +\end{itemdescr} + +\rSec3[mdspan.layout.right]{Class template \tcode{layout_right::mapping}} + +\rSec4[mdspan.layout.right.overview]{Overview} + +\pnum +\tcode{layout_right} provides a layout mapping +where the rightmost extent is stride 1, and +strides increase right-to-left as the product of extents. + +\begin{codeblock} +namespace std { + template + class layout_right::mapping { + public: + using extents_type = Extents; + using size_type = typename extents_type::size_type; + using rank_type = typename extents_type::rank_type; + using layout_type = layout_right; + + // \ref{mdspan.layout.right.ctor}, constructors + constexpr mapping() noexcept = default; + constexpr mapping(const mapping&) noexcept = default; + constexpr mapping(const extents_type&) noexcept; + template + constexpr explicit(!is_convertible_v) + mapping(const mapping&) noexcept; + template + constexpr explicit(@\seebelow@) + mapping(const layout_left::mapping&) noexcept; + template + constexpr explicit(extents_type::rank() > 0) + mapping(const layout_stride::mapping&) noexcept; + + constexpr mapping& operator=(const mapping&) noexcept = default; + + // \ref{mdspan.layout.right.obs}, observers + constexpr const extents_type& extents() const noexcept { return @\exposid{extents_}@; } + + constexpr size_type required_span_size() const noexcept; + + template + constexpr size_type operator()(Indices...) const noexcept; + + static constexpr bool is_always_unique() noexcept { return true; } + static constexpr bool is_always_contiguous() noexcept { return true; } + static constexpr bool is_always_strided() noexcept { return true; } + + static constexpr bool is_unique() noexcept { return true; } + static constexpr bool is_contiguous() noexcept { return true; } + static constexpr bool is_strided() noexcept { return true; } + + constexpr size_type stride(rank_type) const noexcept; + + template + friend constexpr bool operator==(const mapping&, const mapping&) noexcept; + + private: + extents_type @\exposid{extents_}@{}; // \expos + }; +} +\end{codeblock} + +\pnum +If \tcode{Extents} is not a specialization of \tcode{extents}, +then the program is ill-formed. + +\pnum +\tcode{layout_right::mapping} is a trivially copyable type +that models \libconcept{regular} for each \tcode{E}. + +\rSec4[mdspan.layout.right.ctor]{Constructors} + +\indexlibraryctor{layout_right::mapping}% +\begin{itemdecl} +constexpr mapping(const extents_type& e) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +The size of the multidimensional index space \tcode{e} is representable as +a value of type \tcode{size_type}\iref{basic.fundamental}. + +\pnum +\effects +Direct-non-list-initializes \exposid{extents_} with \tcode{e}. +\end{itemdescr} + +\indexlibraryctor{layout_right::mapping}% +\begin{itemdecl} +template + constexpr explicit(!is_convertible_v) + mapping(const mapping& other) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_constructible_v} is \tcode{true}. + +\pnum +\expects +\tcode{other.required_span_size()} is representable as +a value of type \tcode{size_type}\iref{basic.fundamental}. + +\pnum +\effects +Direct-non-list-initializes \exposid{extents_} with \tcode{other.extents()}. +\end{itemdescr} + +\indexlibraryctor{layout_right::mapping}% +\begin{itemdecl} +template + constexpr explicit(!is_convertible_v) + mapping(const layout_left::mapping& other) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{extents_type::rank() <= 1} is \tcode{true}, and +\item +\tcode{is_constructible_v} is \tcode{true}. +\end{itemize} + +\pnum +\expects +\tcode{other.required_span_size()} is representable as +a value of type \tcode{size_type}\iref{basic.fundamental}. + +\pnum +\effects +Direct-non-list-initializes \exposid{extents_} with \tcode{other.extents()}. +\end{itemdescr} + +\indexlibraryctor{layout_right::mapping}% +\begin{itemdecl} +template + constexpr explicit(extents_type::rank() > 0) + mapping(const layout_stride::mapping& other) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_constructible_v} is \tcode{true}. + +\pnum +\expects +\begin{itemize} +\item +If \tcode{extents_type::rank() > 0} is \tcode{true}, +then for all $r$ in the range $[0, \tcode{extents_type::rank()})$, +\tcode{other.stride($r$)} equals +\tcode{extents().\exposid{rev-prod-of-extents}(r)}. +\item +\tcode{other.required_span_size()} is representable as +a value of type \tcode{size_type}\iref{basic.fundamental}. +\end{itemize} + +\pnum +\effects +Direct-non-list-initializes \exposid{extents_} with \tcode{other.extents()}. +\end{itemdescr} + +\rSec4[mdspan.layout.right.obs]{Observers} + +\indexlibrarymember{required_span_size}{layout_right::mapping}% +\begin{itemdecl} +size_type required_span_size() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{extents().\exposid{fwd-prod-of-extents}(extents_type::rank())}. +\end{itemdescr} + +\indexlibrarymember{operator()}{layout_right::mapping}% +\begin{itemdecl} +template + constexpr size_type operator()(Indices... i) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{sizeof...(Indices) == extents_type::rank()} is \tcode{true}, +\item +\tcode{(is_convertible_v \&\& ...)} is \tcode{true}, and +\item +\tcode{(is_nothrow_constructible_v \&\& ...)} is +\tcode{true}. +\end{itemize} + +\pnum +\expects +\tcode{extents_type::\exposid{index-cast}(i)} is +a multidimensional index in \exposid{extents_}\iref{mdspan.overview}. + +\pnum +\effects +Let \tcode{P} be a parameter pack such that +\begin{codeblock} +is_same_v, index_sequence> +\end{codeblock} +is \tcode{true}. Equivalent to: +\begin{codeblock} +return ((static_cast(i) * stride(P)) + ... + 0); +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{stride}{layout_right::mapping}% +\begin{itemdecl} +constexpr size_type stride(rank_type i) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{extents_type::rank() > 0} is \tcode{true}. + +\pnum +\expects +\tcode{i < extents_type::rank()} is \tcode{true}. + +\pnum +\returns +\tcode{extents().\exposid{rev-prod-of-extents}(i)}. +\end{itemdescr} + +\indexlibrarymember{operator==}{layout_right::mapping}% +\begin{itemdecl} +template + friend constexpr bool operator==(const mapping& x, const mapping& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{extents_type::rank() == OtherExtents::rank()} is \tcode{true}. + +\pnum +\effects +Equivalent to: \tcode{return x.extents() == y.extents();} +\end{itemdescr} + +\rSec3[mdspan.layout.stride]{Class template \tcode{layout_stride::mapping}} + +\rSec4[mdspan.layout.stride.overview]{Overview} + +\pnum +\tcode{layout_stride} provides a layout mapping +where the strides are user-defined. + +\begin{codeblock} +namespace std { + template + class layout_stride::mapping { + public: + using extents_type = Extents; + using size_type = typename extents_type::size_type; + using rank_type = typename extents_type::rank_type; + using layout_type = layout_stride; + + private: + static constexpr rank_type @\exposid{rank_}@ = extents_type::rank(); // \expos + + public: + // \ref{mdspan.layout.stride.ctor}, constructors + constexpr mapping() noexcept = default; + constexpr mapping(const mapping&) noexcept = default; + template + constexpr mapping(const extents_type&, span) noexcept; + template + constexpr mapping(const extents_type&, const array&) noexcept; + + template + constexpr explicit(@\seebelow@) mapping(const StridedLayoutMapping&) noexcept; + + constexpr mapping& operator=(const mapping&) noexcept = default; + + // \ref{mdspan.layout.stride.obs}, observers + constexpr const extents_type& extents() const noexcept { return @\exposid{extents_}@; } + constexpr array strides() const noexcept { return @\exposid{strides_}@; } + + constexpr size_type required_span_size() const noexcept; + + template + constexpr size_type operator()(Indices...) const noexcept; + + static constexpr bool is_always_unique() noexcept { return true; } + static constexpr bool is_always_contiguous() noexcept { return false; } + static constexpr bool is_always_strided() noexcept { return true; } + + static constexpr bool is_unique() noexcept { return true; } + constexpr bool is_contiguous() const noexcept; + static constexpr bool is_strided() noexcept { return true; } + + constexpr size_type stride(rank_type i) const noexcept { return @\exposid{strides_}@[i]; } + + template + friend constexpr bool operator==(const mapping&, const OtherMapping&) noexcept; + + private: + extents_type @\exposid{extents_}@{}; // \expos + array @\exposid{strides_}@{}; // \expos + }; +} +\end{codeblock} + +\pnum +If \tcode{Extents} is not a specialization of \tcode{extents}, +then the program is ill-formed. + +\pnum +\tcode{layout_stride::mapping} is a trivially copyable type +that models \libconcept{regular} for each \tcode{E}. + +\rSec4[mdspan.layout.stride.expo]{Exposition-only helpers} + +\pnum +Let \tcode{\exposid{REQUIRED-SPAN-SIZE}(e, strides)} be: +\begin{itemize} +\item +\tcode{1}, if \tcode{e.rank() == 0} is \tcode{true}, otherwise +\item +\tcode{0}, if the size of the multidimensional index space \tcode{e} is 0, otherwise +\item +\tcode{1} plus the sum of products of \tcode{(e.extent($r$) - 1)} and \tcode{strides[$r$]} +for all $r$ in the range $[0, \tcode{e.rank()})$. +\end{itemize} + +\pnum +Let \tcode{\exposid{OFFSET}(m)} be: +\begin{itemize} +\item +\tcode{m()}, if \tcode{e.rank() == 0} is \tcode{true}, otherwise +\item +\tcode{0}, if the size of the multidimensional index space \tcode{e} is 0, otherwise +\item +\tcode{m(z...)} for a pack of integers \tcode{z} +that is a multidimensional index in \tcode{m.extents()} and +each element of \tcode{z} equals 0. +\end{itemize} + +\pnum +Let \exposid{is-extents} be the exposition-only variable template +defined as follows: +\begin{codeblock} +template + constexpr bool @\exposid{is-extents}@ = false; // \expos +template + constexpr bool @\exposid{is-extents}@> = true; // \expos +\end{codeblock} + +\pnum +Let \exposconcept{layout-mapping-alike} be the exposition-only concept +defined as follows: +\begin{codeblock} +template +concept @\defexposconcept{layout-mapping-alike}@ = requires { // \expos + requires @\exposid{is-extents}@; + { M::is_always_strided() } -> same_as; + { M::is_always_contiguous() } -> same_as; + { M::is_always_unique() } -> same_as; + bool_constant::value; + bool_constant::value; + bool_constant::value; +}; +\end{codeblock} +\begin{note} +This concept checks that the functions +\tcode{M::is_always_strided()}, +\tcode{M::is_always_contiguous()}, and +\tcode{M::is_always_unique()} exist, +are constant expressions, and +have a return type of \tcode{bool}. +\end{note} + +\rSec4[mdspan.layout.stride.ctor]{Constructors} + +\indexlibraryctor{layout_stride::mapping}% +\begin{itemdecl} +template + constexpr mapping(const extents_type& e, span s) noexcept; +template + constexpr mapping(const extents_type& e, const array& s) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{is_convertible_v} is \tcode{true}, and +\item +\tcode{is_nothrow_constructible_v} is \tcode{true}. +\end{itemize} + +\pnum +\expects +\begin{itemize} +\item +\tcode{s[$i$] > 0} is \tcode{true} +for all $i$ in the range $[0, \exposid{rank_})$. +\item +\tcode{\exposid{REQUIRED-SPAN-SIZE}(e, s)} is representable +as a value of type \tcode{size_type}\iref{basic.fundamental}. +\item +If \exposid{rank_} is greater than 0, +then there exists a permutation $P$ of the integers +in the range $[0, \exposid{rank_})$, +such that \tcode{s[$p_i$] >= s[$p_{i-1}$] * e.extent(p$_{i-1}$)} is \tcode{true} +for all $i$ in the range $[1, \exposid{rank_})$, +where $p_i$ is the $i^\text{th}$ element of $P$. +\begin{note} +For \tcode{layout_stride}, +this condition is necessary and sufficient +for \tcode{is_unique()} to be \tcode{true}. +\end{note} +\end{itemize} + +\pnum +\effects +Direct-non-list-initializes \exposid{extents_} with \tcode{e}, and +for all $d$ in the range $[0, \exposid{rank_})$, +direct-non-list-initializes \tcode{strides_[$d$]} with \tcode{as_const(s[$d$])}. +\end{itemdescr} + +\indexlibraryctor{layout_stride::mapping}% +\begin{itemdecl} +template + constexpr explicit(@\seebelow@) + mapping(const StridedLayoutMapping& other) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{\exposconcept{layout-mapping-alike}} is satisfied. +\item +\tcode{is_constructible_v} is\\\tcode{true}. +\item +\tcode{StridedLayoutMapping::is_always_unique()} is \tcode{true}. +\item +\tcode{StridedLayoutMapping::is_always_strided()} is \tcode{true}. +\end{itemize} + +\pnum +\expects +\begin{itemize} +\item +\tcode{StridedLayoutMapping} meets the layout mapping requirements, +\item +\tcode{other.stride($r$) > 0} is \tcode{true} +for every rank index $r$ of \tcode{extents()}, +\item +\tcode{other.required_span_size()} is representable as +a value of type \tcode{size_type}\iref{basic.fundamental}, and +\item +\tcode{\exposid{OFFSET}(other) == 0} is \tcode{true}. +\end{itemize} + +\pnum +\effects +Direct-non-list-initializes \exposid{extents_} with \tcode{other.extents()}, and +for all $d$ in the range $[0, \exposid{rank_})$, +direct-non-list-initializes \tcode{\exposid{strides_}[$d$]} +with \tcode{other.stride($d$)}. + +\pnum +Remarks: The expression inside \tcode{explicit} is equivalent to: +\begin{codeblock} +!(is_convertible_v && + (@\exposid{is-mapping-of}@ || + @\exposid{is-mapping-of}@ || + @\exposid{is-mapping-of}@)) +\end{codeblock} +\end{itemdescr} + +\rSec4[mdspan.layout.stride.obs]{Observers} + +\indexlibrarymember{required_span_size}{layout_stride::mapping}% +\begin{itemdecl} +constexpr size_type required_span_size() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{\exposid{REQUIRED-SPAN-SIZE}(extents(), \exposid{strides_})}. +\end{itemdescr} + +\indexlibrarymember{operator()}{layout_stride::mapping}% +\begin{itemdecl} +template + constexpr size_type operator()(Indices... i) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{sizeof...(Indices) == \exposid{rank_}} is \tcode{true}, +\item +\tcode{(is_convertible_v \&\& ...)} is \tcode{true}, and +\item +\tcode{(is_nothrow_constructible_v \&\& ...)} is \tcode{true}. +\end{itemize} + +\pnum +\expects +\tcode{extents_type::\exposid{index-cast}(i)} is +a multidimensional index in \exposid{extents_}\iref{mdspan.overview}. + +\pnum +\effects +Let \tcode{P} be a parameter pack such that +\begin{codeblock} +is_same_v, index_sequence> +\end{codeblock} +is \tcode{true}. +Equivalent to: +\begin{codeblock} +return ((static_cast(i) * stride(P)) + ... + 0); +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{is_contiguous}{layout_stride::mapping}% +\begin{itemdecl} +constexpr bool is_contiguous() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\begin{itemize} +\item +\tcode{true} if \exposid{rank_} is 0. +\item +Otherwise, \tcode{true} if there is +a permutation $P$ of the integers in the range $[0, \exposid{rank_})$ +such that \tcode{stride($p_0$)} equals 1, and +\tcode{stride($p_i$)} equals \tcode{stride($ p_{i-1}$) * extents().extent($p_{i-1}$)} +for $i$ in the range $[1, \exposid{rank_})$, +where $p_i$ is the $i^\text{th}$ element of $P$. +\item +Otherwise, \tcode{false}. +\end{itemize} +\end{itemdescr} + +\indexlibrarymember{operator==}{layout_stride::mapping}% +\begin{itemdecl} +template + friend constexpr bool operator==(const mapping& x, const OtherMapping& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{\exposconcept{layout-mapping-alike}} is satisfied. +\item +\tcode{\exposid{rank_} == OtherMapping::extents_type::rank()} is \tcode{true}. +\item +\tcode{OtherMapping::is_always_strided()} is \tcode{true}. +\end{itemize} + +\pnum +\expects +\tcode{OtherMapping} meets the layout mapping requirements. + +\pnum +\returns +\tcode{true} if \tcode{x.extents() == y.extents()} is \tcode{true}, +\tcode{\exposid{OFFSET}(y) == 0} is \tcode{true}, and +each of \tcode{x.stride($r$) == y.stride($r$)} is \tcode{true} +for $r$ in the range $[0, \tcode{x.extents.rank()})$. +Otherwise, \tcode{false}. +\end{itemdescr} + +\rSec2[mdspan.accessor]{Accessor policy} + +\rSec3[mdspan.accessor.general]{General} + +\pnum +An \defn{accessor policy} defines types and operations by which +a reference to a single object is created +from an abstract data handle to a number of such objects and an index. + +\pnum +A range of indices $[0, N)$ is an \defnadj{accessible}{range} of +a given data handle and an accessor +if, for each $i$ in the range, +the accessor policy's \tcode{access} function produces a valid reference to an object. + +\pnum +In subclause \ref{mdspan.accessor.reqmts}, + +\begin{itemize} +\item +\tcode{A} denotes an accessor policy. +\item +\tcode{a} denotes a value of type \tcode{A} or \tcode{const A}. +\item +\tcode{p} denotes a value of type \tcode{A::pointer} or \tcode{const A::pointer}. +\begin{note} +The type \tcode{A::pointer} need not be dereferenceable. +\end{note} +\item +\tcode{n}, \tcode{i}, and \tcode{j} each denote values of type \tcode{size_t}. +\end{itemize} + +\rSec3[mdspan.accessor.reqmts]{Requirements} + +\pnum +A type \tcode{A} meets the accessor policy requirements if +\begin{itemize} +\item +\tcode{A} models \libconcept{copyable}, +\item +\tcode{is_nothrow_move_constructible_v} is \tcode{true}, +\item +\tcode{is_nothrow_move_assignable_v} is \tcode{true}, +\item +\tcode{is_nothrow_swappable_v} is \tcode{true}, and +\item +the following types and expressions +are well-formed and have the specified semantics. +\end{itemize} + +\begin{itemdecl} +typename A::element_type +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +A complete object type that is not an abstract class type. +\end{itemdescr} + +\begin{itemdecl} +typename A::pointer +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +A type that models \libconcept{copyable}, and +for which \tcode{is_nothrow_move_constructible_v} is \tcode{true}, +\tcode{is_nothrow_move_assignable_v} is \tcode{true}, and +\tcode{is_nothrow_swappable_v} is \tcode{true}. +\begin{note} +The type of \tcode{pointer} need not be \tcode{element_type*}. +\end{note} +\end{itemdescr} + +\begin{itemdecl} +typename A::reference +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +A type that models +\tcode{\libconcept{common_reference_with}}. +\begin{note} +The type of \tcode{reference} need not be \tcode{element_type\&}. +\end{note} +\end{itemdescr} + +\begin{itemdecl} +typename A::offset_policy +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +A type \tcode{OP} such that: + +\begin{itemize} +\item +\tcode{OP} meets the accessor policy requirements, +\item +\tcode{\libconcept{constructible_from}} is modeled, and +\item +\tcode{is_same_v} is \tcode{true}. +\end{itemize} +\end{itemdescr} + +\begin{itemdecl} +a.access(p, i) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{A::reference} + +\pnum +\remarks +The expression is equality preserving. + +\pnum +\begin{note} +Concrete accessor policies can impose preconditions for their \tcode{access} function. +However, they might not. +For example, an accessor where +\tcode{p} is \tcode{span} and +\tcode{access(p, i)} returns \tcode{p[i \% p.size()]} +does not need to impose a precondition on \tcode{i}. +\end{note} +\end{itemdescr} + +\begin{itemdecl} +a.offset(p, i) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{A::offset_policy::pointer} + +\pnum +\returns +\tcode{q} such that for \tcode{b} being \tcode{A::offset_policy(a)}, and +any integer \tcode{n} for which $[0, \tcode{n})$ is +an accessible range of \tcode{p} and \tcode{a}: +\begin{itemize} +\item +$[0, \tcode{n} - \tcode{i})$ is an accessible range of \tcode{q} and \tcode{b}; and +\item +\tcode{b.access(q, j)} provides access to +the same element as \tcode{a.access(p, i + j)}, +for every \tcode{j} in the range $[0, \tcode{n} - \tcode{i})$. +\end{itemize} + +\pnum +\remarks +The expression is equality-preserving. +\end{itemdescr} + +\rSec3[mdspan.accessor.default]{Class template \tcode{default_accessor}} + +\rSec4[mdspan.accessor.default.overview]{Overview} + +\begin{codeblock} +namespace std { + template + struct default_accessor { + using offset_policy = default_accessor; + using element_type = ElementType; + using reference = ElementType&; + using pointer = ElementType*; + + constexpr default_accessor() noexcept = default; + template + constexpr default_accessor(default_accessor) noexcept; + constexpr reference access(pointer p, size_t i) const noexcept; + constexpr pointer offset(pointer p, size_t i) const noexcept; + }; +} +\end{codeblock} + +\pnum +\tcode{default_accessor} meets the accessor policy requirements. + +\pnum +\tcode{ElementType} is required to be a complete object type +that is neither an abstract class type nor an array type. + +\pnum +Each specialization of \tcode{default_accessor} is +a trivially copyable type that models \libconcept{semiregular}. + +\pnum +$[0, n)$ is an accessible range for +an object \tcode{p} of type \tcode{pointer} and +an object of type \tcode{default_accessor} +if and only if \range{p}{p + $n$} is a valid range. + +\rSec4[mdspan.accessor.default.members]{Members} + +\indexlibraryctor{default_accessor}% +\begin{itemdecl} +template + constexpr default_accessor(default_accessor) noexcept {} +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_convertible_v} +is \tcode{true}. +\end{itemdescr} + +\indexlibrarymember{access}{default_accessor}% +\begin{itemdecl} +constexpr reference access(pointer p, size_t i) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return p[i];} +\end{itemdescr} + +\indexlibrarymember{offset}{default_accessor}% +\begin{itemdecl} +constexpr pointer offset(pointer p, size_t i) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Euivalent to: \tcode{return p + i;} +\end{itemdescr} + +\rSec2[mdspan.mdspan]{Class template \tcode{mdspan}} + +\rSec3[mdspan.mdspan.overview]{Overview} + +\pnum +\tcode{mdspan} is a view of a multidimensional array of elements. + +\begin{codeblock} +namespace std { + template + class mdspan { + public: + using extents_type = Extents; + using layout_type = LayoutPolicy; + using accessor_type = AccessorPolicy; + using mapping_type = typename layout_type::template mapping; + using element_type = ElementType; + using value_type = remove_cv_t; + using size_type = typename extents_type::size_type; + using rank_type = typename extents_type::rank_type; + using pointer = typename accessor_type::pointer; + using reference = typename accessor_type::reference; + + static constexpr rank_type rank() noexcept { return extents_type::rank(); } + static constexpr rank_type rank_dynamic() noexcept { return extents_type::rank_dynamic(); } + static constexpr size_t static_extent(rank_type r) noexcept + { return extents_type::static_extent(r); } + constexpr size_type extent(rank_type r) const noexcept { return extents().extent(r); } + + // \ref{mdspan.mdspan.ctor}, constructors + constexpr mdspan(); + constexpr mdspan(const mdspan& rhs) = default; + constexpr mdspan(mdspan&& rhs) = default; + + template + constexpr explicit mdspan(pointer ptr, OtherSizeTypes... exts); + template + constexpr explicit(N != rank_dynamic()) mdspan(pointer p, span exts); + template + constexpr explicit(N != rank_dynamic()) + mdspan(pointer p, const array& exts); + constexpr mdspan(pointer p, const extents_type& ext); + constexpr mdspan(pointer p, const mapping_type& m); + constexpr mdspan(pointer p, const mapping_type& m, const accessor_type& a); + + template + constexpr explicit(@\seebelow@) + mdspan(const mdspan& other); + + constexpr mdspan& operator=(const mdspan& rhs) = default; + constexpr mdspan& operator=(mdspan&& rhs) = default; + + // \ref{mdspan.mdspan.members}, members + template + constexpr reference operator[](OtherSizeTypes... indices) const; + template + constexpr reference operator[](span indices) const; + template + constexpr reference operator[](const array& indices) const; + + constexpr size_t size() const noexcept; + + friend constexpr void swap(mdspan& x, mdspan& y) noexcept; + + constexpr const extents_type& extents() const noexcept { return @\exposid{map_}@.extents(); } + constexpr const pointer& data() const noexcept { return @\exposid{ptr_}@; } + constexpr const mapping_type& mapping() const noexcept { return @\exposid{map_}@; } + constexpr const accessor_type& accessor() const noexcept { return @\exposid{acc_}@; } + + static constexpr bool is_always_unique() + { return mapping_type::is_always_unique(); } + static constexpr bool is_always_contiguous() + { return mapping_type::is_always_contiguous(); } + static constexpr bool is_always_strided() + { return mapping_type::is_always_strided(); } + + constexpr bool is_unique() const + { return @\exposid{map_}@.is_unique(); } + constexpr bool is_contiguous() const + { return @\exposid{map_}@.is_contiguous(); } + constexpr bool is_strided() const + { return @\exposid{map_.}@is_strided(); } + constexpr size_type stride(rank_type r) const + { return @\exposid{map_}@.stride(r); } + + private: + accessor_type @\exposid{acc_}@; // \expos + mapping_type @\exposid{map_}@; // \expos + pointer @\exposid{ptr_}@; // \expos + }; + + template + requires(is_array_v && rank_v == 1) + mdspan(CArray&) + -> mdspan, extents>>; + + template + requires(is_pointer_v>) + mdspan(Pointer&&) + -> mdspan>, extents>; + + template + requires((is_convertible_v && ...) && sizeof...(Integrals) > 0) + explicit mdspan(ElementType*, Integrals...) + -> mdspan>; + + template + mdspan(ElementType*, span) + -> mdspan>; + + template + mdspan(ElementType*, const array&) + -> mdspan>; + + template + mdspan(ElementType*, const extents&) + -> mdspan>; + + template + mdspan(ElementType*, const MappingType&) + -> mdspan; + + template + mdspan(const typename AccessorType::pointer&, const MappingType&, const AccessorType&) + -> mdspan; +} +\end{codeblock} + +\pnum +\mandates +\begin{itemize} +\item +\tcode{ElementType} is a complete object type +that is neither an abstract class type nor an array type, +\item +\tcode{Extents} is a specialization of \tcode{extents}, and +\item +\tcode{is_same_v} +is \tcode{true}. +\end{itemize} + +\pnum +\tcode{LayoutPolicy} shall meet +the layout mapping policy requirements\iref{mdspan.layout.policy.reqmts}, and +\tcode{AccessorPolicy} shall meet +the accessor policy requirements\iref{mdspan.accessor.reqmts}. + +\pnum +Each specialization \tcode{MDS} of \tcode{mdspan} models \libconcept{copyable} and +\begin{itemize} +\item +\tcode{is_nothrow_move_constructible_v} is \tcode{true}, +\item +\tcode{is_nothrow_move_assignable_v} is \tcode{true}, and +\item +\tcode{is_nothrow_swappable_v} is \tcode{true}. +\end{itemize} + +\pnum +A specialization of \tcode{mdspan} is a trivially copyable type if +its \tcode{accessor_type}, \tcode{mapping_type}, and \tcode{pointer} +are trivially copyable types. + +\rSec3[mdspan.mdspan.ctor]{Constructors} + +\indexlibraryctor{mdspan}% +\begin{itemdecl} +constexpr mdspan(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{rank_dynamic() > 0} is \tcode{true}. +\item +\tcode{is_default_constructible_v} is \tcode{true}. +\item +\tcode{is_default_constructible_v} is \tcode{true}. +\item +\tcode{is_default_constructible_v} is \tcode{true}. +\end{itemize} + +\pnum +\expects +$[0, \tcode{\exposid{map_}.required_span_size()})$ is +an accessible range of \exposid{ptr_} and \exposid{acc_} +for the values of \exposid{map_} and \exposid{acc_} +after the invocation of this constructor. + +\pnum +\effects +Value-initializes \exposid{ptr_}, \exposid{map_}, and \exposid{acc_}. +\end{itemdescr} + +\indexlibraryctor{mdspan}% +\begin{itemdecl} +template + constexpr explicit mdspan(pointer p, OtherSizeTypes... exts); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{N} be \tcode{sizeof...(OtherSizeTypes)}. + +\pnum +\constraints +\begin{itemize} +\item +\tcode{(is_convertible_v \&\& ...)} is \tcode{true}, +\item +\tcode{(is_nothrow_constructible \&\& ...)} is \tcode{true}, +\item +\tcode{N == rank() || N == rank_dynamic()} is \tcode{true}, +\item +\tcode{is_constructible_v} is \tcode{true}, and +\item +\tcode{is_default_constructible_v} is \tcode{true}. +\end{itemize} + +\pnum +\expects +$[0, \tcode{\exposid{map_}.required_span_size()})$ is +an accessible range of \tcode{p} and \exposid{acc_} +for the values of \exposid{map_} and \exposid{acc_} +after the invocation of this constructor. + +\pnum +\effects +\begin{itemize} +\item +Direct-non-list-initializes \exposid{ptr_} with \tcode{std::move(p)}, +\item +direct-non-list-initializes \exposid{map_} with +\tcode{Extents(static_cast(std::move(exts))...)}, and +\item +value-initializes \exposid{acc_}. +\end{itemize} +\end{itemdescr} + +\indexlibraryctor{mdspan}% +\begin{itemdecl} +template + constexpr explicit(N != rank_dynamic()) + mdspan(pointer p, span exts); +template + constexpr explicit(N != rank_dynamic()) + mdspan(pointer p, const array& exts); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{is_convertible_v} is \tcode{true}, +\item +\tcode{(is_nothrow_constructible \&\& ...)} is \tcode{true}, +\item +\tcode{N == rank() || N == rank_dynamic()} is \tcode{true}, +\item +\tcode{is_constructible_v} is \tcode{true}, and +\item +\tcode{is_default_constructible_v} is \tcode{true}. +\end{itemize} + +\pnum +\expects +$[0, \tcode{\exposid{map_}.required_span_size()})$ is +an accessible range of \tcode{p} and \exposid{acc_} +for the values of \exposid{map_} and \exposid{acc_} +after the invocation of this constructor. + +\pnum +\effects +\begin{itemize} +\item +Direct-non-list-initializes \exposid{ptr_} with \tcode{std::move(p)}, +\item +direct-non-list-initializes \exposid{map_} with \tcode{extents_type(exts)}, and +\item +value-initializes \exposid{acc_}. +\end{itemize} +\end{itemdescr} + +\indexlibraryctor{mdspan}% +\begin{itemdecl} +constexpr mdspan(pointer p, const extents_type& ext); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{is_constructible_v} is \tcode{true}, and +\item +\tcode{is_default_constructible_v} is \tcode{true}. +\end{itemize} + +\pnum +\expects +$[0, \tcode{\exposid{map_}.required_span_size()})$ is +an accessible range of \tcode{p} and \exposid{acc_} +for the values of \exposid{map_} and \exposid{acc_} +after the invocation of this constructor. + +\pnum +\effects +\begin{itemize} +\item +Direct-non-list-initializes \exposid{ptr_} with \tcode{std::move(p)}, +\item +direct-non-list-initializes \exposid{map_} with \tcode{ext}, and +\item +value-initializes \exposid{acc_}. +\end{itemize} +\end{itemdescr} + +\indexlibraryctor{mdspan}% +\begin{itemdecl} +constexpr mdspan(pointer p, const mapping_type& m); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_default_constructible_v} is \tcode{true}. + +\pnum +\expects +$[0, \tcode{m.required_span_size()})$ is +an accessible range of \tcode{p} and \exposid{acc_} +for the value of \exposid{acc_} after the invocation of this constructor. + +\pnum +\effects +\begin{itemize} +\item +Direct-non-list-initializes \exposid{ptr_} with \tcode{std::move(p)}, +\item +direct-non-list-initializes \exposid{map_} with \tcode{m}, and +\item +value-initializes \exposid{acc_}. +\end{itemize} +\end{itemdescr} + +\indexlibraryctor{mdspan}% +\begin{itemdecl} +constexpr mdspan(pointer p, const mapping_type& m, const accessor_type& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +$[0, \tcode{m.required_span_size()})$ is +an accessible range of \tcode{p} and \tcode{a}. + +\pnum +\effects +\begin{itemize} +\item +Direct-non-list-initializes \exposid{ptr_} with \tcode{std::move(p)}, +\item +direct-non-list-initializes \exposid{map_} with \tcode{m}, and +\item +direct-non-list-initializes \exposid{acc_} with \tcode{a}. +\end{itemize} +\end{itemdescr} + +\indexlibraryctor{mdspan}% +\begin{itemdecl} +template + constexpr explicit(@\seebelow@) + mdspan(const mdspan& other); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{is_constructible_v\&>} +is \tcode{true}, and +\item +\tcode{is_constructible_v} is \tcode{true}. +\end{itemize} + +\pnum +\mandates +\begin{itemize} +\item +\tcode{is_constructible_v} is \tcode{true}, and +\item +\tcode{is_constructible_v} is \tcode{true}. +\end{itemize} + +\pnum +\expects +\begin{itemize} +\item +For each rank index \tcode{r} of \tcode{extents_type}, +\tcode{static_extent(r) == dynamic_extent || static_extent(r) == other.extent(r)} +is \tcode{true}. +\item +$[0, \tcode{\exposid{map_}.required_span_size()})$ is +an accessible range of \exposid{ptr_} and \exposid{acc_} +for values of \exposid{ptr_}, \exposid{map_}, and \exposid{acc_} +after the invocation of this constructor. +\end{itemize} + +\pnum +\effects +\begin{itemize} +\item +Direct-non-list-initializes \exposid{ptr_} with \tcode{other.\exposid{ptr_}}, +\item +direct-non-list-initializes \exposid{map_} with \tcode{other.\exposid{map_}}, and +\item +direct-non-list-initializes \exposid{acc_} with \tcode{other.\exposid{acc_}}. +\end{itemize} + +\pnum +\remarks +The expression inside \tcode{explicit} is equivalent to: +\begin{codeblock} +!is_convertible_v&, mapping_type> +|| !is_convertible_v +\end{codeblock} +\end{itemdescr} + +\rSec3[mdspan.mdspan.members]{Members} + +\indexlibrarymember{operator[]}{mdspan}% +\begin{itemdecl} +template + constexpr reference operator[](OtherSizeTypes... indices) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{(is_convertible_v \&\& ...)} is \tcode{true}, +\item +\tcode{(is_nothrow_constructible_v \&\& ...)} is \tcode{true}, and +\item +\tcode{sizeof...(OtherSizeTypes) == rank()} is \tcode{true}. +\end{itemize} + +\pnum +Let \tcode{I} be \tcode{extents_type::\exposid{index-cast}(std::move(indices))}. + +\pnum +\expects +\tcode{I} is a multidimensional index in \tcode{extents()}. +\begin{note} +This implies that +\tcode{\exposid{map_}(I) < \exposid{map_}.required_span_size()} +is \tcode{true}. +\end{note} + +\pnum +\effects +Equivalent to: +\begin{codeblock} +return @\exposid{acc_}@.access(@\exposid{ptr_}@, @\exposid{map_}@(static_cast(std::move(indices))...)); +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator[]}{mdspan}% +\begin{itemdecl} +template + constexpr reference operator[](span indices) const; +template + constexpr reference operator[](const array& indices) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{is_convertible_v} is \tcode{true}, and +\item +\tcode{is_nothrow_constructible_v} is \tcode{true}. +\end{itemize} + +\pnum +\effects +Let \tcode{P} be a parameter pack such that +\begin{codeblock} +is_same_v, index_sequence> +\end{codeblock} +is \tcode{true}. +Equivalent to: +\begin{codeblock} +return operator[](as_const(indices[P])...); +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{size}{mdspan}% +\begin{itemdecl} +constexpr size_t size() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +The size of the multidimensional index space \tcode{extents()} +is representable as a value of type \tcode{size_t}\iref{basic.fundamental}. + +\pnum +\returns +\tcode{extents().\exposid{fwd-prod-of-extents}(rank())}. +\end{itemdescr} + +\indexlibrarymember{swap}{mdspan}% +\begin{itemdecl} +friend constexpr void swap(mdspan& x, mdspan& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +swap(x.@\exposid{ptr_}@, y.@\exposid{ptr_}@); +swap(x.@\exposid{map_}@, y.@\exposid{map_}@); +swap(x.@\exposid{acc_}@, y.@\exposid{acc_}@); +\end{codeblock} +\end{itemdescr} diff --git a/source/lib-intro.tex b/source/lib-intro.tex index 4dbbdcd82b..291a48d786 100644 --- a/source/lib-intro.tex +++ b/source/lib-intro.tex @@ -1051,6 +1051,7 @@ \tcode{} \\ \tcode{} \\ \tcode{} \\ +\tcode{} \\ \tcode{} \\ \tcode{} \\ \tcode{} \\ diff --git a/source/support.tex b/source/support.tex index f3a481d2bd..2e34b6f0f3 100644 --- a/source/support.tex +++ b/source/support.tex @@ -654,6 +654,7 @@ #define @\defnlibxname{cpp_lib_map_try_emplace}@ 201411L // also in \libheader{map} #define @\defnlibxname{cpp_lib_math_constants}@ 201907L // also in \libheader{numbers} #define @\defnlibxname{cpp_lib_math_special_functions}@ 201603L // also in \libheader{cmath} +#define @\defnlibxname{cpp_lib_mdspan}@ 202207L // also in \libheader{mdspan} #define @\defnlibxname{cpp_lib_memory_resource}@ 201603L // also in \libheader{memory_resource} #define @\defnlibxname{cpp_lib_move_only_function}@ 202110L // also in \libheader{functional} #define @\defnlibxname{cpp_lib_node_extract}@ 201606L From 7fbd06369585112c2c349e0e3c6d231e351240fe Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 29 Jul 2022 08:58:44 +0200 Subject: [PATCH 182/430] P2599R2 index_type & size_type in mdspan --- source/containers.tex | 311 +++++++++++++++++++++--------------------- 1 file changed, 158 insertions(+), 153 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index d4b68e12aa..9c58effae5 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -15045,11 +15045,11 @@ \begin{codeblock} namespace std { // \ref{mdspan.extents}, class template \tcode{extents} - template + template class extents; // \ref{mdspan.extents.dextents}, alias template \tcode{dextents} - template + template using dextents = @\seebelow@; // \ref{mdspan.layout}, layout mapping @@ -15110,48 +15110,49 @@ \begin{codeblock} namespace std { - template + template class @\libglobal{extents}@ { public: - using size_type = SizeType; + using index_type = IndexType; + using size_type = make_unsigned_t; using rank_type = size_t; // \ref{mdspan.extents.obs}, observers of the multidimensional index space static constexpr rank_type rank() noexcept { return sizeof...(Extents); } static constexpr rank_type rank_dynamic() noexcept { return @\exposid{dynamic-index}@(rank()); } static constexpr size_t static_extent(rank_type) noexcept; - constexpr size_type extent(rank_type) const noexcept; + constexpr index_type extent(rank_type) const noexcept; // \ref{mdspan.extents.ctor}, constructors constexpr extents() noexcept = default; - template + template constexpr explicit(@\seebelow@) - extents(const extents&) noexcept; - template - constexpr explicit extents(OtherSizeTypes...) noexcept; - template + extents(const extents&) noexcept; + template + constexpr explicit extents(OtherIndexTypes...) noexcept; + template constexpr explicit(N != rank_dynamic()) - extents(span) noexcept; - template + extents(span) noexcept; + template constexpr explicit(N != rank_dynamic()) - extents(const array&) noexcept; + extents(const array&) noexcept; // \ref{mdspan.extents.cmp}, comparison operators - template + template friend constexpr bool operator==(const extents&, - const extents&) noexcept; + const extents&) noexcept; // \ref{mdspan.extents.expo}, exposition-only helpers constexpr size_t @\exposid{fwd-prod-of-extents}@(rank_type) const noexcept; // \expos constexpr size_t @\exposid{rev-prod-of-extents}@(rank_type) const noexcept; // \expos - template - static constexpr auto @\exposid{index-cast}@(OtherSizeType&&) noexcept; // \expos + template + static constexpr auto @\exposid{index-cast}@(OtherIndexType&&) noexcept; // \expos private: static constexpr rank_type @\exposid{dynamic-index}@(rank_type) noexcept; // \expos static constexpr rank_type @\exposid{dynamic-index-inv}@(rank_type) noexcept; // \expos - array @\exposid{dynamic-extents}@{}; // \expos + array @\exposid{dynamic-extents}@{}; // \expos }; template @@ -15164,10 +15165,10 @@ \mandates \begin{itemize} \item -\tcode{SizeType} is a signed or unsigned integer type, and +\tcode{IndexType} is a signed or unsigned integer type, and \item each element of \tcode{Extents} is either equal to \tcode{dynamic_extent}, or -is representable as a value of type \tcode{SizeType}. +is representable as a value of type \tcode{IndexType}. \end{itemize} \pnum @@ -15251,8 +15252,8 @@ \end{itemdescr} \begin{itemdecl} -template - static constexpr auto @\exposid{index-cast}@(OtherSizeType&& i) noexcept; +template + static constexpr auto @\exposid{index-cast}@(OtherIndexType&& i) noexcept; \end{itemdecl} \begin{itemdescr} @@ -15260,15 +15261,15 @@ \effects \begin{itemize} \item -If \tcode{OtherSizeType} is an integral type other than \tcode{bool}, +If \tcode{OtherIndexType} is an integral type other than \tcode{bool}, then equivalent to \tcode{return i;}, \item -otherwise, equivalent to \tcode{return static_cast(i);}. +otherwise, equivalent to \tcode{return static_cast(i);}. \end{itemize} \begin{note} This function will always return an integral type other than \tcode{bool}. Since this function's call sites are constrained on -convertibility of \tcode{OtherSizeType} to \tcode{size_type}, +convertibility of \tcode{OtherIndexType} to \tcode{index_type}, integer-class types can use the \tcode{static_cast} branch without loss of precision. \end{note} @@ -15278,9 +15279,9 @@ \indexlibraryctor{extents}% \begin{itemdecl} -template +template constexpr explicit(@\seebelow@) - extents(const extents& other) noexcept; + extents(const extents& other) noexcept; \end{itemdecl} \begin{itemdescr} @@ -15306,7 +15307,7 @@ \tcode{sizeof...(OtherExtents)} is zero, or \item \tcode{other.extent(r)} is representable as -a value of type \tcode{size_type} for every rank index \tcode{r} of \tcode{other}. +a value of type \tcode{index_type} for every rank index \tcode{r} of \tcode{other}. \end{itemize} \end{itemize} @@ -15319,25 +15320,25 @@ The expression inside \tcode{explicit} is equivalent to: \begin{codeblock} (((Extents != dynamic_extent) && (OtherExtents == dynamic_extent)) || ... ) || -(numeric_limits::max() < numeric_limits::max()) +(numeric_limits::max() < numeric_limits::max()) \end{codeblock} \end{itemdescr} \indexlibraryctor{extents}% \begin{itemdecl} -template - explicit constexpr extents(OtherSizeTypes... exts) noexcept; +template + explicit constexpr extents(OtherIndexTypes... exts) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \constraints -Let \tcode{N} be \tcode{sizeof...(OtherSizeTypes)}. +Let \tcode{N} be \tcode{sizeof...(OtherIndexTypes)}. \begin{itemize} \item -\tcode{(is_convertible_v \&\& ...)} is \tcode{true}, +\tcode{(is_convertible_v \&\& ...)} is \tcode{true}, \item -\tcode{(is_nothrow_constructible_v \&\& ...)} is \tcode{true}, and +\tcode{(is_nothrow_constructible_v \&\& ...)} is \tcode{true}, and \item \tcode{N == rank_dynamic() || N == rank()} is \tcode{true}. \begin{note} @@ -15350,14 +15351,14 @@ \pnum Let \tcode{exts_arr} be \begin{codeblock} -array{static_cast(std::move(exts))...} +array{static_cast(std::move(exts))...} \end{codeblock} \pnum \expects \begin{itemize} \item -If \tcode{sizeof...(OtherSizeTypes) != rank_dynamic()} is \tcode{true}, +If \tcode{sizeof...(OtherIndexTypes) != rank_dynamic()} is \tcode{true}, \tcode{exts_arr[$r$]} equals $E_r$ for each $r$ for which $E_r$ is a static extent, and \item @@ -15367,7 +15368,7 @@ \tcode{sizeof...(exts) == 0} is \tcode{true}, or \item each element of \tcode{exts} is nonnegative and -is representable as a value of type \tcode{size_type}. +is representable as a value of type \tcode{index_type}. \end{itemize} \end{itemize} @@ -15378,12 +15379,12 @@ \indexlibraryctor{extents}% \begin{itemdecl} -template +template constexpr explicit(N != rank_dynamic()) - extents(span exts) noexcept; -template + extents(span exts) noexcept; +template constexpr explicit(N != rank_dynamic()) - extents(const array& exts) noexcept; + extents(const array& exts) noexcept; \end{itemdecl} \begin{itemdescr} @@ -15391,9 +15392,9 @@ \constraints \begin{itemize} \item -\tcode{is_convertible_v} is \tcode{true}, +\tcode{is_convertible_v} is \tcode{true}, \item -\tcode{is_nothrow_constructible_v} is \tcode{true}, and +\tcode{is_nothrow_constructible_v} is \tcode{true}, and \item \tcode{N == rank_dynamic() || N == rank()} is \tcode{true}. \end{itemize} @@ -15411,7 +15412,7 @@ \tcode{N} is zero, or \item \tcode{exts[r]} is nonnegative and -is representable as a value of type \tcode{size_type} for every rank index \tcode{r}. +is representable as a value of type \tcode{index_type} for every rank index \tcode{r}. \end{itemize} \end{itemize} @@ -15465,7 +15466,7 @@ \indexlibrarymember{extent}{extents}% \begin{itemdecl} -constexpr size_type extent(rank_type i) const noexcept; +constexpr index_type extent(rank_type i) const noexcept; \end{itemdecl} \begin{itemdescr} @@ -15482,9 +15483,9 @@ \indexlibrarymember{operator==}{extents}% \begin{itemdecl} -template +template friend constexpr bool operator==(const extents& lhs, - const extents& rhs) noexcept; + const extents& rhs) noexcept; \end{itemdecl} \begin{itemdescr} @@ -15500,7 +15501,7 @@ \indexlibraryglobal{dextents}% \begin{itemdecl} -template +template using dextents = @\seebelow@; \end{itemdecl} @@ -15509,7 +15510,7 @@ \result A type \tcode{E} that is a specialization of \tcode{extents} such that \tcode{E::rank() == Rank \&\& E::rank() == E::rank_dynamic()} is \tcode{true}, and -\tcode{E::size_type} denotes \tcode{SizeType}. +\tcode{E::index_type} denotes \tcode{IndexType}. \end{itemdescr} \rSec2[mdspan.layout]{Layout mapping} @@ -15582,13 +15583,13 @@ \end{itemdescr} \begin{itemdecl} -typename M::size_type +typename M::index_type \end{itemdecl} \begin{itemdescr} \pnum \result -\tcode{typename M::extents_type::size_type}. +\tcode{typename M::extents_type::index_type}. \end{itemdescr} \begin{itemdecl} @@ -15630,17 +15631,17 @@ \begin{itemdescr} \pnum \result -\tcode{typename M::size_type} +\tcode{typename M::index_type} \pnum \returns A nonnegative integer -less than \tcode{numeric_limits::max()} and +less than \tcode{numeric_limits::max()} and less than or equal to \tcode{numeric_limits::max()}. \end{itemdescr} \begin{itemdecl} -m(i...) == m(static_cast(i)...) +m(i...) == m(static_cast(i)...) \end{itemdecl} \begin{itemdescr} @@ -15660,7 +15661,7 @@ \begin{itemdescr} \pnum \result -\tcode{typename M::size_type} +\tcode{typename M::index_type} \pnum \returns @@ -15750,7 +15751,7 @@ \pnum \result -\tcode{typename M::size_type} +\tcode{typename M::index_type} \pnum \returns @@ -15866,6 +15867,7 @@ class layout_left::mapping { public: using extents_type = Extents; + using index_type = typename extents_type::index_type; using size_type = typename extents_type::size_type; using rank_type = typename extents_type::rank_type; using layout_type = layout_left; @@ -15889,10 +15891,10 @@ // \ref{mdspan.layout.left.obs}, observers constexpr const extents_type& extents() const noexcept { return @\exposid{extents_}@; } - constexpr size_type required_span_size() const noexcept; + constexpr index_type required_span_size() const noexcept; template - constexpr size_type operator()(Indices...) const noexcept; + constexpr index_type operator()(Indices...) const noexcept; static constexpr bool is_always_unique() noexcept { return true; } static constexpr bool is_always_contiguous() noexcept { return true; } @@ -15902,7 +15904,7 @@ static constexpr bool is_contiguous() noexcept { return true; } static constexpr bool is_strided() noexcept { return true; } - constexpr size_type stride(rank_type) const noexcept; + constexpr index_type stride(rank_type) const noexcept; template friend constexpr bool operator==(const mapping&, const mapping&) noexcept; @@ -15932,7 +15934,7 @@ \pnum \expects The size of the multidimensional index space \tcode{e} -is representable as a value of type \tcode{size_type}\iref{basic.fundamental}. +is representable as a value of type \tcode{index_type}\iref{basic.fundamental}. \pnum \effects @@ -15954,7 +15956,7 @@ \pnum \expects \tcode{other.required_span_size()} is representable as -a value of type \tcode{size_type}\iref{basic.fundamental}. +a value of type \tcode{index_type}\iref{basic.fundamental}. \pnum \effects @@ -15981,7 +15983,7 @@ \pnum \expects \tcode{other.required_span_size()} is representable as -a value of type \tcode{size_type}\iref{basic.fundamental}. +a value of type \tcode{index_type}\iref{basic.fundamental}. \pnum \effects @@ -16010,7 +16012,7 @@ \tcode{extents().\exposid{fwd-prod-of-extents}($r$)}, and \item \tcode{other.required_span_size()} is representable as -a value of type \tcode{size_type}\iref{basic.fundamental}. +a value of type \tcode{index_type}\iref{basic.fundamental}. \end{itemize} \pnum @@ -16022,7 +16024,7 @@ \indexlibrarymember{required_span_size}{layout_left::mapping}% \begin{itemdecl} -constexpr size_type required_span_size() const noexcept; +constexpr index_type required_span_size() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -16034,7 +16036,7 @@ \indexlibrarymember{operator()}{layout_left::mapping}% \begin{itemdecl} template - constexpr size_type operator()(Indices... i) const noexcept; + constexpr index_type operator()(Indices... i) const noexcept; \end{itemdecl} \begin{itemdescr} @@ -16044,9 +16046,9 @@ \item \tcode{sizeof...(Indices) == extents_type::rank()} is \tcode{true}, \item -\tcode{(is_convertible_v \&\& ...)} is \tcode{true}, and +\tcode{(is_convertible_v \&\& ...)} is \tcode{true}, and \item -\tcode{(is_nothrow_constructible_v \&\& ...)} is \tcode{true}. +\tcode{(is_nothrow_constructible_v \&\& ...)} is \tcode{true}. \end{itemize} \pnum @@ -16063,13 +16065,13 @@ is \tcode{true}. Equivalent to: \begin{codeblock} -return ((static_cast(i) * stride(P)) + ... + 0); +return ((static_cast(i) * stride(P)) + ... + 0); \end{codeblock} \end{itemdescr} \indexlibrarymember{stride}{layout_left::mapping}% \begin{itemdecl} -constexpr size_type stride(rank_type i) const; +constexpr index_type stride(rank_type i) const; \end{itemdecl} \begin{itemdescr} @@ -16117,6 +16119,7 @@ class layout_right::mapping { public: using extents_type = Extents; + using index_type = typename extents_type::index_type; using size_type = typename extents_type::size_type; using rank_type = typename extents_type::rank_type; using layout_type = layout_right; @@ -16140,10 +16143,10 @@ // \ref{mdspan.layout.right.obs}, observers constexpr const extents_type& extents() const noexcept { return @\exposid{extents_}@; } - constexpr size_type required_span_size() const noexcept; + constexpr index_type required_span_size() const noexcept; template - constexpr size_type operator()(Indices...) const noexcept; + constexpr index_type operator()(Indices...) const noexcept; static constexpr bool is_always_unique() noexcept { return true; } static constexpr bool is_always_contiguous() noexcept { return true; } @@ -16153,7 +16156,7 @@ static constexpr bool is_contiguous() noexcept { return true; } static constexpr bool is_strided() noexcept { return true; } - constexpr size_type stride(rank_type) const noexcept; + constexpr index_type stride(rank_type) const noexcept; template friend constexpr bool operator==(const mapping&, const mapping&) noexcept; @@ -16183,7 +16186,7 @@ \pnum \expects The size of the multidimensional index space \tcode{e} is representable as -a value of type \tcode{size_type}\iref{basic.fundamental}. +a value of type \tcode{index_type}\iref{basic.fundamental}. \pnum \effects @@ -16205,7 +16208,7 @@ \pnum \expects \tcode{other.required_span_size()} is representable as -a value of type \tcode{size_type}\iref{basic.fundamental}. +a value of type \tcode{index_type}\iref{basic.fundamental}. \pnum \effects @@ -16232,7 +16235,7 @@ \pnum \expects \tcode{other.required_span_size()} is representable as -a value of type \tcode{size_type}\iref{basic.fundamental}. +a value of type \tcode{index_type}\iref{basic.fundamental}. \pnum \effects @@ -16261,7 +16264,7 @@ \tcode{extents().\exposid{rev-prod-of-extents}(r)}. \item \tcode{other.required_span_size()} is representable as -a value of type \tcode{size_type}\iref{basic.fundamental}. +a value of type \tcode{index_type}\iref{basic.fundamental}. \end{itemize} \pnum @@ -16273,7 +16276,7 @@ \indexlibrarymember{required_span_size}{layout_right::mapping}% \begin{itemdecl} -size_type required_span_size() const noexcept; +index_type required_span_size() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -16285,7 +16288,7 @@ \indexlibrarymember{operator()}{layout_right::mapping}% \begin{itemdecl} template - constexpr size_type operator()(Indices... i) const noexcept; + constexpr index_type operator()(Indices... i) const noexcept; \end{itemdecl} \begin{itemdescr} @@ -16295,9 +16298,9 @@ \item \tcode{sizeof...(Indices) == extents_type::rank()} is \tcode{true}, \item -\tcode{(is_convertible_v \&\& ...)} is \tcode{true}, and +\tcode{(is_convertible_v \&\& ...)} is \tcode{true}, and \item -\tcode{(is_nothrow_constructible_v \&\& ...)} is +\tcode{(is_nothrow_constructible_v \&\& ...)} is \tcode{true}. \end{itemize} @@ -16314,13 +16317,13 @@ \end{codeblock} is \tcode{true}. Equivalent to: \begin{codeblock} -return ((static_cast(i) * stride(P)) + ... + 0); +return ((static_cast(i) * stride(P)) + ... + 0); \end{codeblock} \end{itemdescr} \indexlibrarymember{stride}{layout_right::mapping}% \begin{itemdecl} -constexpr size_type stride(rank_type i) const noexcept; +constexpr index_type stride(rank_type i) const noexcept; \end{itemdecl} \begin{itemdescr} @@ -16367,6 +16370,7 @@ class layout_stride::mapping { public: using extents_type = Extents; + using index_type = typename extents_type::index_type; using size_type = typename extents_type::size_type; using rank_type = typename extents_type::rank_type; using layout_type = layout_stride; @@ -16378,10 +16382,10 @@ // \ref{mdspan.layout.stride.ctor}, constructors constexpr mapping() noexcept = default; constexpr mapping(const mapping&) noexcept = default; - template - constexpr mapping(const extents_type&, span) noexcept; - template - constexpr mapping(const extents_type&, const array&) noexcept; + template + constexpr mapping(const extents_type&, span) noexcept; + template + constexpr mapping(const extents_type&, const array&) noexcept; template constexpr explicit(@\seebelow@) mapping(const StridedLayoutMapping&) noexcept; @@ -16390,12 +16394,12 @@ // \ref{mdspan.layout.stride.obs}, observers constexpr const extents_type& extents() const noexcept { return @\exposid{extents_}@; } - constexpr array strides() const noexcept { return @\exposid{strides_}@; } + constexpr array strides() const noexcept { return @\exposid{strides_}@; } - constexpr size_type required_span_size() const noexcept; + constexpr index_type required_span_size() const noexcept; template - constexpr size_type operator()(Indices...) const noexcept; + constexpr index_type operator()(Indices...) const noexcept; static constexpr bool is_always_unique() noexcept { return true; } static constexpr bool is_always_contiguous() noexcept { return false; } @@ -16405,14 +16409,14 @@ constexpr bool is_contiguous() const noexcept; static constexpr bool is_strided() noexcept { return true; } - constexpr size_type stride(rank_type i) const noexcept { return @\exposid{strides_}@[i]; } + constexpr index_type stride(rank_type i) const noexcept { return @\exposid{strides_}@[i]; } template friend constexpr bool operator==(const mapping&, const OtherMapping&) noexcept; private: extents_type @\exposid{extents_}@{}; // \expos - array @\exposid{strides_}@{}; // \expos + array @\exposid{strides_}@{}; // \expos }; } \end{codeblock} @@ -16459,7 +16463,7 @@ template constexpr bool @\exposid{is-extents}@ = false; // \expos template - constexpr bool @\exposid{is-extents}@> = true; // \expos + constexpr bool @\exposid{is-extents}@> = true; // \expos \end{codeblock} \pnum @@ -16490,10 +16494,10 @@ \indexlibraryctor{layout_stride::mapping}% \begin{itemdecl} -template - constexpr mapping(const extents_type& e, span s) noexcept; -template - constexpr mapping(const extents_type& e, const array& s) noexcept; +template + constexpr mapping(const extents_type& e, span s) noexcept; +template + constexpr mapping(const extents_type& e, const array& s) noexcept; \end{itemdecl} \begin{itemdescr} @@ -16501,9 +16505,9 @@ \constraints \begin{itemize} \item -\tcode{is_convertible_v} is \tcode{true}, and +\tcode{is_convertible_v} is \tcode{true}, and \item -\tcode{is_nothrow_constructible_v} is \tcode{true}. +\tcode{is_nothrow_constructible_v} is \tcode{true}. \end{itemize} \pnum @@ -16514,7 +16518,7 @@ for all $i$ in the range $[0, \exposid{rank_})$. \item \tcode{\exposid{REQUIRED-SPAN-SIZE}(e, s)} is representable -as a value of type \tcode{size_type}\iref{basic.fundamental}. +as a value of type \tcode{index_type}\iref{basic.fundamental}. \item If \exposid{rank_} is greater than 0, then there exists a permutation $P$ of the integers @@ -16567,7 +16571,7 @@ for every rank index $r$ of \tcode{extents()}, \item \tcode{other.required_span_size()} is representable as -a value of type \tcode{size_type}\iref{basic.fundamental}, and +a value of type \tcode{index_type}\iref{basic.fundamental}, and \item \tcode{\exposid{OFFSET}(other) == 0} is \tcode{true}. \end{itemize} @@ -16593,7 +16597,7 @@ \indexlibrarymember{required_span_size}{layout_stride::mapping}% \begin{itemdecl} -constexpr size_type required_span_size() const noexcept; +constexpr index_type required_span_size() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -16605,7 +16609,7 @@ \indexlibrarymember{operator()}{layout_stride::mapping}% \begin{itemdecl} template - constexpr size_type operator()(Indices... i) const noexcept; + constexpr index_type operator()(Indices... i) const noexcept; \end{itemdecl} \begin{itemdescr} @@ -16615,9 +16619,9 @@ \item \tcode{sizeof...(Indices) == \exposid{rank_}} is \tcode{true}, \item -\tcode{(is_convertible_v \&\& ...)} is \tcode{true}, and +\tcode{(is_convertible_v \&\& ...)} is \tcode{true}, and \item -\tcode{(is_nothrow_constructible_v \&\& ...)} is \tcode{true}. +\tcode{(is_nothrow_constructible_v \&\& ...)} is \tcode{true}. \end{itemize} \pnum @@ -16634,7 +16638,7 @@ is \tcode{true}. Equivalent to: \begin{codeblock} -return ((static_cast(i) * stride(P)) + ... + 0); +return ((static_cast(i) * stride(P)) + ... + 0); \end{codeblock} \end{itemdescr} @@ -16947,6 +16951,7 @@ using mapping_type = typename layout_type::template mapping; using element_type = ElementType; using value_type = remove_cv_t; + using index_type = typename extents_type::index_type; using size_type = typename extents_type::size_type; using rank_type = typename extents_type::rank_type; using pointer = typename accessor_type::pointer; @@ -16956,20 +16961,20 @@ static constexpr rank_type rank_dynamic() noexcept { return extents_type::rank_dynamic(); } static constexpr size_t static_extent(rank_type r) noexcept { return extents_type::static_extent(r); } - constexpr size_type extent(rank_type r) const noexcept { return extents().extent(r); } + constexpr index_type extent(rank_type r) const noexcept { return extents().extent(r); } // \ref{mdspan.mdspan.ctor}, constructors constexpr mdspan(); constexpr mdspan(const mdspan& rhs) = default; constexpr mdspan(mdspan&& rhs) = default; - template - constexpr explicit mdspan(pointer ptr, OtherSizeTypes... exts); - template - constexpr explicit(N != rank_dynamic()) mdspan(pointer p, span exts); - template + template + constexpr explicit mdspan(pointer ptr, OtherIndexTypes... exts); + template + constexpr explicit(N != rank_dynamic()) mdspan(pointer p, span exts); + template constexpr explicit(N != rank_dynamic()) - mdspan(pointer p, const array& exts); + mdspan(pointer p, const array& exts); constexpr mdspan(pointer p, const extents_type& ext); constexpr mdspan(pointer p, const mapping_type& m); constexpr mdspan(pointer p, const mapping_type& m, const accessor_type& a); @@ -16984,14 +16989,14 @@ constexpr mdspan& operator=(mdspan&& rhs) = default; // \ref{mdspan.mdspan.members}, members - template - constexpr reference operator[](OtherSizeTypes... indices) const; - template - constexpr reference operator[](span indices) const; - template - constexpr reference operator[](const array& indices) const; + template + constexpr reference operator[](OtherIndexTypes... indices) const; + template + constexpr reference operator[](span indices) const; + template + constexpr reference operator[](const array& indices) const; - constexpr size_t size() const noexcept; + constexpr size_type size() const noexcept; friend constexpr void swap(mdspan& x, mdspan& y) noexcept; @@ -17013,7 +17018,7 @@ { return @\exposid{map_}@.is_contiguous(); } constexpr bool is_strided() const { return @\exposid{map_.}@is_strided(); } - constexpr size_type stride(rank_type r) const + constexpr index_type stride(rank_type r) const { return @\exposid{map_}@.stride(r); } private: @@ -17037,17 +17042,17 @@ explicit mdspan(ElementType*, Integrals...) -> mdspan>; - template - mdspan(ElementType*, span) + template + mdspan(ElementType*, span) -> mdspan>; - template - mdspan(ElementType*, const array&) + template + mdspan(ElementType*, const array&) -> mdspan>; - template - mdspan(ElementType*, const extents&) - -> mdspan>; + template + mdspan(ElementType*, const extents&) + -> mdspan>; template mdspan(ElementType*, const MappingType&) @@ -17131,21 +17136,21 @@ \indexlibraryctor{mdspan}% \begin{itemdecl} -template - constexpr explicit mdspan(pointer p, OtherSizeTypes... exts); +template + constexpr explicit mdspan(pointer p, OtherIndexTypes... exts); \end{itemdecl} \begin{itemdescr} \pnum -Let \tcode{N} be \tcode{sizeof...(OtherSizeTypes)}. +Let \tcode{N} be \tcode{sizeof...(OtherIndexTypes)}. \pnum \constraints \begin{itemize} \item -\tcode{(is_convertible_v \&\& ...)} is \tcode{true}, +\tcode{(is_convertible_v \&\& ...)} is \tcode{true}, \item -\tcode{(is_nothrow_constructible \&\& ...)} is \tcode{true}, +\tcode{(is_nothrow_constructible \&\& ...)} is \tcode{true}, \item \tcode{N == rank() || N == rank_dynamic()} is \tcode{true}, \item @@ -17168,7 +17173,7 @@ Direct-non-list-initializes \exposid{ptr_} with \tcode{std::move(p)}, \item direct-non-list-initializes \exposid{map_} with -\tcode{Extents(static_cast(std::move(exts))...)}, and +\tcode{extents_type(static_cast(std::move(exts\brk{}))...)}, and \item value-initializes \exposid{acc_}. \end{itemize} @@ -17176,12 +17181,12 @@ \indexlibraryctor{mdspan}% \begin{itemdecl} -template +template constexpr explicit(N != rank_dynamic()) - mdspan(pointer p, span exts); -template + mdspan(pointer p, span exts); +template constexpr explicit(N != rank_dynamic()) - mdspan(pointer p, const array& exts); + mdspan(pointer p, const array& exts); \end{itemdecl} \begin{itemdescr} @@ -17189,9 +17194,9 @@ \constraints \begin{itemize} \item -\tcode{is_convertible_v} is \tcode{true}, +\tcode{is_convertible_v} is \tcode{true}, \item -\tcode{(is_nothrow_constructible \&\& ...)} is \tcode{true}, +\tcode{(is_nothrow_constructible \&\& ...)} is \tcode{true}, \item \tcode{N == rank() || N == rank_dynamic()} is \tcode{true}, \item @@ -17371,8 +17376,8 @@ \indexlibrarymember{operator[]}{mdspan}% \begin{itemdecl} -template - constexpr reference operator[](OtherSizeTypes... indices) const; +template + constexpr reference operator[](OtherIndexTypes... indices) const; \end{itemdecl} \begin{itemdescr} @@ -17380,11 +17385,11 @@ \constraints \begin{itemize} \item -\tcode{(is_convertible_v \&\& ...)} is \tcode{true}, +\tcode{(is_convertible_v \&\& ...)} is \tcode{true}, \item -\tcode{(is_nothrow_constructible_v \&\& ...)} is \tcode{true}, and +\tcode{(is_nothrow_constructible_v \&\& ...)} is \tcode{true}, and \item -\tcode{sizeof...(OtherSizeTypes) == rank()} is \tcode{true}. +\tcode{sizeof...(OtherIndexTypes) == rank()} is \tcode{true}. \end{itemize} \pnum @@ -17403,16 +17408,16 @@ \effects Equivalent to: \begin{codeblock} -return @\exposid{acc_}@.access(@\exposid{ptr_}@, @\exposid{map_}@(static_cast(std::move(indices))...)); +return @\exposid{acc_}@.access(@\exposid{ptr_}@, @\exposid{map_}@(static_cast(std::move(indices))...)); \end{codeblock} \end{itemdescr} \indexlibrarymember{operator[]}{mdspan}% \begin{itemdecl} -template - constexpr reference operator[](span indices) const; -template - constexpr reference operator[](const array& indices) const; +template + constexpr reference operator[](span indices) const; +template + constexpr reference operator[](const array& indices) const; \end{itemdecl} \begin{itemdescr} @@ -17420,9 +17425,9 @@ \constraints \begin{itemize} \item -\tcode{is_convertible_v} is \tcode{true}, and +\tcode{is_convertible_v} is \tcode{true}, and \item -\tcode{is_nothrow_constructible_v} is \tcode{true}. +\tcode{is_nothrow_constructible_v} is \tcode{true}. \end{itemize} \pnum @@ -17440,14 +17445,14 @@ \indexlibrarymember{size}{mdspan}% \begin{itemdecl} -constexpr size_t size() const noexcept; +constexpr size_type size() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \expects The size of the multidimensional index space \tcode{extents()} -is representable as a value of type \tcode{size_t}\iref{basic.fundamental}. +is representable as a value of type \tcode{size_type}\iref{basic.fundamental}. \pnum \returns From 165dc29bbd1d5f4cb138b957f2c264ba127a37e8 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 29 Jul 2022 09:23:37 +0200 Subject: [PATCH 183/430] P2604R0 mdspan: rename pointer and contiguous --- source/containers.tex | 87 ++++++++++++++++++++++--------------------- 1 file changed, 44 insertions(+), 43 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index 9c58effae5..d4d30cd466 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -15692,7 +15692,7 @@ \end{itemdescr} \begin{itemdecl} -m.is_contiguous() +m.is_exhaustive() \end{itemdecl} \begin{itemdescr} @@ -15708,7 +15708,7 @@ \begin{note} A mapping can return \tcode{false} even if the condition is met. For certain layouts, it is possibly not feasible to determine efficiently -whether the layout is contiguous. +whether the layout is exhaustive. \end{note} \end{itemdescr} @@ -15779,7 +15779,7 @@ \end{itemdescr} \begin{itemdecl} -M::is_always_contiguous() +M::is_always_exhaustive() \end{itemdecl} \begin{itemdescr} @@ -15789,12 +15789,12 @@ \pnum \returns -\tcode{true} only if \tcode{m.is_contiguous()} is \tcode{true} +\tcode{true} only if \tcode{m.is_exhaustive()} is \tcode{true} for all possible objects \tcode{m} of type \tcode{M}. \begin{note} A mapping can return \tcode{false} even if the above condition is met. For certain layout mappings, it is possibly not feasible to determine -whether every instance is contiguous. +whether every instance is exhaustive. \end{note} \end{itemdescr} @@ -15897,11 +15897,11 @@ constexpr index_type operator()(Indices...) const noexcept; static constexpr bool is_always_unique() noexcept { return true; } - static constexpr bool is_always_contiguous() noexcept { return true; } + static constexpr bool is_always_exhaustive() noexcept { return true; } static constexpr bool is_always_strided() noexcept { return true; } static constexpr bool is_unique() noexcept { return true; } - static constexpr bool is_contiguous() noexcept { return true; } + static constexpr bool is_exhaustive() noexcept { return true; } static constexpr bool is_strided() noexcept { return true; } constexpr index_type stride(rank_type) const noexcept; @@ -16149,11 +16149,11 @@ constexpr index_type operator()(Indices...) const noexcept; static constexpr bool is_always_unique() noexcept { return true; } - static constexpr bool is_always_contiguous() noexcept { return true; } + static constexpr bool is_always_exhaustive() noexcept { return true; } static constexpr bool is_always_strided() noexcept { return true; } static constexpr bool is_unique() noexcept { return true; } - static constexpr bool is_contiguous() noexcept { return true; } + static constexpr bool is_exhaustive() noexcept { return true; } static constexpr bool is_strided() noexcept { return true; } constexpr index_type stride(rank_type) const noexcept; @@ -16402,11 +16402,11 @@ constexpr index_type operator()(Indices...) const noexcept; static constexpr bool is_always_unique() noexcept { return true; } - static constexpr bool is_always_contiguous() noexcept { return false; } + static constexpr bool is_always_exhaustive() noexcept { return false; } static constexpr bool is_always_strided() noexcept { return true; } static constexpr bool is_unique() noexcept { return true; } - constexpr bool is_contiguous() const noexcept; + constexpr bool is_exhaustive() const noexcept; static constexpr bool is_strided() noexcept { return true; } constexpr index_type stride(rank_type i) const noexcept { return @\exposid{strides_}@[i]; } @@ -16474,17 +16474,17 @@ concept @\defexposconcept{layout-mapping-alike}@ = requires { // \expos requires @\exposid{is-extents}@; { M::is_always_strided() } -> same_as; - { M::is_always_contiguous() } -> same_as; + { M::is_always_exhaustive() } -> same_as; { M::is_always_unique() } -> same_as; bool_constant::value; - bool_constant::value; + bool_constant::value; bool_constant::value; }; \end{codeblock} \begin{note} This concept checks that the functions \tcode{M::is_always_strided()}, -\tcode{M::is_always_contiguous()}, and +\tcode{M::is_always_exhaustive()}, and \tcode{M::is_always_unique()} exist, are constant expressions, and have a return type of \tcode{bool}. @@ -16642,9 +16642,9 @@ \end{codeblock} \end{itemdescr} -\indexlibrarymember{is_contiguous}{layout_stride::mapping}% +\indexlibrarymember{is_exhaustive}{layout_stride::mapping}% \begin{itemdecl} -constexpr bool is_contiguous() const noexcept; +constexpr bool is_exhaustive() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -16720,9 +16720,9 @@ \item \tcode{a} denotes a value of type \tcode{A} or \tcode{const A}. \item -\tcode{p} denotes a value of type \tcode{A::pointer} or \tcode{const A::pointer}. +\tcode{p} denotes a value of type \tcode{A::data_handle_type} or \tcode{const A::data_handle_type}. \begin{note} -The type \tcode{A::pointer} need not be dereferenceable. +The type \tcode{A::data_handle_type} need not be dereferenceable. \end{note} \item \tcode{n}, \tcode{i}, and \tcode{j} each denote values of type \tcode{size_t}. @@ -16757,7 +16757,7 @@ \end{itemdescr} \begin{itemdecl} -typename A::pointer +typename A::data_handle_type \end{itemdecl} \begin{itemdescr} @@ -16765,10 +16765,10 @@ \result A type that models \libconcept{copyable}, and for which \tcode{is_nothrow_move_constructible_v} is \tcode{true}, -\tcode{is_nothrow_move_assignable_v} is \tcode{true}, and -\tcode{is_nothrow_swappable_v} is \tcode{true}. +\tcode{is_nothrow_move_assignable_v} is \tcode{true}, and +\tcode{is_nothrow_swappable_v} is \tcode{true}. \begin{note} -The type of \tcode{pointer} need not be \tcode{element_type*}. +The type of \tcode{data_handle_type} need not be \tcode{element_type*}. \end{note} \end{itemdescr} @@ -16836,7 +16836,7 @@ \begin{itemdescr} \pnum \result -\tcode{A::offset_policy::pointer} +\tcode{A::offset_policy::data_handle_type} \pnum \returns @@ -16868,13 +16868,13 @@ using offset_policy = default_accessor; using element_type = ElementType; using reference = ElementType&; - using pointer = ElementType*; + using data_handle_type = ElementType*; constexpr default_accessor() noexcept = default; template constexpr default_accessor(default_accessor) noexcept; - constexpr reference access(pointer p, size_t i) const noexcept; - constexpr pointer offset(pointer p, size_t i) const noexcept; + constexpr reference access(data_handle_type p, size_t i) const noexcept; + constexpr data_handle_type offset(data_handle_type p, size_t i) const noexcept; }; } \end{codeblock} @@ -16892,7 +16892,7 @@ \pnum $[0, n)$ is an accessible range for -an object \tcode{p} of type \tcode{pointer} and +an object \tcode{p} of type \tcode{data_handle_type} and an object of type \tcode{default_accessor} if and only if \range{p}{p + $n$} is a valid range. @@ -16913,7 +16913,7 @@ \indexlibrarymember{access}{default_accessor}% \begin{itemdecl} -constexpr reference access(pointer p, size_t i) const noexcept; +constexpr reference access(data_handle_type p, size_t i) const noexcept; \end{itemdecl} \begin{itemdescr} @@ -16924,7 +16924,7 @@ \indexlibrarymember{offset}{default_accessor}% \begin{itemdecl} -constexpr pointer offset(pointer p, size_t i) const noexcept; +constexpr data_handle_type offset(data_handle_type p, size_t i) const noexcept; \end{itemdecl} \begin{itemdescr} @@ -16954,7 +16954,7 @@ using index_type = typename extents_type::index_type; using size_type = typename extents_type::size_type; using rank_type = typename extents_type::rank_type; - using pointer = typename accessor_type::pointer; + using data_handle_type = typename accessor_type::data_handle_type; using reference = typename accessor_type::reference; static constexpr rank_type rank() noexcept { return extents_type::rank(); } @@ -17001,21 +17001,21 @@ friend constexpr void swap(mdspan& x, mdspan& y) noexcept; constexpr const extents_type& extents() const noexcept { return @\exposid{map_}@.extents(); } - constexpr const pointer& data() const noexcept { return @\exposid{ptr_}@; } + constexpr const data_handle_type& data_handle() const noexcept { return @\exposid{ptr_}@; } constexpr const mapping_type& mapping() const noexcept { return @\exposid{map_}@; } constexpr const accessor_type& accessor() const noexcept { return @\exposid{acc_}@; } static constexpr bool is_always_unique() { return mapping_type::is_always_unique(); } - static constexpr bool is_always_contiguous() - { return mapping_type::is_always_contiguous(); } + static constexpr bool is_always_exhaustive() + { return mapping_type::is_always_exhaustive(); } static constexpr bool is_always_strided() { return mapping_type::is_always_strided(); } constexpr bool is_unique() const { return @\exposid{map_}@.is_unique(); } - constexpr bool is_contiguous() const - { return @\exposid{map_}@.is_contiguous(); } + constexpr bool is_exhaustive() const + { return @\exposid{map_}@.is_exhaustive(); } constexpr bool is_strided() const { return @\exposid{map_.}@is_strided(); } constexpr index_type stride(rank_type r) const @@ -17024,7 +17024,7 @@ private: accessor_type @\exposid{acc_}@; // \expos mapping_type @\exposid{map_}@; // \expos - pointer @\exposid{ptr_}@; // \expos + data_handle_type @\exposid{ptr_}@; // \expos }; template @@ -17060,7 +17060,8 @@ typename MappingType::layout_type>; template - mdspan(const typename AccessorType::pointer&, const MappingType&, const AccessorType&) + mdspan(const typename AccessorType::data_handle_type&, const MappingType&, + const AccessorType&) -> mdspan; } @@ -17098,7 +17099,7 @@ \pnum A specialization of \tcode{mdspan} is a trivially copyable type if -its \tcode{accessor_type}, \tcode{mapping_type}, and \tcode{pointer} +its \tcode{accessor_type}, \tcode{mapping_type}, and \tcode{data_handle_type} are trivially copyable types. \rSec3[mdspan.mdspan.ctor]{Constructors} @@ -17115,7 +17116,7 @@ \item \tcode{rank_dynamic() > 0} is \tcode{true}. \item -\tcode{is_default_constructible_v} is \tcode{true}. +\tcode{is_default_constructible_v} is \tcode{true}. \item \tcode{is_default_constructible_v} is \tcode{true}. \item @@ -17226,7 +17227,7 @@ \indexlibraryctor{mdspan}% \begin{itemdecl} -constexpr mdspan(pointer p, const extents_type& ext); +constexpr mdspan(data_handle_type p, const extents_type& ext); \end{itemdecl} \begin{itemdescr} @@ -17260,7 +17261,7 @@ \indexlibraryctor{mdspan}% \begin{itemdecl} -constexpr mdspan(pointer p, const mapping_type& m); +constexpr mdspan(data_handle_type p, const mapping_type& m); \end{itemdecl} \begin{itemdescr} @@ -17288,7 +17289,7 @@ \indexlibraryctor{mdspan}% \begin{itemdecl} -constexpr mdspan(pointer p, const mapping_type& m, const accessor_type& a); +constexpr mdspan(data_handle_type p, const mapping_type& m, const accessor_type& a); \end{itemdecl} \begin{itemdescr} @@ -17333,7 +17334,7 @@ \mandates \begin{itemize} \item -\tcode{is_constructible_v} is \tcode{true}, and +\tcode{is_constructible_v} is\newline \tcode{true}, and \item \tcode{is_constructible_v} is \tcode{true}. \end{itemize} From 5fd55fb338e91809f6c4552bc60353983a42070a Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 29 Jul 2022 11:35:30 +0200 Subject: [PATCH 184/430] P2613R1 Add the missing empty to mdspan --- source/containers.tex | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/source/containers.tex b/source/containers.tex index d4d30cd466..380ddb2931 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -16997,6 +16997,7 @@ constexpr reference operator[](const array& indices) const; constexpr size_type size() const noexcept; + [[nodiscard]] constexpr bool empty() const noexcept; friend constexpr void swap(mdspan& x, mdspan& y) noexcept; @@ -17460,6 +17461,19 @@ \tcode{extents().\exposid{fwd-prod-of-extents}(rank())}. \end{itemdescr} +\indexlibrarymember{empty}{mdspan}% +\begin{itemdecl} +[[nodiscard]] constexpr bool empty() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} +if the size of the multidimensional index space \tcode{extents()} is 0, +otherwise \tcode{false}. +\end{itemdescr} + \indexlibrarymember{swap}{mdspan}% \begin{itemdecl} friend constexpr void swap(mdspan& x, mdspan& y) noexcept; From 5fbaa539298cea9bdb567f662bcaae05b8e527e1 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Mon, 11 Jul 2022 23:48:35 +0200 Subject: [PATCH 185/430] P0429R9 A Standard flat_map - Replaced "may" with "can" in notes. - Replace && in constraints with prose "and" to avoid overfull \hbox --- source/containers.tex | 1819 ++++++++++++++++++++++++++++++++++++++++- source/lib-intro.tex | 1 + source/support.tex | 1 + 3 files changed, 1807 insertions(+), 14 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index 380ddb2931..df9ecacc0f 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -26,11 +26,11 @@ \ref{unord} & Unordered associative containers & \tcode{}, \tcode{} \\ \rowsep \ref{container.adaptors} & Container adaptors & - \tcode{}, \tcode{} \\ \rowsep -\ref{views} & Views & \tcode{}, \tcode{} \\ + \tcode{}, \tcode{}, \tcode{} \\ \rowsep +\ref{views} & Views & + \tcode{}, \tcode{} \\ \end{libsumtab} - \rSec1[container.requirements]{Requirements}% \indextext{requirements!container} @@ -1237,7 +1237,7 @@ \tcode{vector}, \tcode{forward_list}, \tcode{list}, and \tcode{deque}. In addition, \tcode{array} is provided as a sequence container which provides limited sequence operations because it has a fixed number of elements. The library also provides container adaptors that -make it easy to construct abstract data types, such as \tcode{stack}s or \tcode{queue}s, out of +make it easy to construct abstract data types, such as \tcode{stack}s, \tcode{queue}s, \tcode{flat_map}s, or \tcode{flat_multimap}s, out of the basic sequence container kinds (or out of other kinds of sequence containers that the user defines). \pnum @@ -2518,6 +2518,11 @@ \tcode{map} and \tcode{multimap}. +The library also provides container adaptors +that make it easy to construct abstract data types, +such as \tcode{flat_map}s or \tcode{flat_multimap}s, +out of the basic sequence container kinds +(or out of other program-defined sequence containers). \pnum Each associative container is parameterized on @@ -12962,21 +12967,32 @@ \rSec2[container.adaptors.general]{In general} \pnum -The headers \libheader{queue} and \libheader{stack} define the container adaptors -\tcode{queue}, \tcode{priority_queue}, and \tcode{stack}. +The headers \libheader{queue}, \libheader{stack}, and \libheader{flat_map} define the container adaptors +\tcode{queue}, \tcode{priority_queue}, \tcode{stack}, and \tcode{flat_map}, respectively. \pnum -The container adaptors each take a \tcode{Container} template parameter, and each constructor takes -a \tcode{Container} reference argument. This container is copied into the \tcode{Container} member -of each adaptor. If the container takes an allocator, then a compatible allocator may be passed in +Each container adaptor takes +one or more template parameters +named \tcode{Container}, \tcode{KeyContainer}, or \tcode{MappedContainer} +that denote the types of containers that the container adaptor adapts. +Each container adaptor has at least one constructor +that takes a reference argument to one or more such template parameters. +For each constructor reference argument to a container \tcode{C}, +the constructor copies the container into the container adaptor. +If \tcode{C} takes an allocator, then a compatible allocator may be passed in to the adaptor's constructor. Otherwise, normal copy or move construction is used for the container argument. -The first template parameter \tcode{T} of the container adaptors +For the container adaptors +that take a single container template parameter \tcode{Container}, +the first template parameter \tcode{T} of the container adaptor shall denote the same type as \tcode{Container::value_type}. \pnum For container adaptors, no \tcode{swap} function throws an exception unless that -exception is thrown by the swap of the adaptor's \tcode{Container} or +exception is thrown by the swap of the adaptor's +\tcode{Container}, +\tcode{KeyContainer}, +\tcode{MappedContainer}, or \tcode{Compare} object (if any). \pnum @@ -12985,21 +13001,51 @@ if it has an \tcode{InputIterator} template parameter and a type that does not qualify as an input iterator is deduced for that parameter. +\pnum +For container adaptors that have them, +the \tcode{insert}, \tcode{emplace}, and \tcode{erase} members +affect the validity of iterators, references, and pointers +to the adaptor's container(s) in the same way that +the containers' respective +\tcode{insert}, \tcode{emplace}, and \tcode{erase} members do. +\begin{example} +A call to \tcode{flat_map::insert} +can invalidate all iterators to the \tcode{flat_map}. +\end{example} + \pnum A deduction guide for a container adaptor shall not participate in overload resolution if any of the following are true: \begin{itemize} \item It has an \tcode{InputIterator} template parameter and a type that does not qualify as an input iterator is deduced for that parameter. \item It has a \tcode{Compare} template parameter and a type that qualifies as an allocator is deduced for that parameter. -\item It has a \tcode{Container} template parameter and a type that qualifies as an allocator is deduced for that parameter. -\item It has no \tcode{Container} template parameter, and it has an \tcode{Allocator} template parameter, and a type that does not qualify as an allocator is deduced for that parameter. +\item It has a \tcode{Container}, \tcode{KeyContainer}, or \tcode{MappedContainer} template parameter and a type that qualifies as an allocator is deduced for that parameter. +\item It has no \tcode{Container}, \tcode{KeyContainer}, or \tcode{MappedContainer} template parameter, and it has an \tcode{Allocator} template parameter, and a type that does not qualify as an allocator is deduced for that parameter. \item It has both \tcode{Container} and \tcode{Allocator} template parameters, and \tcode{uses_allocator_v} is \tcode{false}. +\item It has both \tcode{KeyContainer} and \tcode{Allocator} template parameters, and +\tcode{uses_allocator_v} is \tcode{false}. +\item It has both \tcode{MappedContainer} and \tcode{Allocator} template parameters, and +\tcode{uses_allocator_v} is \tcode{false}. \end{itemize} \pnum The exposition-only alias template \exposid{iter-value-type} -defined in \ref{sequences.general} +defined in \ref{sequences.general} and +the exposition-only alias templates \exposid{iter-key-type} and \exposid{iter-mapped-type} +defined in \ref{associative.general} may appear in deduction guides for container adaptors. +\pnum +The following exposition-only alias templates may appear in deduction guides +for container adaptors: +\begin{codeblock} +template + using @\exposid{cont-key-type}@ = // \expos + remove_const_t; +template + using @\exposid{cont-mapped-type}@ = // \expos + typename Container::value_type::second_type; +\end{codeblock} + \rSec2[queue.syn]{Header \tcode{} synopsis} \indexheader{queue} @@ -13076,6 +13122,50 @@ } \end{codeblock} +\rSec2[flat.map.syn]{Header \tcode{} synopsis} + +\indexheader{flat_map}% +\begin{codeblock} +#include // see \ref{compare.syn} +#include // see \ref{initializer.list.syn} + + // \ref{flat.map}, class template \tcode{flat_map} + template, + class KeyContainer = vector, class MappedContainer = vector> + class flat_map; + + struct sorted_unique_t { explicit sorted_unique_t() = default; }; + inline constexpr sorted_unique_t sorted_unique{}; + + template + size_t erase_if(flat_map& c, Predicate pred); + + template + struct uses_allocator, + Allocator>; + + // \ref{flat.multimap}, class template \tcode{flat_multimap} + template, + class KeyContainer = vector, class MappedContainer = vector> + class flat_multimap; + + struct sorted_equivalent_t { explicit sorted_equivalent_t() = default; }; + inline constexpr sorted_equivalent_t sorted_equivalent{}; + + template + size_t erase_if(flat_multimap& c, + Predicate pred); + + template + struct uses_allocator, + Allocator>; +} +\end{codeblock} + \rSec2[queue]{Class template \tcode{queue}} \rSec3[queue.defn]{Definition} @@ -14296,6 +14386,1707 @@ As if by \tcode{x.swap(y)}. \end{itemdescr} +\rSec2[flat.map]{Class template \tcode{flat_map}} + +\rSec3[flat.map.overview]{Overview} + +\pnum +\indexlibraryglobal{flatmap}% +A \tcode{flat_map} is a container adaptor +that provides an associative container interface +that supports unique keys +(i.e., contains at most one of each key value) and +provides for fast retrieval of values of another type \tcode{T} +based on the keys. +\tcode{flat_map} supports iterators +that meet the \oldconcept{InputIterator} requirements and +model the +\libconcept{random_access_iterator} concept\iref{iterator.concept.random.access}. + +\pnum +A \tcode{flat_map} meets all of the requirements +of a container\iref{container.reqmts} and +of a reversible container\iref{container.rev.reqmts}, +plus the optional container requirements\iref{container.opt.reqmts}. +\tcode{flat_map} meets the requirements of +an associative container\iref{associative.reqmts}, +except that: +\begin{itemize} +\item +it does not meet the requirements related to node handles\iref{container.node}, +\item +it does not meet the requirements related to iterator invalidation, and +\item +the time complexity of the operations that insert or erase a single +element from the map is linear, including the ones that take an insertion +position iterator. +\end{itemize} +\begin{note} +A \tcode{flat_map} does not meet the additional requirements of +an allocator-aware container\iref{container.alloc.reqmts}. +\end{note} + +\pnum +A \tcode{flat_map} also provides most operations +described in \ref{associative.reqmts} for unique keys. +This means that a \tcode{flat_map} supports +the \tcode{a_uniq} operations in \ref{associative.reqmts}, +but not the \tcode{a_eq} operations. +For a \tcode{flat_map} +the \tcode{key_type} is \tcode{Key} and +the \tcode{value_type} is \tcode{pair}. + +\pnum +Descriptions are provided here only for operations on \tcode{flat_map} that +are not described in one of those sets of requirements or for operations where +there is additional semantic information. + +\pnum +A \tcode{flat_map} maintains the following invariants: +\begin{itemize} +\item +it contains the same number of keys and values; +\item +the keys are sorted with respect to the comparison object; and +\item +the value at offset \tcode{off} within the value container is +the value associated with the key at offset \tcode{off} +within the key container. +\end{itemize} + +\pnum +If any member function in \ref{flat.map.defn} exits via an exception +the invariants are restored. +\begin{note} +This can result in the \tcode{flat_map} being emptied. +\end{note} + +\pnum +Any sequence container\iref{sequence.reqmts} \tcode{C} +supporting \oldconcept{RandomAccessIterator} can be used +to instantiate \tcode{flat_map}, +as long as invocations of +member functions \tcode{C::size} and \tcode{C::max_size} do not exit via an exception. +In particular, \tcode{vector}\iref{vector} and \tcode{deque}\iref{deque} +can be used. +\begin{note} +\tcode{vector} is not a sequence container. +\end{note} + +\pnum +The program is ill-formed if +\tcode{Key} is not the same type as \tcode{KeyContainer::value_type} or +\tcode{T} is not the same type as \tcode{MappedContainer::value_type}. + +\pnum +The effect of calling a constructor +that takes +both \tcode{key_container_type} and \tcode{mapped_container_type} arguments with +containers of different sizes is undefined. + +\pnum +The effect of calling a constructor or member function +that takes a \tcode{sorted_unique_t} argument with +a container, containers, or range +that is not sorted with respect to \tcode{key_comp()}, or +that contains equal elements, +is undefined. + +\rSec3[flat.map.defn]{Definition} + +\begin{codeblock} +namespace std { + template, + class KeyContainer = vector, class MappedContainer = vector> + class flat_map { + public: + // types + using key_type = Key; + using mapped_type = T; + using value_type = pair; + using key_compare = Compare; + using reference = pair; + using const_reference = pair; + using size_type = size_t; + using difference_type = ptrdiff_t; + using iterator = @\impdefx{type of \tcode{flat_map::iterator}}@; // see \ref{container.requirements} + using const_iterator = @\impdefx{type of \tcode{flat_map::const_iterator}}@; // see \ref{container.requirements} + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + using key_container_type = KeyContainer; + using mapped_container_type = MappedContainer; + + class value_compare { + private: + key_compare comp; // \expos + value_compare(key_compare c) : comp(c) { } // \expos + public: + bool operator()(const_reference x, const_reference y) const { + return comp(x.first, y.first); + } + }; + + struct containers { + key_container_type keys; + mapped_container_type values; + }; + + // \ref{flat.map.cons}, construct/copy/destroy + flat_map() : flat_map(key_compare()) { } + + flat_map(key_container_type key_cont, mapped_container_type mapped_cont); + template + flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont, + const Allocator& a); + + flat_map(sorted_unique_t, key_container_type key_cont, mapped_container_type mapped_cont); + template + flat_map(sorted_unique_t, const key_container_type& key_cont, + const mapped_container_type& mapped_cont, const Allocator& a); + + explicit flat_map(const key_compare& comp) + : c(), compare(comp) { } + template + flat_map(const key_compare& comp, const Allocator& a); + template + explicit flat_map(const Allocator& a); + + template + flat_map(InputIterator first, InputIterator last, const key_compare& comp = key_compare()) + : c(), compare(comp) { insert(first, last); } + template + flat_map(InputIterator first, InputIterator last, + const key_compare& comp, const Allocator& a); + template + flat_map(InputIterator first, InputIterator last, const Allocator& a); + + template<@\exposconcept{container-compatible-range}@ R> + flat_map(from_range_t fr, R&& rg) + : flat_map(fr, std::forward(rg), key_compare()) { } + template<@\exposconcept{container-compatible-range}@ R, class Allocator> + flat_map(from_range_t, R&& rg, const Allocator& a); + template<@\exposconcept{container-compatible-range}@ R> + flat_map(from_range_t, R&& rg, const key_compare& comp) + : flat_map(comp) { insert_range(std::forward(rg)); } + template<@\exposconcept{container-compatible-range}@ R, class Allocator> + flat_map(from_range_t, R&& rg, const key_compare& comp, const Allocator& a); + + template + flat_map(sorted_unique_t s, InputIterator first, InputIterator last, + const key_compare& comp = key_compare()) + : c(), compare(comp) { insert(s, first, last); } + template + flat_map(sorted_unique_t, InputIterator first, InputIterator last, + const key_compare& comp, const Allocator& a); + template + flat_map(sorted_unique_t, InputIterator first, InputIterator last, const Allocator& a); + + flat_map(initializer_list il, const key_compare& comp = key_compare()) + : flat_map(il.begin(), il.end(), comp) { } + template + flat_map(initializer_list il, const key_compare& comp, const Allocator& a); + template + flat_map(initializer_list il, const Allocator& a); + + flat_map(sorted_unique_t s, initializer_list il, + const key_compare& comp = key_compare()) + : flat_map(s, il.begin(), il.end(), comp) { } + template + flat_map(sorted_unique_t, initializer_list il, + const key_compare& comp, const Allocator& a); + template + flat_map(sorted_unique_t, initializer_list il, const Allocator& a); + + flat_map& operator=(initializer_list il); + + // iterators + iterator begin() noexcept; + const_iterator begin() const noexcept; + iterator end() noexcept; + const_iterator end() const noexcept; + + reverse_iterator rbegin() noexcept; + const_reverse_iterator rbegin() const noexcept; + reverse_iterator rend() noexcept; + const_reverse_iterator rend() const noexcept; + + const_iterator cbegin() const noexcept; + const_iterator cend() const noexcept; + const_reverse_iterator crbegin() const noexcept; + const_reverse_iterator crend() const noexcept; + + // \ref{flat.map.capacity}, capacity + [[nodiscard]] bool empty() const noexcept; + size_type size() const noexcept; + size_type max_size() const noexcept; + + // \ref{flat.map.access}, element access + mapped_type& operator[](const key_type& x); + mapped_type& operator[](key_type&& x); + template mapped_type& operator[](K&& x); + mapped_type& at(const key_type& x); + const mapped_type& at(const key_type& x) const; + template mapped_type& at(const K& x); + template const mapped_type& at(const K& x) const; + + // \ref{flat.map.modifiers}, modifiers + template pair emplace(Args&&... args); + template + iterator emplace_hint(const_iterator position, Args&&... args); + + pair insert(const value_type& x) + { return emplace(x); } + pair insert(value_type&& x) + { return emplace(std::move(x)); } + iterator insert(const_iterator position, const value_type& x) + { return emplace_hint(position, x); } + iterator insert(const_iterator position, value_type&& x) + { return emplace_hint(position, std::move(x)); } + + template pair insert(P&& x); + template + iterator insert(const_iterator position, P&&); + template + void insert(InputIterator first, InputIterator last); + template + void insert(sorted_unique_t, InputIterator first, InputIterator last); + template<@\exposconcept{container-compatible-range}@ R> + void insert_range(R&& rg); + + void insert(initializer_list il) + { insert(il.begin(), il.end()); } + void insert(sorted_unique_t s, initializer_list il) + { insert(s, il.begin(), il.end()); } + + containers extract() &&; + void replace(key_container_type&& key_cont, mapped_container_type&& mapped_cont); + + template + pair try_emplace(const key_type& k, Args&&... args); + template + pair try_emplace(key_type&& k, Args&&... args); + template + pair try_emplace(K&& k, Args&&... args); + template + iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); + template + iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); + template + iterator try_emplace(const_iterator hint, K&& k, Args&&... args); + template + pair insert_or_assign(const key_type& k, M&& obj); + template + pair insert_or_assign(key_type&& k, M&& obj); + template + pair insert_or_assign(K&& k, M&& obj); + template + iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); + template + iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); + template + iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); + + iterator erase(iterator position); + iterator erase(const_iterator position); + size_type erase(const key_type& x); + template size_type erase(K&& x); + iterator erase(const_iterator first, const_iterator last); + + void swap(flat_map& y) noexcept; + void clear() noexcept; + + // observers + key_compare key_comp() const; + value_compare value_comp() const; + + const key_container_type& keys() const noexcept { return c.keys; } + const mapped_container_type& values() const noexcept { return c.values; } + + // map operations + iterator find(const key_type& x); + const_iterator find(const key_type& x) const; + template iterator find(const K& x); + template const_iterator find(const K& x) const; + + size_type count(const key_type& x) const; + template size_type count(const K& x) const; + + bool contains(const key_type& x) const; + template bool contains(const K& x) const; + + iterator lower_bound(const key_type& x); + const_iterator lower_bound(const key_type& x) const; + template iterator lower_bound(const K& x); + template const_iterator lower_bound(const K& x) const; + + iterator upper_bound(const key_type& x); + const_iterator upper_bound(const key_type& x) const; + template iterator upper_bound(const K& x); + template const_iterator upper_bound(const K& x) const; + + pair equal_range(const key_type& x); + pair equal_range(const key_type& x) const; + template pair equal_range(const K& x); + template pair equal_range(const K& x) const; + + friend bool operator==(const flat_map& x, const flat_map& y); + + friend @\exposid{synth-three-way-result}@ + operator<=>(const flat_map& x, const flat_map& y); + + friend void swap(flat_map& x, flat_map& y) noexcept + { x.swap(y); } + + private: + containers c; // \expos + key_compare compare; // \expos + + struct key_equiv { // \expos + key_equiv(key_compare c) : comp(c) { } + bool operator()(const_reference x, const_reference y) const { + return !comp(x.first, y.first) && !comp(y.first, x.first); + } + key_compare comp; + }; + }; + + template + flat_map(KeyContainer, MappedContainer) + -> flat_map, KeyContainer, MappedContainer>; + + template + flat_map(KeyContainer, MappedContainer, Allocator) + -> flat_map, KeyContainer, MappedContainer>; + + template + flat_map(sorted_unique_t, KeyContainer, MappedContainer) + -> flat_map, KeyContainer, MappedContainer>; + + template + flat_map(sorted_unique_t, KeyContainer, MappedContainer, Allocator) + -> flat_map, KeyContainer, MappedContainer>; + + template>> + flat_map(InputIterator, InputIterator, Compare = Compare()) + -> flat_map<@\exposid{iter-key-type}@, @\exposid{iter-mapped-type}@, Compare>; + + template>> + flat_map(sorted_unique_t, InputIterator, InputIterator, Compare = Compare()) + -> flat_map<@\exposid{iter-key-type}@, @\exposid{iter-mapped-type}@, Compare>; + + template>, + class Allocator> + flat_map(from_range_t, R&&, Compare = Compare(), Allocator = Allocator()) + -> flat_map<@\exposid{range-key-type}@, @\exposid{range-mapped-type}@, Compare>; + + template + flat_map(from_range_t, R&&, Allocator) + -> flat_map<@\exposid{range-key-type}@, @\exposid{range-mapped-type}@>; + + template> + flat_map(initializer_list>, Compare = Compare()) + -> flat_map; + + template> + flat_map(sorted_unique_t, initializer_list>, Compare = Compare()) + -> flat_map; + + template + struct uses_allocator, Allocator> + : bool_constant && + uses_allocator_v> { }; +} +\end{codeblock} + +\pnum +The member type \tcode{containers} has the data members and special members +specified above. +It has no base classes or members other than those specified. + +\rSec3[flat.map.cons]{Constructors} + +\indexlibraryctor{flat_map}% +\begin{itemdecl} +flat_map(key_container_type key_cont, mapped_container_type mapped_cont); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{c.keys} with \tcode{std::move(key_cont)} and +\tcode{c.values} with \tcode{std::move(mapped_cont)}; +value-initializes \tcode{compare}; +sorts the range \range{begin()}{end()} with respect to \tcode{value_comp()}; and +finally erases the duplicate elements as if by: +\begin{codeblock} +auto zv = ranges::zip_view(c.keys, c.values); +auto it = ranges::unique(zv, key_equiv(compare)).begin(); +auto dist = distance(zv.begin(), it); +c.keys.erase(c.keys.begin() + dist, c.keys.end()); +c.values.erase(c.values.begin() + dist, c.values.end()); +\end{codeblock} + +\pnum +\complexity +Linear in $N$ if the container arguments are already sorted with respect +to \tcode{value_comp()} and otherwise $N \log N$, +where $N$ is \tcode{key_cont.size()}. +\end{itemdescr} + +\indexlibraryctor{flat_map}% +\begin{itemdecl} +template + flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont, + const Allocator& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{uses_allocator_v} is \tcode{true} and +\tcode{uses_allocator_v} is \tcode{true}. + +\pnum +\effects +Equivalent to \tcode{flat_map(key_cont, mapped_cont)}, +except that \tcode{c.keys} and \tcode{c.values} are constructed with +uses-allocator construction\iref{allocator.uses.construction}. + +\pnum +\complexity +Same as \tcode{flat_map(key_cont, mapped_cont)}. +\end{itemdescr} + +\indexlibraryctor{flat_map}% +\begin{itemdecl} +flat_map(sorted_unique_t, key_container_type key_cont, mapped_container_type mapped_cont); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{c.keys} with \tcode{std::move(key_cont)} and +\tcode{c.values} with \tcode{std::move(mapped_cont)}; +value-initializes \tcode{compare}. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexlibraryctor{flat_map}% +\begin{itemdecl} +template + flat_map(sorted_unique_t s, const key_container_type& key_cont, + const mapped_container_type& mapped_cont, const Allocator& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{uses_allocator_v} is \tcode{true} and +\tcode{uses_allocator_v} is \tcode{true}. + +\pnum +\effects +Equivalent to \tcode{flat_map(s, key_cont, mapped_cont)}, +except that \tcode{c.keys} and \tcode{c.values} are constructed +with uses-allocator construction\iref{allocator.uses.construction}. + +\pnum +\complexity +Linear. +\end{itemdescr} + +\indexlibraryctor{flat_map}% +\begin{itemdecl} +template + flat_map(const key_compare& comp, const Allocator& a); +template + explicit flat_map(const Allocator& a); +template + flat_map(InputIterator first, InputIterator last, const key_compare& comp, const Allocator& a); +template + flat_map(InputIterator first, InputIterator last, const Allocator& a); +template<@\exposconcept{container-compatible-range}@ R, class Allocator> + flat_map(from_range_t, R&& rg, const Allocator& a); +template<@\exposconcept{container-compatible-range}@ R, class Allocator> + flat_map(from_range_t, R&& rg, const key_compare& comp, const Allocator& a); +template + flat_map(sorted_unique_t, InputIterator first, InputIterator last, + const key_compare& comp, const Allocator& a); +template + flat_map(sorted_unique_t, InputIterator first, InputIterator last, const Allocator& a); +template + flat_map(initializer_list il, const key_compare& comp, const Allocator& a); +template + flat_map(initializer_list il, const Allocator& a); +template + flat_map(sorted_unique_t, initializer_list il, + const key_compare& comp, const Allocator& a); +template + flat_map(sorted_unique_t, initializer_list il, const Allocator& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{uses_allocator_v} is \tcode{true}. + +\pnum +\effects +Equivalent to the corresponding non-allocator constructors +except that \tcode{c.keys} and \tcode{c.values} are constructed +with uses-allocator construction\iref{allocator.uses.construction}. +\end{itemdescr} + +\rSec3[flat.map.capacity]{Capacity} + +\indexlibrarymember{size}{flat_map}% +\begin{itemdecl} +size_type size() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{c.keys.size()}. +\end{itemdescr} + +\indexlibrarymember{max_size}{flat_map}% +\begin{itemdecl} +size_type max_size() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{min(c.keys.max_size(), c.values.max_size())}. +\end{itemdescr} + +\rSec3[flat.map.access]{Access} + +\indexlibrarymember{operator[]}{flat_map}% +\begin{itemdecl} +mapped_type& operator[](const key_type& x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return try_emplace(x).first->second;} +\end{itemdescr} + +\indexlibrarymember{operator[]}{flat_map}% +\begin{itemdecl} +mapped_type& operator[](key_type&& x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return try_emplace(std::move(x)).first->second;} +\end{itemdescr} + +\indexlibrarymember{operator[]}{flat_map}% +\begin{itemdecl} +template mapped_type& operator[](K&& x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +The \grammarterm{qualified-id} \tcode{Compare::is_transparent} is valid and +denotes a type. + +\pnum +\effects +Equivalent to: \tcode{return try_emplace(std::forward(x)).first->second;} +\end{itemdescr} + +\indexlibrarymember{at}{flat_map}% +\begin{itemdecl} +mapped_type& at(const key_type& x); +const mapped_type& at(const key_type& x) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A reference to the \tcode{mapped_type} corresponding +to \tcode{x} in \tcode{*this}. + +\pnum +\throws +An exception object of type \tcode{out_of_range} if +no such element is present. + +\pnum +\complexity +Logarithmic. +\end{itemdescr} + +\indexlibrarymember{at}{flat_map}% +\begin{itemdecl} +template mapped_type& at(const K& x); +template const mapped_type& at(const K& x) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +The \grammarterm{qualified-id} \tcode{Compare::is_transparent} +is valid and denotes a type. + +\pnum +\expects +The expression \tcode{find(x)} is well-formed and has well-defined behavior. + +\pnum +\returns +A reference to the \tcode{mapped_type} corresponding to +\tcode{x} in \tcode{*this}. + +\pnum +\throws +An exception object of type \tcode{out_of_range} +if no such element is present. + +\pnum +\complexity +Logarithmic. +\end{itemdescr} + +\rSec3[flat.map.modifiers]{Modifiers} + +\indexlibrarymember{emplace}{flat_map}% +\begin{itemdecl} +template pair emplace(Args&&... args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_constructible_v, Arg...>} is \tcode{true}. + +\pnum +\effects +Initializes an object \tcode{t} of type \tcode{pair} +with \tcode{std::forward(\linebreak args)...}; +if the map already contains an element +whose key is equivalent to \tcode{t.first}, +\tcode{*this} is unchanged. +Otherwise, equivalent to: +\begin{codeblock} +auto key_it = ranges::upper_bound(c.keys, t.first, compare); +auto value_it = c.values.begin() + distance(c.keys.begin(), key_it); +c.keys.insert(key_it, std::move(t.first)); +c.values.insert(value_it, std::move(t.second)); +\end{codeblock} + +\pnum +\returns +The \tcode{bool} component of the returned pair is \tcode{true} +if and only if the insertion took place, and +the iterator component of the pair points to +the element with key equivalent to \tcode{t.first}. +\end{itemdescr} + +\indexlibrarymember{insert}{flat_map}% +\begin{itemdecl} +template pair insert(P&& x); +template iterator insert(const_iterator position, P&& x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_constructible_v, P>} is \tcode{true}. + +\pnum +\effects +The first form is equivalent to \tcode{return emplace(std::forward

(x));}. +The second form is equivalent to +\tcode{return emplace_hint(position, std::forward

(x));}. +\end{itemdescr} + +\indexlibrarymember{insert}{flat_map}% +\begin{itemdecl} +template + void insert(InputIterator first, InputIterator last); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Adds elements to \tcode{c} as if by: +\begin{codeblock} +for (; first != last; ++first) { + value_type value = *first; + c.keys.insert(c.keys.end(), std::move(value.first)); + c.values.insert(c.values.end(), std::move(value.second)); +} +\end{codeblock} +Then, sorts the range of newly inserted elements +with respect to \tcode{value_comp()}; +merges the resulting sorted range and +the sorted range of pre-existing elements into a single sorted range; and +finally erases the duplicate elements as if by: +\begin{codeblock} +auto zv = ranges::zip_view(c.keys, c.values); +auto it = ranges::unique(zv, key_equiv(compare)).begin(); +auto dist = distance(zv.begin(), it); +c.keys.erase(c.keys.begin() + dist, c.keys.end()); +c.values.erase(c.values.begin() + dist, c.values.end()); +\end{codeblock} + +\pnum +\complexity +$N$ + $M \log M$, +where $N$ is \tcode{size()} before the operation and +$M$ is \tcode{distance(first, last)}. + +\pnum +\remarks +Since this operation performs an in-place merge, it may allocate memory. +\end{itemdescr} + +\indexlibrarymember{insert}{flat_map}% +\begin{itemdecl} +template + void insert(sorted_unique_t, InputIterator first, InputIterator last); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Adds elements to \tcode{c} as if by: +\begin{codeblock} +for (; first != last; ++first) { + value_type value = *first; + c.keys.insert(c.keys.end(), std::move(value.first)); + c.values.insert(c.values.end(), std::move(value.second)); +} +\end{codeblock} +Then, merges the sorted range of newly added elements and +the sorted range of pre-existing elements into a single sorted range; and +finally erases the duplicate elements as if by: +\begin{codeblock} +auto zv = ranges::zip_view(c.keys, c.values); +auto it = ranges::unique(zv, key_equiv(compare)).begin(); +auto dist = distance(zv.begin(), it); +c.keys.erase(c.keys.begin() + dist, c.keys.end()); +c.values.erase(c.values.begin() + dist, c.values.end()); +\end{codeblock} + +\pnum +\complexity +Linear in $N$, where $N$ is \tcode{size()} after the operation. + +\pnum +\remarks +Since this operation performs an in-place merge, it may allocate memory. +\end{itemdescr} + +\indexlibrarymember{insert_range}{flat_map}% +\begin{itemdecl} +template<@\exposconcept{container-compatible-range}@ R> + void insert_range(R&& rg); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Adds elements to \tcode{c} as if by: +\begin{codeblock} +for (const auto& e : range) { + c.keys.insert(c.keys.end(), e.first); + c.values.insert(c.values.end(), e.second); +} +\end{codeblock} +Then, sorts the range of newly inserted elements +with respect to \tcode{value_comp()}; +merges the resulting sorted range and +the sorted range of pre-existing elements into a single sorted range; and +finally erases the duplicate elements as if by: +\begin{codeblock} +auto zv = ranges::zip_view(c.keys, c.values); +auto it = ranges::unique(zv, key_equiv(compare)).begin(); +auto dist = distance(zv.begin(), it); +c.keys.erase(c.keys.begin() + dist, c.keys.end()); +c.values.erase(c.values.begin() + dist, c.values.end()); +\end{codeblock} + +\pnum +\complexity +$N$ + $M \log M$, +where $N$ is \tcode{size()} before the operation and +$M$ is \tcode{ranges::distance(rg)}. + +\pnum +\remarks +Since this operation performs an in-place merge, it may allocate memory. +\end{itemdescr} + +\indexlibrarymember{try_emplace}{flat_map}% +\begin{itemdecl} +template + pair try_emplace(const key_type& k, Args&&... args); +template + pair try_emplace(key_type&& k, Args&&... args); +template + iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); +template + iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_constructible_v} is \tcode{true}. + +\pnum +\effects +If the map already contains an element whose key is equivalent to \tcode{k}, +\tcode{*this} and \tcode{args...} are unchanged. +Otherwise equivalent to: +\begin{codeblock} +auto key_it = ranges::upper_bound(c.keys, k, compare); +auto value_it = c.values.begin() + distance(c.keys.begin(), key_it); +c.keys.insert(key_it, std::forward(k)); +c.values.emplace(value_it, std::forward(args)...); +\end{codeblock} + +\pnum +\returns +In the first two overloads, +the \tcode{bool} component of the returned pair is \tcode{true} +if and only if the insertion took place. +The returned iterator points to the map element +whose key is equivalent to \tcode{k}. + +\pnum +\complexity +The same as \tcode{emplace} for the first two overloads, and +the same as \tcode{emplace_hint} for the last two overloads. +\end{itemdescr} + +\indexlibrarymember{try_emplace}{flat_map}% +\begin{itemdecl} +template + pair try_emplace(K&& k, Args&&... args); +template + iterator try_emplace(const_iterator hint, K&& k, Args&&... args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +The \grammarterm{qualified-id} \tcode{Compare::is_transparent} +is valid and denotes a type. +\item +\tcode{is_constructible_v} is \tcode{true}. +\item +\tcode{is_constructible_v} is \tcode{true}. +\item +For the first overload, +\tcode{is_convertible_v} and +\tcode{is_convertible_v} are both \tcode{false}. +\end{itemize} + +\pnum +\expects +The conversion from \tcode{k} into \tcode{key_type} constructs +an object \tcode{u}, +for which \tcode{find(k) == find(u)} is \tcode{true}. + +\pnum +\effects +If the map already contains an element whose key is equivalent to \tcode{k}, +\tcode{*this} and \tcode{args...} are unchanged. +Otherwise equivalent to: +\begin{codeblock} +auto key_it = ranges::upper_bound(c.keys, k, compare); +auto value_it = c.values.begin() + distance(c.keys.begin(), key_it); +c.keys.emplace(key_it, std::forward(k)); +c.values.emplace(value_it, std::forward(args)...); +\end{codeblock} + +\pnum +\returns +In the first overload, +the \tcode{bool} component of the returned pair is \tcode{true} +if and only if the insertion took place. +The returned iterator points to the map element +whose key is equivalent to \tcode{k}. + +\pnum +\complexity +The same as \tcode{emplace} and \tcode{emplace_hint}, respectively. +\end{itemdescr} + +\indexlibrarymember{insert_or_assign}{flat_map}% +\begin{itemdecl} +template + pair insert_or_assign(const key_type& k, M&& obj); +template + pair insert_or_assign(key_type&& k, M&& obj); +template + iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); +template + iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_assignable_v} is \tcode{true} and +\tcode{is_constructible_v} is \tcode{true}. + +\pnum +\effects +If the map already contains an element \tcode{e} +whose key is equivalent to \tcode{k}, +assigns \tcode{std::forward<\linebreak M>(obj)} to \tcode{e.second}. +Otherwise, equivalent to +\begin{codeblock} +try_emplace(std::forward(k), std::forward(obj)) +\end{codeblock} +for the first two overloads or +\begin{codeblock} +try_emplace_hint(hint, std::forward(k), std::forward(obj)) +\end{codeblock} +for the last two overloads. + +\pnum +\returns +In the first two overloads, the \tcode{bool} component of the returned pair +is \tcode{true} if and only if the insertion took place. The returned +iterator points to the map element whose key is equivalent to \tcode{k}. + +\pnum +\complexity +The same as \tcode{emplace} for the first two overloads and +the same as \tcode{emplace_hint} for the last two overloads. +\end{itemdescr} + +\indexlibrarymember{insert_or_assign}{flat_map}% +\begin{itemdecl} +template + pair insert_or_assign(K&& k, M&& obj); +template + iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +The \grammarterm{qualified-id} \tcode{Compare::is_transparent} +is valid and denotes a type. +\item +\tcode{is_constructible_v} is \tcode{true}. +\item +\tcode{is_assignable_v} is \tcode{true}. +\item +\tcode{is_constructible_v} is \tcode{true}. +\end{itemize} + +\pnum +\expects +The conversion from \tcode{k} into \tcode{key_type} constructs +an object \tcode{u}, for which \tcode{find(k) == find(u)} is \tcode{true}. + +\pnum +\effects +If the map already contains an element \tcode{e} +whose key is equivalent to \tcode{k}, +assigns \tcode{std::forward<\linebreak M>(obj)} to \tcode{e.second}. +Otherwise, equivalent to +\begin{codeblock} +try_emplace(std::forward(k), std::forward(obj)) +\end{codeblock} +for the first overload or +\begin{codeblock} +try_emplace_hint(hint, std::forward(k), std::forward(obj)) +\end{codeblock} +for the second overload. + +\pnum +\returns +In the first overload, +the \tcode{bool} component of the returned pair is \tcode{true} +if and only if the insertion took place. +The returned iterator points to the map element +whose key is equivalent to \tcode{k}. + +\pnum +\complexity +The same as \tcode{emplace} and \tcode{emplace_hint}, respectively. +\end{itemdescr} + +\indexlibrarymember{swap}{flat_map}% +\begin{itemdecl} +void swap(flat_map& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +ranges::swap(compare, y.compare); +ranges::swap(c.keys, y.c.keys); +ranges::swap(c.values, y.c.values); +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{extract}{flat_map}% +\begin{itemdecl} +containers extract() &&; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\ensures +\tcode{*this} is emptied, even if the function exits via an exception. + +\pnum +\returns +\tcode{std::move(c)}. +\end{itemdescr} + +\indexlibrarymember{replace}{flat_map}% +\begin{itemdecl} +void replace(key_container_type&& key_cont, mapped_container_type&& mapped_cont); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{key_cont.size() == mapped_cont.size()} is \tcode{true}, +the elements of \tcode{key_cont} are sorted with respect to \tcode{compare}, and +\tcode{key_cont} contains no equal elements. + +\pnum +\effects +Equivalent to: +\begin{codeblock} +c.keys = std::move(key_cont); +c.values = std::move(mapped_cont); +\end{codeblock} +\end{itemdescr} + +\rSec3[flat.map.erasure]{Erasure} + +\indexlibrarymember{erase_if}{flat_map}% +\begin{itemdecl} +template + typename flat_map::size_type + erase_if(flat_map& c, Predicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{Key} and \tcode{T} meet the \oldconcept{MoveAssignable} requirements. + +\pnum +\effects +Let $E$ be \tcode{bool(pred(pair(e)))}. +Erases all elements \tcode{e} in \tcode{c} for which $E$ holds. + +\pnum +\returns +The number of elements erased. + +\pnum +\complexity +Exactly \tcode{c.size()} applications of the predicate. + +\pnum +\remarks +Stable\iref{algorithm.stable}. +If an invocation of \tcode{erase_if} exits via an exception, +\tcode{c} is in a valid but unspecified state\iref{defns.valid}. +\begin{note} +\tcode{c} still meets its invariants, +but can be empty. +\end{note} +\end{itemdescr} + +\rSec2[flat.multimap]{Class template \tcode{flat_multimap}} + +\rSec3[flat.multimap.overview]{Overview} + +\pnum +\indexlibraryglobal{flat_multimap}% +A \tcode{flat_multimap} is a container adaptor +that provides an associative container interface +that supports equivalent keys +(i.e., possibly containing multiple copies of the same key value) and +provides for fast retrieval of values of another type \tcode{T} +based on the keys. +\tcode{flat_multimap} supports iterators that meet +the \oldconcept{InputIterator} requirements and +model the +\libconcept{random_access_iterator} concept\iref{iterator.concept.random.access}. + +\pnum +A \tcode{flat_multimap} meets all of the requirements +for a container\iref{container.reqmts} and +for a reversible container\iref{container.rev.reqmts}, +plus the optional container requirements\iref{container.opt.reqmts}. +\tcode{flat_multimap} meets the requirements of +an associative container\iref{associative.reqmts}, except that: +\begin{itemize} +\item +it does not meet the requirements related to node handles\iref{container.node}, +\item +it does not meet the requirements related to iterator invalidation, and +\item +the time complexity of the operations +that insert or erase a single element from the map is linear, +including the ones that take an insertion position iterator. +\end{itemize} +\begin{note} +A \tcode{flat_multimap} does not meet the additional requirements of an +allocator-aware container\iref{container.alloc.reqmts}. +\end{note} + +\pnum +A \tcode{flat_multimap} also provides most operations described +in \ref{associative.reqmts} for equal keys. +This means that a \tcode{flat_multimap} supports the \tcode{a_eq} operations +in \ref{associative.reqmts} but not the \tcode{a_uniq} operations. +For a \tcode{flat_multimap} +the \tcode{key_type} is \tcode{Key} and +the \tcode{value_type} is \tcode{pair}. + +\pnum +Except as otherwise noted, +operations on \tcode{flat_multimap} are equivalent to those of \tcode{flat_map}, +except that \tcode{flat_multimap} operations +do not remove or replace elements with equal keys. +\begin{example} +\tcode{flat_multimap} constructors and emplace do not erase +non-unique elements after sorting them. +\end{example} + +\pnum +A \tcode{flat_multimap} maintains the following invariants: +\begin{itemize} +\item +it contains the same number of keys and values; +\item +the keys are sorted with respect to the comparison object; and +\item +the value at offset \tcode{off} within the value container is the value +associated with the key at offset \tcode{off} within the key container. +\end{itemize} + +\pnum +If any member function in \ref{flat.multimap.defn} exits via an exception, +the invariants are restored. +\begin{note} +This can result in the \tcode{flat_multimap} being emptied. +\end{note} + +\pnum +Any sequence container\iref{sequence.reqmts} \tcode{C} +supporting \oldconcept{RandomAccessIterator} can be used to +instantiate \tcode{flat_multimap}, +as long as invocations of +member functions \tcode{C::size} and \tcode{C::max_size} do not exit via an exception. +In particular, +\tcode{vector}\iref{vector} and \tcode{deque}\iref{deque} can be used. +\begin{note} +\tcode{vector} is not a sequence container. +\end{note} + +\pnum +The program is ill-formed if +\tcode{Key} is not the same type as \tcode{KeyContainer::value_type} or +\tcode{T} is not the same type as \tcode{MappedContainer::value_type}. + +\pnum +The effect of calling a constructor +that takes both \tcode{key_container_type} and +\tcode{mapped_container_type} arguments +with containers of different sizes is undefined. + +\pnum +The effect of calling a constructor or member function +that takes a \tcode{sorted_equivalent_t} argument +with a container, containers, or range +that are not sorted with respect to \tcode{key_comp()} is undefined. + +\rSec3[flat.multimap.defn]{Definition} + +\begin{codeblock} +namespace std { + template, + class KeyContainer = vector, class MappedContainer = vector> + class flat_multimap { + public: + // types + using key_type = Key; + using mapped_type = T; + using value_type = pair; + using key_compare = Compare; + using reference = pair; + using const_reference = pair; + using size_type = size_t; + using difference_type = ptrdiff_t; + using iterator = @\impdefx{type of \tcode{flat_multimap::iterator}}@; // see \ref{container.requirements} + using const_iterator = @\impdefx{type of \tcode{flat_multimap::const_iterator}}@; // see \ref{container.requirements} + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + using key_container_type = KeyContainer; + using mapped_container_type = MappedContainer; + + class value_compare { + private: + key_compare comp; // \expos + value_compare(key_compare c) : comp(c) { } // \expos + public: + bool operator()(const_reference x, const_reference y) const { + return comp(x.first, y.first); + } + }; + + struct containers { + key_container_type keys; + mapped_container_type values; + }; + + // \ref{flat.multimap.cons}, construct/copy/destroy + flat_multimap() : flat_multimap(key_compare()) { } + + flat_multimap(key_container_type key_cont, mapped_container_type mapped_cont); + template + flat_multimap(const key_container_type& key_cont, const mapped_container_type& mapped_cont, + const Allocator& a); + + flat_multimap(sorted_equivalent_t, + key_container_type key_cont, mapped_container_type mapped_cont); + template + flat_multimap(sorted_equivalent_t, const key_container_type& key_cont, + const mapped_container_type& mapped_cont, const Allocator& a); + + explicit flat_multimap(const key_compare& comp) + : c(), compare(comp) { } + template + flat_multimap(const key_compare& comp, const Allocator& a); + template + explicit flat_multimap(const Allocator& a); + + template + flat_multimap(InputIterator first, InputIterator last, + const key_compare& comp = key_compare()) + : c(), compare(comp) + { insert(first, last); } + template + flat_multimap(InputIterator first, InputIterator last, + const key_compare& comp, const Allocator& a); + template + flat_multimap(InputIterator first, InputIterator last, + const Allocator& a); + + template<@\exposconcept{container-compatible-range}@ R> + flat_mutlimap(from_range_t fr, R&& rg) + : flat_multimap(fr, std::forward(rg), key_compare()) { } + template<@\exposconcept{container-compatible-range}@ R, class Allocator> + flat_mutlimap(from_range_t, R&& rg, const Allocator& a); + template<@\exposconcept{container-compatible-range}@ R> + flat_multimap(from_range_t, R&& rg, const key_compare& comp) + : flat_multimap(comp) { insert_range(std::forward(rg)); } + template<@\exposconcept{container-compatible-range}@ R, class Allocator> + flat_multimap(from_range_t, R&& rg, const key_compare& comp, const Allocator& a); + + template + flat_multimap(sorted_equivalent_t s, InputIterator first, InputIterator last, + const key_compare& comp = key_compare()) + : c(), compare(comp) { insert(s, first, last); } + template + flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, + const key_compare& comp, const Allocator& a); + template + flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, + const Allocator& a); + + flat_multimap(initializer_list il, + const key_compare& comp = key_compare()) + : flat_multimap(il.begin(), il.end(), comp) { } + template + flat_multimap(initializer_list il, + const key_compare& comp, const Allocator& a); + template + flat_multimap(initializer_list il, const Allocator& a); + + flat_multimap(sorted_equivalent_t s, initializer_list il, + const key_compare& comp = key_compare()) + : flat_multimap(s, il.begin(), il.end(), comp) { } + template + flat_multimap(sorted_equivalent_t, initializer_list il, + const key_compare& comp, const Allocator& a); + template + flat_multimap(sorted_equivalent_t, initializer_list il, const Allocator& a); + + flat_multimap& operator=(initializer_list il); + + // iterators + iterator begin() noexcept; + const_iterator begin() const noexcept; + iterator end() noexcept; + const_iterator end() const noexcept; + + reverse_iterator rbegin() noexcept; + const_reverse_iterator rbegin() const noexcept; + reverse_iterator rend() noexcept; + const_reverse_iterator rend() const noexcept; + + const_iterator cbegin() const noexcept; + const_iterator cend() const noexcept; + const_reverse_iterator crbegin() const noexcept; + const_reverse_iterator crend() const noexcept; + + // capacity + [[nodiscard]] bool empty() const noexcept; + size_type size() const noexcept; + size_type max_size() const noexcept; + + // modifiers + template iterator emplace(Args&&... args); + template + iterator emplace_hint(const_iterator position, Args&&... args); + + iterator insert(const value_type& x) + { return emplace(x); } + iterator insert(value_type&& x) + { return emplace(std::move(x)); } + iterator insert(const_iterator position, const value_type& x) + { return emplace_hint(position, x); } + iterator insert(const_iterator position, value_type&& x) + { return emplace_hint(position, std::move(x)); } + + template iterator insert(P&& x); + template + iterator insert(const_iterator position, P&&); + template + void insert(InputIterator first, InputIterator last); + template + void insert(sorted_equivalent_t, InputIterator first, InputIterator last); + template<@\exposconcept{container-compatible-range}@ R> + void insert_range(R&& rg); + + void insert(initializer_list il) + { insert(il.begin(), il.end()); } + void insert(sorted_equivalent_t s, initializer_list il) + { insert(s, il.begin(), il.end()); } + + containers extract() &&; + void replace(key_container_type&& key_cont, mapped_container_type&& mapped_cont); + + iterator erase(iterator position); + iterator erase(const_iterator position); + size_type erase(const key_type& x); + template size_type erase(K&& x); + iterator erase(const_iterator first, const_iterator last); + + void swap(flat_multimap&) noexcept; + void clear() noexcept; + + // observers + key_compare key_comp() const; + value_compare value_comp() const; + + const key_container_type& keys() const noexcept { return c.keys; } + const mapped_container_type& values() const noexcept { return c.values; } + + // map operations + iterator find(const key_type& x); + const_iterator find(const key_type& x) const; + template iterator find(const K& x); + template const_iterator find(const K& x) const; + + size_type count(const key_type& x) const; + template size_type count(const K& x) const; + + bool contains(const key_type& x) const; + template bool contains(const K& x) const; + + iterator lower_bound(const key_type& x); + const_iterator lower_bound(const key_type& x) const; + template iterator lower_bound(const K& x); + template const_iterator lower_bound(const K& x) const; + + iterator upper_bound(const key_type& x); + const_iterator upper_bound(const key_type& x) const; + template iterator upper_bound(const K& x); + template const_iterator upper_bound(const K& x) const; + + pair equal_range(const key_type& x); + pair equal_range(const key_type& x) const; + template + pair equal_range(const K& x); + template + pair equal_range(const K& x) const; + + friend bool operator==(const flat_multimap& x, const flat_multimap& y); + + friend @\exposid{synth-three-way-result}@ + operator<=>(const flat_multimap& x, const flat_multimap& y); + + friend void swap(flat_multimap& x, flat_multimap& y) noexcept + { x.swap(y); } + + private: + containers c; // \expos + key_compare compare; // \expos + }; + + template + flat_multimap(KeyContainer, MappedContainer) + -> flat_multimap, KeyContainer, MappedContainer>; + + template + flat_multimap(KeyContainer, MappedContainer, Allocator) + -> flat_multimap, KeyContainer, MappedContainer>; + + template + flat_multimap(sorted_equivalent_t, KeyContainer, MappedContainer) + -> flat_multimap, KeyContainer, MappedContainer>; + + template + flat_multimap(sorted_equivalent_t, KeyContainer, MappedContainer, Allocator) + -> flat_multimap, KeyContainer, MappedContainer>; + + template>> + flat_multimap(InputIterator, InputIterator, Compare = Compare()) + -> flat_multimap<@\exposid{iter-key-type}@, @\exposid{iter-mapped-type}@, Compare>; + + template>> + flat_multimap(sorted_equivalent_t, InputIterator, InputIterator, Compare = Compare()) + -> flat_multimap<@\exposid{iter-key-type}@, @\exposid{iter-mapped-type}@, Compare>; + + template>, + class Allocator> + flat_multimap(from_range_t, R&&, Compare = Compare(), Allocator = Allocator()) + -> flat_multimap<@\exposid{range-key-type}@, @\exposid{range-mapped-type}@, Compare>; + + template + flat_multimap(from_range_t, R&&, Allocator) + -> flat_multimap<@\exposid{range-key-type}@, @\exposid{range-mapped-type}@>; + + template> + flat_multimap(initializer_list>, Compare = Compare()) + -> flat_multimap; + + template> + flat_multimap(sorted_equivalent_t, initializer_list>, Compare = Compare()) + -> flat_multimap; + + template + struct uses_allocator, + Allocator> + : bool_constant && + uses_allocator_v> { }; +} +\end{codeblock} + +\pnum +The member type \tcode{containers} has the data members and special members +specified above. It has no base classes or members other than those +specified. + +\rSec3[flat.multimap.cons]{Constructors} + +\indexlibraryctor{flat_multimap}% +\begin{itemdecl} +flat_multimap(key_container_type key_cont, mapped_container_type mapped_cont); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{c.keys} with \tcode{std::move(key_cont)} and +\tcode{c.values} with \tcode{std::move(mapped_cont)}; +value-initializes \tcode{compare}; and +sorts the range \range{begin()}{end()} with respect to \tcode{value_comp()}. + +\pnum +\complexity +Linear in $N$ if the container arguments are already sorted +with respect to \tcode{value_comp()} and +otherwise $N \log N$, +where $N$ is \tcode{key_cont.size()}. +\end{itemdescr} + +\indexlibraryctor{flat_multimap}% +\begin{itemdecl} +template + flat_multimap(const key_container_type& key_cont, const mapped_container_type& mapped_cont, + const Allocator& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{uses_allocator_v} is \tcode{true} and +\tcode{uses_allocator_v} is \tcode{true}. + +\pnum +\effects +Equivalent to \tcode{flat_multimap(key_cont, mapped_cont)}, +except that \tcode{c.keys} and \tcode{c.values} are constructed +with uses-allocator construction\iref{allocator.uses.construction}. + +\pnum +\complexity +Same as \tcode{flat_multimap(key_cont, mapped_cont)}. +\end{itemdescr} + +\indexlibraryctor{flat_multimap}% +\begin{itemdecl} +flat_multimap(sorted_equivalent_t, key_container_type key_cont, mapped_container_type mapped_cont); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{c.keys} with \tcode{std::move(key_cont)} and +\tcode{c.values} with \tcode{std::move(mapped_cont)}; +value-initializes \tcode{compare}. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexlibraryctor{flat_multimap}% +\begin{itemdecl} +template + flat_multimap(sorted_equivalent_t s, const key_container_type& key_cont, + const mapped_container_type& mapped_cont, const Allocator& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{uses_allocator_v} is \tcode{true} and +\tcode{uses_allocator_v} is \tcode{true}. + +\pnum +\effects +Equivalent to \tcode{flat_multimap(s, key_cont, mapped_cont)}, +except that \tcode{c.keys} and \tcode{c.val\-ues} are constructed +with uses-allocator construction\iref{allocator.uses.construction}. + +\pnum +\complexity +Linear. +\end{itemdescr} + +\indexlibraryctor{flat_multimap}% +\begin{itemdecl} +template + flat_multimap(const key_compare& comp, const Allocator& a); +template + explicit flat_multimap(const Allocator& a); +template + flat_multimap(InputIterator first, InputIterator last, const key_compare& comp, + const Allocator& a); +template + flat_multimap(InputIterator first, InputIterator last, const Allocator& a); +template<@\exposconcept{container-compatible-range}@ R, class Allocator> + flat_mutlimap(from_range_t, R&& rg, const Allocator& a); +template<@\exposconcept{container-compatible-range}@ R, class Allocator> + flat_multimap(from_range_t, R&& rg, const key_compare& comp, const Allocator& a); +template + flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, + const key_compare& comp, const Allocator& a); +template + flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, + const Allocator& a); +template + flat_multimap(initializer_list il, const key_compare& comp, const Allocator& a); +template + flat_multimap(initializer_list il, const Allocator& a); +template + flat_multimap(sorted_equivalent_t, initializer_list il, + const key_compare& comp, const Allocator& a); +template + flat_multimap(sorted_equivalent_t, initializer_list il, const Allocator& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{uses_allocator_v} is \tcode{true} and +\tcode{uses_allocator_v} is \tcode{true}. + +\pnum +\effects +Equivalent to the corresponding non-allocator constructors +except that \tcode{c.keys} and \tcode{c.values} are constructed +with uses-allocator construction\iref{allocator.uses.construction}. +\end{itemdescr} + +\rSec3[flat.multimap.erasure]{Erasure} + +\indexlibrarymember{erase_if}{flat_multimap}% +\begin{itemdecl} +template + typename flat_multimap::size_type + erase_if(flat_multimap& c, Predicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{Key} and \tcode{T} meet the \oldconcept{MoveAssignable} requirements. + +\pnum +\effects +Let $E$ be \tcode{bool(pred(pair(e)))}. +Erases all elements \tcode{e} in \tcode{c} for which $E$ holds. + +\pnum +\returns +The number of elements erased. + +\pnum +\complexity +Exactly \tcode{c.size()} applications of the predicate. + +\pnum +\remarks +Stable\iref{algorithm.stable}. +If an invocation of \tcode{erase_if} exits via an exception, +\tcode{c} is in a valid but unspecified state\iref{defns.valid}. +\begin{note} +\tcode{c} still meets its invariants, +but can be empty. +\end{note} +\end{itemdescr} + \rSec1[views]{Views} \rSec2[views.general]{General} diff --git a/source/lib-intro.tex b/source/lib-intro.tex index 291a48d786..208b8cd8c4 100644 --- a/source/lib-intro.tex +++ b/source/lib-intro.tex @@ -1034,6 +1034,7 @@ \tcode{} \\ \tcode{} \\ \columnbreak +\tcode{} \\ \tcode{} \\ \tcode{} \\ \tcode{} \\ diff --git a/source/support.tex b/source/support.tex index 2e34b6f0f3..cdcdaf1bbe 100644 --- a/source/support.tex +++ b/source/support.tex @@ -616,6 +616,7 @@ #define @\defnlibxname{cpp_lib_execution}@ 201902L // also in \libheader{execution} #define @\defnlibxname{cpp_lib_expected}@ 202202L // also in \libheader{expected} #define @\defnlibxname{cpp_lib_filesystem}@ 201703L // also in \libheader{filesystem} +#define @\defnlibxname{cpp_lib_flat_map}@ 202207L // also in \libheader{flat_map} #define @\defnlibxname{cpp_lib_format}@ 202110L // also in \libheader{format} #define @\defnlibxname{cpp_lib_gcd_lcm}@ 201606L // also in \libheader{numeric} #define @\defnlibxname{cpp_lib_generic_associative_lookup}@ 201304L // also in \libheader{map}, \libheader{set} From d14c6ed4e499c7663af520bd32370f4054442f42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Sun, 14 Aug 2022 13:48:21 +0100 Subject: [PATCH 186/430] [flat.{,multi}map.cons] Clarify that the state before the move is meant. --- source/containers.tex | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index df9ecacc0f..223e37a24d 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -14833,9 +14833,9 @@ \pnum \complexity -Linear in $N$ if the container arguments are already sorted with respect -to \tcode{value_comp()} and otherwise $N \log N$, -where $N$ is \tcode{key_cont.size()}. +Linear in $N$ if the container arguments are already sorted +with respect to \tcode{value_comp()} and otherwise $N \log N$, +where $N$ is the value of \tcode{key_cont.size()} before this call. \end{itemdescr} \indexlibraryctor{flat_map}% @@ -15933,9 +15933,8 @@ \pnum \complexity Linear in $N$ if the container arguments are already sorted -with respect to \tcode{value_comp()} and -otherwise $N \log N$, -where $N$ is \tcode{key_cont.size()}. +with respect to \tcode{value_comp()} and otherwise $N \log N$, +where $N$ is the value of \tcode{key_cont.size()} before this call. \end{itemdescr} \indexlibraryctor{flat_multimap}% From 85b8c3470961fc0e66f96806ddae877ec27e3b0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Sun, 14 Aug 2022 13:54:02 +0100 Subject: [PATCH 187/430] [sequence.reqmts] Use "program-defined sequence container" consistently. The earlier wording of "containers that the user defines" was not retained for new additions to the Standard, and it is needlessly informal. The term "program-defined" was only added recently, whereas the original wording has essentially existed since the beginnig. --- source/containers.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/containers.tex b/source/containers.tex index 223e37a24d..059045bcca 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -1238,7 +1238,7 @@ \tcode{array} is provided as a sequence container which provides limited sequence operations because it has a fixed number of elements. The library also provides container adaptors that make it easy to construct abstract data types, such as \tcode{stack}s, \tcode{queue}s, \tcode{flat_map}s, or \tcode{flat_multimap}s, out of -the basic sequence container kinds (or out of other kinds of sequence containers that the user defines). +the basic sequence container kinds (or out of other program-defined sequence containers). \pnum \begin{note} From 8ae820d3ac445c1af4c6be91354ac1ac84d2df52 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sun, 31 Jul 2022 12:58:47 +0200 Subject: [PATCH 188/430] P1222R4 A Standard flat_set --- source/containers.tex | 1223 ++++++++++++++++++++++++++++++++++++++++- source/lib-intro.tex | 1 + 2 files changed, 1219 insertions(+), 5 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index 059045bcca..bff7c915e4 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -26,7 +26,7 @@ \ref{unord} & Unordered associative containers & \tcode{}, \tcode{} \\ \rowsep \ref{container.adaptors} & Container adaptors & - \tcode{}, \tcode{}, \tcode{} \\ \rowsep + \tcode{}, \tcode{}, \tcode{}, \tcode{} \\ \rowsep \ref{views} & Views & \tcode{}, \tcode{} \\ \end{libsumtab} @@ -1237,7 +1237,13 @@ \tcode{vector}, \tcode{forward_list}, \tcode{list}, and \tcode{deque}. In addition, \tcode{array} is provided as a sequence container which provides limited sequence operations because it has a fixed number of elements. The library also provides container adaptors that -make it easy to construct abstract data types, such as \tcode{stack}s, \tcode{queue}s, \tcode{flat_map}s, or \tcode{flat_multimap}s, out of +make it easy to construct abstract data types, +such as \tcode{stack}s, +\tcode{queue}s, +\tcode{flat_map}s, +\tcode{flat_multimap}s, +\tcode{flat_set}s, or +\tcode{flat_multiset}s, out of the basic sequence container kinds (or out of other program-defined sequence containers). \pnum @@ -2520,7 +2526,8 @@ \tcode{multimap}. The library also provides container adaptors that make it easy to construct abstract data types, -such as \tcode{flat_map}s or \tcode{flat_multimap}s, +such as \tcode{flat_map}s, \tcode{flat_multimap}s, +\tcode{flat_set}s, or \tcode{flat_multiset}s, out of the basic sequence container kinds (or out of other program-defined sequence containers). @@ -12967,8 +12974,8 @@ \rSec2[container.adaptors.general]{In general} \pnum -The headers \libheader{queue}, \libheader{stack}, and \libheader{flat_map} define the container adaptors -\tcode{queue}, \tcode{priority_queue}, \tcode{stack}, and \tcode{flat_map}, respectively. +The headers \libheader{queue}, \libheader{stack}, \libheader{flat_map}, and \libheader{flat_set} define the container adaptors +\tcode{queue}, \tcode{priori\-ty_queue}, \tcode{stack}, \tcode{flat_map}, and \tcode{flat_set}, respectively. \pnum Each container adaptor takes @@ -13166,6 +13173,41 @@ } \end{codeblock} +\rSec2[flat.set.syn]{Header \tcode{} synopsis}% +\indexheader{flat_set}% + +\begin{codeblock} +#include // see \ref{initializer.list.syn} + +namespace std { + // \ref{flat.set}, class template \tcode{flat_set} + template, class KeyContainer = vector> + class flat_set; + + struct sorted_unique_t { explicit sorted_unique_t() = default; }; + inline constexpr sorted_unique_t sorted_unique{}; + + template + size_t erase_if(flat_set& c, Predicate pred); + + template + struct uses_allocator, Allocator>; + + // \ref{flat.multiset}, class template \tcode{flat_multiset} + template, class KeyContainer = vector> + class flat_multiset; + + struct sorted_equivalent_t { explicit sorted_equivalent_t() = default; }; + inline constexpr sorted_equivalent_t sorted_equivalent{}; + + template + size_t erase_if(flat_multiset& c, Predicate pred); + + template + struct uses_allocator, Allocator>; +} +\end{codeblock} + \rSec2[queue]{Class template \tcode{queue}} \rSec3[queue.defn]{Definition} @@ -16086,6 +16128,1177 @@ \end{note} \end{itemdescr} +\rSec2[flat.set]{Class template \tcode{flat_set}} + +\rSec3[flat.set.overview]{Overview} + +\pnum +\indexlibraryglobal{flat_set}% +A \tcode{flat_set} is a container adaptor +that provides an associative container interface +that supports unique keys +(i.e., contains at most one of each key value) and +provides for fast retrieval of the keys themselves. +\tcode{flat_set} supports iterators that model +the \libconcept{random_access_iterator} concept\iref{iterator.concept.random.access}. + +\pnum +A \tcode{flat_set} meets all of the requirements +for a container\iref{container.reqmts} and +for a reversible container\iref{container.rev.reqmts}, +plus the optional container requirements\iref{container.opt.reqmts}. +\tcode{flat_set} meets the requirements of +an associative container\iref{associative.reqmts}, except that: +\begin{itemize} +\item +it does not meet the requirements +related to node handles\iref{container.node.overview}, +\item +it does not meet the requirements related to iterator invalidation, and +\item +the time complexity of the operations +that insert or erase a single element from the set +is linear, +including the ones that take an insertion position iterator. +\end{itemize} +\begin{note} +A \tcode{flat_set} does not meet +the additional requirements of an allocator-aware container, +as described in \ref{container.alloc.reqmts}. +\end{note} + +\pnum +A \tcode{flat_set} also provides most operations +described in \ref{associative.reqmts} for unique keys. +This means that a \tcode{flat_set} supports +the \tcode{a_uniq} operations in \ref{associative.reqmts}, +but not support the \tcode{a_eq} operations. +For a \tcode{flat_set}, +both the \tcode{key_type} and \tcode{value_type} are \tcode{Key}. + +\pnum +Descriptions are provided here only for operations on \tcode{flat_set} +that are not described in one of those sets of requirements or +for operations where there is additional semantic information. + +\pnum +A \tcode{flat_set} maintains the invariant that the keys are sorted with +respect to the comparison object. + +\pnum +If any member function in \ref{flat.set.defn} exits via an exception, +the invariant is restored. +\begin{note} +This can result in the \tcode{flat_set}'s being emptied. +\end{note} + +\pnum +Any sequence container\iref{sequence.reqmts} +supporting \oldconcept{RandomAccessIterator} +can be used to instantiate \tcode{flat_set}. +In particular, \tcode{vector}\iref{vector} and \tcode{deque}\iref{deque} +can be used. +\begin{note} +\tcode{vector} is not a sequence container. +\end{note} + +\pnum +The program is ill-formed if \tcode{Key} is not the same type +as \tcode{KeyContainer::value_type}. + +\pnum +The effect of calling a constructor or member function +that takes a \tcode{sorted_unique_t} argument +with a range that is not sorted with respect to \tcode{key_comp()}, or +that contains equal elements, is undefined. + +\rSec3[flat.set.defn]{Definition} + +\begin{codeblock} +namespace std { + template, class KeyContainer = vector> + class @\libglobal{flat_set}@ { + public: + // types + using key_type = Key; + using value_type = Key; + using key_compare = Compare; + using value_compare = Compare; + using reference = value_type&; + using const_reference = const value_type&; + using size_type = typename KeyContainer::size_type; + using difference_type = typename KeyContainer::difference_type; + using iterator = @\impdefx{type of \tcode{flat_set::iterator}}@; // see \ref{container.requirements} + using const_iterator = @\impdefx{type of \tcode{flat_set::const_iterator}}@; // see \ref{container.requirements} + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + using container_type = KeyContainer; + + // \ref{flat.set.ctor}, constructors + flat_set() : flat_set(key_compare()) { } + + explicit flat_set(container_type cont); + template + flat_set(const container_type& cont, const Allocator& a); + + flat_set(sorted_unique_t, container_type cont) + : c(std::move(cont)), compare(key_compare()) { } + template + flat_set(sorted_unique_t, const container_type& cont, const Allocator& a); + + explicit flat_set(const key_compare& comp) + : c(), compare(comp) { } + template + flat_set(const key_compare& comp, const Allocator& a); + template + explicit flat_set(const Allocator& a); + + template + flat_set(InputIterator first, InputIterator last, + const key_compare& comp = key_compare()) + : c(), compare(comp) + { insert(first, last); } + template + flat_set(InputIterator first, InputIterator last, + const key_compare& comp, const Allocator& a); + template + flat_set(InputIterator first, InputIterator last, const Allocator& a); + + template<@\exposconcept{container-compatible-range}@ R> + flat_set(from_range_t fr, R&& rg) + : flat_set(fr, std::forward(range), key_compare()) { } + template<@\exposconcept{container-compatible-range}@ R, class Allocator> + flat_set(from_range_t, R&& rg, const Allocator& a); + template<@\exposconcept{container-compatible-range}@ R> + flat_set(from_range_t, R&& rg, const key_compare& comp) + : flat_set(comp) + { insert_range(std::forward(range)); } + template<@\exposconcept{container-compatible-range}@ R, class Allocator> + flat_set(from_range_t, R&& rg, const key_compare& comp, + const Allocator& a); + + template + flat_set(sorted_unique_t, InputIterator first, InputIterator last, + const key_compare& comp = key_compare()) + : c(first, last), compare(comp) { } + template + flat_set(sorted_unique_t, InputIterator first, InputIterator last, + const key_compare& comp, const Allocator& a); + template + flat_set(sorted_unique_t, InputIterator first, InputIterator last, + const Allocator& a); + + flat_set(initializer_list il, + const key_compare& comp = key_compare()) + : flat_set(il.begin(), il.end(), comp) { } + template + flat_set(initializer_list il, + const key_compare& comp, const Allocator& a); + template + flat_set(initializer_list il, const Allocator& a); + + flat_set(sorted_unique_t s, initializer_list il, + const key_compare& comp = key_compare()) + : flat_set(s, il.begin(), il.end(), comp) { } + template + flat_set(sorted_unique_t, initializer_list il, + const key_compare& comp, const Allocator& a); + template + flat_set(sorted_unique_t, initializer_list il, + const Allocator& a); + + flat_set& operator=(initializer_list); + + // iterators + iterator begin() noexcept; + const_iterator begin() const noexcept; + iterator end() noexcept; + const_iterator end() const noexcept; + + reverse_iterator rbegin() noexcept; + const_reverse_iterator rbegin() const noexcept; + reverse_iterator rend() noexcept; + const_reverse_iterator rend() const noexcept; + + const_iterator cbegin() const noexcept; + const_iterator cend() const noexcept; + const_reverse_iterator crbegin() const noexcept; + const_reverse_iterator crend() const noexcept; + + // capacity + [[nodiscard]] bool empty() const noexcept; + size_type size() const noexcept; + size_type max_size() const noexcept; + + // \ref{flat.set.modifiers}, modifiers + template pair emplace(Args&&... args); + template + iterator emplace_hint(const_iterator position, Args&&... args); + + pair insert(const value_type& x) + { return emplace(x); } + pair insert(value_type&& x) + { return emplace(std::move(x)); } + template pair insert(K&& x); + iterator insert(const_iterator position, const value_type& x) + { return emplace_hint(position, x); } + iterator insert(const_iterator position, value_type&& x) + { return emplace_hint(position, std::move(x)); } + template iterator insert(const_iterator hint, K&& x); + + template + void insert(InputIterator first, InputIterator last); + template + void insert(sorted_unique_t, InputIterator first, InputIterator last); + template<@\exposconcept{container-compatible-range}@ R> + void insert_range(R&& rg); + + void insert(initializer_list il) + { insert(il.begin(), il.end()); } + void insert(sorted_unique_t s, initializer_list il) + { insert(s, il.begin(), il.end()); } + + container_type extract() &&; + void replace(container_type&&); + + iterator erase(iterator position); + iterator erase(const_iterator position); + size_type erase(const key_type& x); + template size_type erase(K&& x); + iterator erase(const_iterator first, const_iterator last); + + void swap(flat_set& y) noexcept; + void clear() noexcept; + + // observers + key_compare key_comp() const; + value_compare value_comp() const; + + // set operations + iterator find(const key_type& x); + const_iterator find(const key_type& x) const; + template iterator find(const K& x); + template const_iterator find(const K& x) const; + + size_type count(const key_type& x) const; + template size_type count(const K& x) const; + + bool contains(const key_type& x) const; + template bool contains(const K& x) const; + + iterator lower_bound(const key_type& x); + const_iterator lower_bound(const key_type& x) const; + template iterator lower_bound(const K& x); + template const_iterator lower_bound(const K& x) const; + + iterator upper_bound(const key_type& x); + const_iterator upper_bound(const key_type& x) const; + template iterator upper_bound(const K& x); + template const_iterator upper_bound(const K& x) const; + + pair equal_range(const key_type& x); + pair equal_range(const key_type& x) const; + template + pair equal_range(const K& x); + template + pair equal_range(const K& x) const; + + friend bool operator==(const flat_set& x, const flat_set& y); + + friend @\placeholder{synth-three-way-result}@ + operator<=>(const flat_set& x, const flat_set& y); + + friend void swap(flat_set& x, flat_set& y) noexcept { x.swap(y); } + + private: + container_type @\exposid{c}@; // \expos + key_compare @\exposid{compare}@; // \expos + }; + + template>> + flat_set(InputIterator, InputIterator, Compare = Compare()) + -> flat_set<@\placeholder{iter-value-type}@, Compare>; + + template>> + flat_set(sorted_unique_t, InputIterator, InputIterator, Compare = Compare()) + -> flat_set<@\placeholder{iter-value-type}@, Compare>; + + template>, + class Allocator = allocator>> + flat_set(from_range_t, R&&, Compare = Compare(), Allocator = Allocator()) + -> flat_set, Compare>; + + template + flat_set(from_range_t, R&&, Allocator) + -> flat_set, less>>; + + template> + flat_set(initializer_list, Compare = Compare()) + -> flat_set; + + template> + flat_set(sorted_unique_t, initializer_list, Compare = Compare()) + -> flat_set; + + template + struct uses_allocator, Allocator> + : bool_constant> { }; +} +\end{codeblock} + +\rSec3[flat.set.ctor]{Constructors} + +\indexlibraryctor{flat_set}% +\begin{itemdecl} +flat_set(container_type cont); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \exposid{c} with \tcode{std::move(cont)}, +value-initializes \tcode{compare}, +sorts the range \range{begin()}{end()} with respect to \tcode{compare}, and +finally erases all but the first element +from each group of consecutive equivalent elements. + +\pnum +\complexity +Linear in $N$ if \tcode{cont} is sorted with respect to \tcode{compare} and +otherwise $N \log N$, where $N$ is \tcode{cont.size()}. +\end{itemdescr} + +\indexlibraryctor{flat_set}% +\begin{itemdecl} +template + flat_set(const container_type& cont, const Allocator& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{uses_allocator_v} is \tcode{true}. + +\pnum +\effects +Equivalent to \tcode{flat_set(cont)}, +except that \exposid{c} is constructed with +uses-allocator construction\iref{allocator.uses.construction}. + +\pnum +\complexity +Same as \tcode{flat_set(cont)}. +\end{itemdescr} + +\indexlibraryctor{flat_set}% +\begin{itemdecl} +template + flat_set(sorted_unique_t s, const container_type& cont, const Allocator& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{uses_allocator_v} is \tcode{true}. + +\pnum +\effects +Equivalent to \tcode{flat_set(s, cont)}, +except that \exposid{c} is constructed with +uses-allocator construction\iref{allocator.uses.construction}. + +\pnum +\complexity +Linear. +\end{itemdescr} + +\indexlibraryctor{flat_set}% +\begin{itemdecl} +template + flat_set(const key_compare& comp, const Allocator& a); +template + explicit flat_set(const Allocator& a); +template + flat_set(InputIterator first, InputIterator last, + const key_compare& comp, const Allocator& a); +template + flat_set(InputIterator first, InputIterator last, const Allocator& a); +template<@\exposconcept{container-compatible-range}@ R, class Allocator> + flat_set(from_range_t, R&& rg, const Allocator& a); +template<@\exposconcept{container-compatible-range}@ R, class Allocator> + flat_set(from_range_t, R&& rg, const key_compare& comp, const Allocator& a); +template + flat_set(sorted_unique_t, InputIterator first, InputIterator last, + const key_compare& comp, const Allocator& a); +template + flat_set(sorted_unique_t, InputIterator first, InputIterator last, const Allocator& a); +template + flat_set(initializer_list il, const key_compare& comp, const Allocator& a); +template + flat_set(initializer_list il, const Allocator& a); +template + flat_set(sorted_unique_t, initializer_list il, + const key_compare& comp, const Allocator& a); +template + flat_set(sorted_unique_t, initializer_list il, const Allocator& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{uses_allocator_v} is \tcode{true}. + +\pnum +\effects +Equivalent to the corresponding non-allocator constructors +except that \exposid{c} is constructed with +uses-allocator construction\iref{allocator.uses.construction}. +\end{itemdescr} + +\rSec3[flat.set.modifiers]{Modifiers} + +\indexlibrarymember{insert}{flat_set}% +\begin{itemdecl} +template pair insert(K&& x); +template iterator insert(const_iterator hint, K&& x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +The \grammarterm{qualified-id} \tcode{Compare::is_transparent} +is valid and denotes a type. +\tcode{is_constructi\-ble_v} is \tcode{true}. + +\pnum +\expects +The conversion from \tcode{x} into \tcode{value_type} constructs +an object \tcode{u}, for which \tcode{find(x) == find(u)} is true. + +\pnum +\effects +If the set already contains an element equivalent to \tcode{x}, +\tcode{*this} and \tcode{x} are unchanged. +Otherwise, +inserts a new element as if by: \tcode{return emplace(std::forward(x));}. + +\pnum +\returns +In the first overload, +the \tcode{bool} component of the returned pair is \tcode{true} +if and only if the insertion took place. +The returned iterator points to the element +whose key is equivalent to \tcode{x}. +\end{itemdescr} + +\indexlibrarymember{insert}{flatset}% +\begin{itemdecl} +template + void insert(InputIterator first, InputIterator last); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Adds elements to \exposid{c} as if by: +\begin{codeblock} +c.insert(c.end(), first, last); +\end{codeblock} +Then, +sorts the range of newly inserted elements with respect to \tcode{compare}; +merges the resulting sorted range and +the sorted range of pre-existing elements into a single sorted range; and +finally erases all but the first element +from each group of consecutive equivalent elements. + +\pnum +\complexity +$N$ + $M \log M$, where $N$ is \tcode{size()} before the operation and +$M$ is \tcode{distance(first, last)}. + +\pnum +\remarks +Since this operation performs an in-place merge, it may allocate memory. +\end{itemdescr} + +\indexlibrarymember{insert}{flat_set}% +\begin{itemdecl} +template + void insert(sorted_unique_t, InputIterator first, InputIterator last); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{insert(first, last)}. + +\pnum +\complexity +Linear. +\end{itemdescr} + +\indexlibrarymember{insert_range}{flat_set}% +\begin{itemdecl} +template<@\exposconcept{container-compatible-range}@ R> + void insert_range(R&& rg); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Adds elements to \exposid{c} as if by: +\begin{codeblock} +for (const auto& e : rg) { + c.insert(c.end(), e); +} +\end{codeblock} +Then, +sorts the range of newly inserted elements with respect to \tcode{compare}; +merges the resulting sorted range and +the sorted range of pre-existing elements into a single sorted range; and +finally erases all but the first element +from each group of consecutive equivalent elements. + +\pnum +\complexity +$N$ + $M \log M$, where $N$ is \tcode{size()} before the operation and $M$ +is \tcode{distance(first, last)}. + +\pnum +\remarks +Since this operation performs an in-place merge, it may allocate memory. +\end{itemdescr} + +\indexlibrarymember{swap}{flat_set}% +\begin{itemdecl} +void swap(flat_set& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +ranges::swap(compare, y.compare); +ranges::swap(c, y.c); +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{extract}{flatset}% +\begin{itemdecl} +container_type extract() &&; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\ensures +\tcode{*this} is emptied, even if the function exits via an exception. + +\pnum +\returns +\tcode{std::move(c)}. +\end{itemdescr} + +\indexlibrarymember{replace}{flat_set}% +\begin{itemdecl} +void replace(container_type&& cont); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +The elements of \tcode{cont} are sorted with respect to \tcode{compare} and +contain no equal elements. + +\pnum +\effects +Equivalent to: \tcode{c = std::move(cont);} +\end{itemdescr} + +\rSec3[flat.set.erasure]{Erasure} + +\indexlibrarymember{erase_if}{flat_set}% +\begin{itemdecl} +template + size_t erase_if(flat_set& c, Predicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto [erase_first, erase_last] = ranges::remove_if(c, pred); +auto n = erase_last - erase_first; +c.erase(erase_first, erase_last); +return n; +\end{codeblock} +\end{itemdescr} + +\rSec2[flat.multiset]{Class template \tcode{flat_multiset}} + +\rSec3[flat.multiset.overview]{Overview} + +\pnum +\indexlibraryglobal{flat_multiset}% +A \tcode{flat_multiset} is a container adaptor +that provides an associative container interface +that supports equivalent keys +(i.e., possibly containing multiple copies of the same key value) and +provides for fast retrieval of the keys themselves. +\tcode{flat_multiset} supports iterators that model the +\libconcept{random_access_iterator} concept\iref{iterator.concept.random.access}. + +\pnum +A \tcode{flat_multiset} meets all of the requirements +for a container\iref{container.reqmts} and +for a reversible container\iref{container.rev.reqmts}, +plus the optional container requirements\iref{container.opt.reqmts}. +\tcode{flat_multiset} meets the requirements of +an associative container\iref{associative.reqmts}, except that: +\begin{itemize} +\item +it does not meet the requirements +related to node handles\iref{container.node.overview}, +\item +it does not meet the requirements related to iterator invalidation, and +\item +the time complexity of the operations +that insert or erase a single element from the +set is linear, +including the ones that take an insertion position iterator. +\end{itemize} +\begin{note} +A \tcode{flat_multiset} does not meet +the additional requirements of an allocator-aware container, +as described in \ref{container.alloc.reqmts}. +\end{note} + +\pnum +A \tcode{flat_multiset} also provides most operations +described in \ref{associative.reqmts} for equal keys. +This means that a \tcode{flat_multiset} supports +the \tcode{a_eq} operations in \ref{associative.reqmts}, +but not the \tcode{a_uniq} operations. +For a \tcode{flat_mutliset}, +both the \tcode{key_type} and \tcode{value_type} are \tcode{Key}. + +\pnum +Descriptions are provided here only for operations on \tcode{flat_multiset} +that are not described in one of the general sections or +for operations where there is additional semantic information. + +\pnum +A \tcode{flat_multiset} maintains the invariant +that the keys are sorted with respect to the comparison object. + +\pnum +If any member function in \ref{flat.multiset.defn} exits via an exception, +the invariant is restored. +\begin{note} +This can result in the \tcode{flat_multiset}'s being emptied. +\end{note} + +\pnum +Any sequence container\iref{sequence.reqmts} +supporting \oldconcept{RandomAccessIterator} +can be used to instantiate \tcode{flat_multiset}. +In particular, +\tcode{vector}\iref{vector} and \tcode{deque}\iref{deque} can be used. +\begin{note} +\tcode{vector} is not a sequence container. +\end{note} + +\pnum +The program is ill-formed if \tcode{Key} is not the same type +as \tcode{KeyContainer::value_type}. + +\pnum +The effect of calling a constructor or member function +that takes a \tcode{sorted_equivalent_t} argument with a range +that is not sorted with respect to \tcode{key_comp()} is undefined. + +\rSec3[flat.multiset.defn]{Definition} + +\begin{codeblock} +namespace std { + template, class KeyContainer = vector> + class flat_multiset { + public: + // types + using key_type = Key; + using value_type = Key; + using key_compare = Compare; + using value_compare = Compare; + using reference = value_type&; + using const_reference = const value_type&; + using size_type = typename KeyContainer::size_type; + using difference_type = typename KeyContainer::difference_type; + using iterator = @\impdefx{type of \tcode{flat_multiset::iterator}}@; // see \ref{container.requirements} + using const_iterator = @\impdefx{type of \tcode{flat_multiset::const_iterator}}@; // see \ref{container.requirements} + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + using container_type = KeyContainer; + + // \ref{flat.multiset.ctor}, constructors + flat_multiset() : flat_multiset(key_compare()) { } + + explicit flat_multiset(container_type cont); + template + flat_multiset(const container_type& cont, const Allocator& a); + + flat_multiset(sorted_equivalent_t, container_type cont) + : c(std::move(cont)), compare(key_compare()) { } + template + flat_multiset(sorted_equivalent_t, const container_type&, const Allocator& a); + + explicit flat_multiset(const key_compare& comp) + : c(), compare(comp) { } + template + flat_multiset(const key_compare& comp, const Allocator& a); + template + explicit flat_multiset(const Allocator& a); + + template + flat_multiset(InputIterator first, InputIterator last, + const key_compare& comp = key_compare()) + : c(), compare(comp) + { insert(first, last); } + template + flat_multiset(InputIterator first, InputIterator last, + const key_compare& comp, const Allocator& a); + template + flat_multiset(InputIterator first, InputIterator last, + const Allocator& a); + + template<@\exposconcept{container-compatible-range}@ R> + flat_multiset(from_range_t fr, R&& rg) + : flat_multiset(fr, std::forward(range), key_compare()) { } + template<@\exposconcept{container-compatible-range}@ R, class Allocator> + flat_multiset(from_range_t, R&& rg, const Allocator& a); + template<@\exposconcept{container-compatible-range}@ R> + flat_multiset(from_range_t, R&& rg, const key_compare& comp) + : flat_multiset(comp) + { insert_range(std::forward(range)); } + template<@\exposconcept{container-compatible-range}@ R, class Allocator> + flat_multiset(from_range_t, R&& rg, const key_compare& comp, + const Allocator& a); + + template + flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, + const key_compare& comp = key_compare()) + : c(first, last), compare(comp) { } + template + flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, + const key_compare& comp, const Allocator& a); + template + flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, + const Allocator& a); + + flat_multiset(initializer_list il, + const key_compare& comp = key_compare()) + : flat_multiset(il.begin(), il.end(), comp) { } + template + flat_multiset(initializer_list il, + const key_compare& comp, const Allocator& a); + template + flat_multiset(initializer_list il, const Allocator& a); + + flat_multiset(sorted_equivalent_t s, initializer_list il, + const key_compare& comp = key_compare()) + : flat_multiset(s, il.begin(), il.end(), comp) { } + template + flat_multiset(sorted_equivalent_t, initializer_list il, + const key_compare& comp, const Allocator& a); + template + flat_multiset(sorted_equivalent_t, initializer_list il, + const Allocator& a); + + flat_multiset& operator=(initializer_list); + + // iterators + iterator begin() noexcept; + const_iterator begin() const noexcept; + iterator end() noexcept; + const_iterator end() const noexcept; + + reverse_iterator rbegin() noexcept; + const_reverse_iterator rbegin() const noexcept; + reverse_iterator rend() noexcept; + const_reverse_iterator rend() const noexcept; + + const_iterator cbegin() const noexcept; + const_iterator cend() const noexcept; + const_reverse_iterator crbegin() const noexcept; + const_reverse_iterator crend() const noexcept; + + // capacity + [[nodiscard]] bool empty() const noexcept; + size_type size() const noexcept; + size_type max_size() const noexcept; + + // \ref{flat.multiset.modifiers}, modifiers + template iterator emplace(Args&&... args); + template + iterator emplace_hint(const_iterator position, Args&&... args); + + iterator insert(const value_type& x) + { return emplace(x); } + iterator insert(value_type&& x) + { return emplace(std::move(x)); } + iterator insert(const_iterator position, const value_type& x) + { return emplace_hint(position, x); } + iterator insert(const_iterator position, value_type&& x) + { return emplace_hint(position, std::move(x)); } + + template + void insert(InputIterator first, InputIterator last); + template + void insert(sorted_equivalent_t, InputIterator first, InputIterator last); + template<@\exposconcept{container-compatible-range}@ R> + void insert_range(R&& rg); + + void insert(initializer_list il) + { insert(il.begin(), il.end()); } + void insert(sorted_equivalent_t s, initializer_list il) + { insert(s, il.begin(), il.end()); } + + container_type extract() &&; + void replace(container_type&&); + + iterator erase(iterator position); + iterator erase(const_iterator position); + size_type erase(const key_type& x); + template size_type erase(K&& x); + iterator erase(const_iterator first, const_iterator last); + + void swap(flat_multiset& y) noexcept; + void clear() noexcept; + + // observers + key_compare key_comp() const; + value_compare value_comp() const; + + // set operations + iterator find(const key_type& x); + const_iterator find(const key_type& x) const; + template iterator find(const K& x); + template const_iterator find(const K& x) const; + + size_type count(const key_type& x) const; + template size_type count(const K& x) const; + + bool contains(const key_type& x) const; + template bool contains(const K& x) const; + + iterator lower_bound(const key_type& x); + const_iterator lower_bound(const key_type& x) const; + template iterator lower_bound(const K& x); + template const_iterator lower_bound(const K& x) const; + + iterator upper_bound(const key_type& x); + const_iterator upper_bound(const key_type& x) const; + template iterator upper_bound(const K& x); + template const_iterator upper_bound(const K& x) const; + + pair equal_range(const key_type& x); + pair equal_range(const key_type& x) const; + template + pair equal_range(const K& x); + template + pair equal_range(const K& x) const; + + friend bool operator==(const flat_multiset& x, const flat_multiset& y); + + friend @\placeholder{synth-three-way-result}@ + operator<=>(const flat_multiset& x, const flat_multiset& y); + + friend void swap(flat_multiset& x, flat_multiset& y) noexcept + { x.swap(y); } + + private: + container_type @\exposid{c}@; // \expos + key_compare @\exposid{compare}@; // \expos + }; + + template>> + flat_multiset(InputIterator, InputIterator, Compare = Compare()) + -> flat_multiset<@\placeholder{iter-value-type}@, @\placeholder{iter-value-type}@, Compare>; + + template>> + flat_multiset(sorted_equivalent_t, InputIterator, InputIterator, Compare = Compare()) + -> flat_multiset<@\placeholder{iter-value-type}@, @\placeholder{iter-value-type}@, Compare>; + + template>, + class Allocator = allocator>> + flat_multiset(from_range_t, R&&, Compare = Compare(), Allocator = Allocator()) + -> flat_multiset, Compare>; + + template + flat_multiset(from_range_t, R&&, Allocator) + -> flat_multiset, less>>; + + template> + flat_multiset(initializer_list, Compare = Compare()) + -> flat_multiset; + + template> + flat_multiset(sorted_equivalent_t, initializer_list, Compare = Compare()) + -> flat_multiset; + + template + struct uses_allocator, Allocator> + : bool_constant> { }; +} +\end{codeblock} + +\rSec3[flat.multiset.ctor]{Constructors} + +\indexlibraryctor{flat_multiset}% +\begin{itemdecl} +flat_multiset(container_type cont); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \exposid{c} with \tcode{std::move(cont)}, +value-initializes \exposid{compare}, and +sorts the range \range{begin()}{end()} with respect to \exposid{compare}. + +\pnum +\complexity +Linear in $N$ if \tcode{cont} is sorted with respect to \exposid{compare} and +otherwise $N \log N$, where $N$ is \tcode{cont.size()}. +\end{itemdescr} + +\indexlibraryctor{flat_multiset}% +\begin{itemdecl} +template + flat_multiset(const container_type& cont, const Allocator& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{uses_allocator_v} is \tcode{true}. + +\pnum +\effects +Equivalent to \tcode{flat_multiset(cont)}, +except that \exposid{c} is constructed with +uses-allocator construction\iref{allocator.uses.construction}. + +\pnum +\complexity +Same as \tcode{flat_multiset(cont)}. +\end{itemdescr} + +\indexlibraryctor{flat_multiset}% +\begin{itemdecl} +template + flat_multiset(sorted_equivalent_t s, const container_type&, const Allocator& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{uses_allocator_v} is \tcode{true}. + +\pnum +\effects +Equivalent to \tcode{flat_multiset(s, cont)}, +except that \exposid{c} is constructed with +uses-allocator construction\iref{allocator.uses.construction}. + +\pnum +\complexity +Linear. +\end{itemdescr} + +\indexlibraryctor{flat_multiset}% +\begin{itemdecl} +template + flat_multiset(const key_compare& comp, const Allocator& a); +template + explicit flat_multiset(const Allocator& a); +template + flat_multiset(InputIterator first, InputIterator last, + const key_compare& comp, const Allocator& a); +template + flat_multiset(InputIterator first, InputIterator last, + const Allocator& a); +template<@\exposconcept{container-compatible-range}@ R, class Allocator> + flat_multiset(from_range_t, R&& rg, const Allocator& a); +template<@\exposconcept{container-compatible-range}@ R, class Allocator> + flat_multiset(from_range_t, R&& rg, const key_compare& comp, + const Allocator& a); +template + flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, + const key_compare& comp, const Allocator& a); +template + flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, + const Allocator& a); +template + flat_multiset(initializer_list il, + const key_compare& comp, const Allocator& a); +template + flat_multiset(initializer_list il, const Allocator& a); +template + flat_multiset(sorted_equivalent_t, initializer_list il, + const key_compare& comp, const Allocator& a); +template + flat_multiset(sorted_equivalent_t, initializer_list il, + const Allocator& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{uses_allocator_v} is \tcode{true}. + +\pnum +\effects +Equivalent to the corresponding non-allocator constructors +except that \exposid{c} is constructed with +uses-allocator construction\iref{allocator.uses.construction}. +\end{itemdescr} + +\rSec3[flat.multiset.modifiers]{Modifiers} + +\indexlibrarymember{emplace}{flat_multiset}% +\begin{itemdecl} +template iterator emplace(Args&&... args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_constructible_v} is \tcode{true}. + +\pnum +\effects +First, initializes an object \tcode{t} of type \tcode{key_type} +with \tcode{std::forward(args)...}, +then inserts \tcode{t} as if by: +\begin{codeblock} +auto it = ranges::upper_bound(c, t, compare); +c.insert(it, std::move(t)); +\end{codeblock} + +\pnum +\returns +An iterator that points to the inserted element. +\end{itemdescr} + +\indexlibrarymember{insert}{flat_mulitset}% +\begin{itemdecl} +template + void insert(InputIterator first, InputIterator last); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Adds elements to \exposid{c} as if by: +\begin{codeblock} +c.insert(c.end(), first, last); +\end{codeblock} +Then, sorts the range of newly inserted elements with respect to \exposid{compare}, +and merges the resulting sorted range and +the sorted range of pre-existing elements into a single sorted range. + +\pnum +\complexity +$N$ + $M \log M$, where $N$ is \tcode{size()} before the operation and $M$ +is \tcode{distance(first, last)}. + +\pnum +\remarks +Since this operation performs an in-place merge, it may allocate memory. +\end{itemdescr} + +\indexlibrarymember{insert}{flat_multiset}% +\begin{itemdecl} +template + void insert(sorted_equivalent_t, InputIterator first, InputIterator last); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{insert(first, last)}. + +\pnum +\complexity +Linear. +\end{itemdescr} + +\indexlibrarymember{swap}{flat_multiset}% +\begin{itemdecl} +void swap(flat_multiset& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +ranges::swap(compare, y.compare); +ranges::swap(c, y.c); +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{extract}{flat_multiset}% +\begin{itemdecl} +container_type extract() &&; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\ensures +\tcode{*this} is emptied, even if the function exits via an exception. + +\pnum +\returns +\tcode{std::move(c)}. +\end{itemdescr} + +\indexlibrarymember{replace}{flat_multiset}% +\begin{itemdecl} +void replace(container_type&& cont); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +The elements of \tcode{cont} are sorted with respect to \exposid{compare}. + +\pnum +\effects +Equivalent to: \tcode{c = std::move(cont);} +\end{itemdescr} + +\rSec3[flat.multiset.erasure]{Erasure} + +\indexlibrarymember{erase_if}{flatmultiset}% +\begin{itemdecl} +template + size_t erase_if(flat_multiset& c, Predicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto [erase_first, erase_last] = ranges::remove_if(c, pred); +auto n = erase_last - erase_first; +c.erase(erase_first, erase_last); +return n; +\end{codeblock} +\end{itemdescr} + \rSec1[views]{Views} \rSec2[views.general]{General} diff --git a/source/lib-intro.tex b/source/lib-intro.tex index 208b8cd8c4..dfef1f18ae 100644 --- a/source/lib-intro.tex +++ b/source/lib-intro.tex @@ -1035,6 +1035,7 @@ \tcode{} \\ \columnbreak \tcode{} \\ +\tcode{} \\ \tcode{} \\ \tcode{} \\ \tcode{} \\ From 3ed0b41fe8c08f2ee0a8d1cdd3d5697d9a0733bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Sun, 14 Aug 2022 19:17:11 +0100 Subject: [PATCH 189/430] [flat.set.modifiers] Fix subject of subclause. --- source/containers.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index bff7c915e4..36f6974326 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -16707,8 +16707,8 @@ \begin{itemdescr} \pnum \expects -The elements of \tcode{cont} are sorted with respect to \tcode{compare} and -contain no equal elements. +The elements of \tcode{cont} are sorted with respect to \tcode{compare}, and +\tcode{cont} contains no equal elements. \pnum \effects From 66b8666296d4b833e00aac005bb80f3e522e97ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Sun, 14 Aug 2022 19:25:26 +0100 Subject: [PATCH 190/430] [flat.{,multi}set.ctor] Clarify that the state before the move is meant. --- source/containers.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index 36f6974326..666252944d 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -16465,7 +16465,7 @@ \pnum \complexity Linear in $N$ if \tcode{cont} is sorted with respect to \tcode{compare} and -otherwise $N \log N$, where $N$ is \tcode{cont.size()}. +otherwise $N \log N$, where $N$ is the value of \tcode{cont.size()} before this call. \end{itemdescr} \indexlibraryctor{flat_set}% @@ -17069,7 +17069,7 @@ \pnum \complexity Linear in $N$ if \tcode{cont} is sorted with respect to \exposid{compare} and -otherwise $N \log N$, where $N$ is \tcode{cont.size()}. +otherwise $N \log N$, where $N$ is the value of \tcode{cont.size()} before this call. \end{itemdescr} \indexlibraryctor{flat_multiset}% From 0e00e2528f535c41a3cdf4464c8bd745737a43ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Sun, 14 Aug 2022 20:47:16 +0100 Subject: [PATCH 191/430] [container.adaptors.general] Also mention flat_multi{map,set} adaptors. Also group the names-per-header by joining them with "and", to make the use of "respectively" less confusing. --- source/containers.tex | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index 666252944d..5ff2b37d95 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -12974,8 +12974,17 @@ \rSec2[container.adaptors.general]{In general} \pnum -The headers \libheader{queue}, \libheader{stack}, \libheader{flat_map}, and \libheader{flat_set} define the container adaptors -\tcode{queue}, \tcode{priori\-ty_queue}, \tcode{stack}, \tcode{flat_map}, and \tcode{flat_set}, respectively. +The headers +\libheader{queue}, +\libheader{stack}, +\libheader{flat_map}, +and \libheader{flat_set} +define the container adaptors +\tcode{queue} and \tcode{priority_queue}, +\tcode{stack}, +\tcode{flat_map} and \tcode{flat_multimap}, +and \tcode{flat_set} and \tcode{flat_multiset}, +respectively. \pnum Each container adaptor takes From 10bab7b9c0cf1b36e61d2583d0ca312a5c2c3311 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sun, 24 Jul 2022 12:51:32 +0200 Subject: [PATCH 192/430] P1223R5 find_last --- source/algorithms.tex | 72 +++++++++++++++++++++++++++++++++++++++++++ source/support.tex | 1 + 2 files changed, 73 insertions(+) diff --git a/source/algorithms.tex b/source/algorithms.tex index 04cb156bc8..04273a3283 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -780,6 +780,29 @@ find_if_not(R&& r, Pred pred, Proj proj = {}); } + // \ref{alg.find.last}, find last + namespace ranges { + template<@\libconcept{forward_iterator}@ I, @\libconcept{sentinel_for}@ S, class T, class Proj = identity> + requires @\libconcept{indirect_binary_predicate}@, const T*> + constexpr subrange find_last(I first, S last, const T& value, Proj proj = {}); + template<@\libconcept{forward_range}@ R, class T, class Proj = identity> + requires + @\libconcept{indirect_binary_predicate}@, Proj>, const T*> + constexpr borrowed_subrange_t find_last(R&& r, const T& value, Proj proj = {}); + template<@\libconcept{forward_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + @\libconcept{indirect_unary_predicate}@> Pred> + constexpr subrange find_last_if(I first, S last, Pred pred, Proj proj = {}); + template<@\libconcept{forward_range}@ R, class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + constexpr borrowed_subrange_t find_last_if(R&& r, Pred pred, Proj proj = {}); + template<@\libconcept{forward_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + @\libconcept{indirect_unary_predicate}@> Pred> + constexpr subrange find_last_if_not(I first, S last, Pred pred, Proj proj = {}); + template<@\libconcept{forward_range}@ R, class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + constexpr borrowed_subrange_t find_last_if_not(R&& r, Pred pred, Proj proj = {}); + } + // \ref{alg.find.end}, find end template constexpr ForwardIterator1 @@ -3514,6 +3537,55 @@ of the corresponding predicate and any projection. \end{itemdescr} +\rSec2[alg.find.last]{Find last} + +\indexlibraryglobal{find_last}% +\begin{itemdecl} +template<@\libconcept{forward_iterator}@ I, @\libconcept{sentinel_for}@ S, class T, class Proj = identity> + requires @\libconcept{indirect_binary_predicate}@, const T*> + constexpr subrange ranges::find_last(I first, S last, const T& value, Proj proj = {}); +template<@\libconcept{forward_range}@ R, class T, class Proj = identity> + requires @\libconcept{indirect_binary_predicate}@, Proj>, const T*> + constexpr borrowed_subrange_t ranges::find_last(R&& r, const T& value, Proj proj = {}); +template<@\libconcept{forward_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + @\libconcept{indirect_unary_predicate}@> Pred> + constexpr subrange ranges::find_last_if(I first, S last, Pred pred, Proj proj = {}); +template<@\libconcept{forward_range}@ R, class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + constexpr borrowed_subrange_t ranges::find_last_if(R&& r, Pred pred, Proj proj = {}); +template<@\libconcept{forward_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + @\libconcept{indirect_unary_predicate}@> Pred> + constexpr subrange ranges::find_last_if_not(I first, S last, Pred pred, Proj proj = {}); +template<@\libconcept{forward_range}@ R, class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + constexpr borrowed_subrange_t ranges::find_last_if_not(R&& r, Pred pred, Proj proj = {}); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let $E$ be: +\begin{itemize} +\item +\tcode{bool(invoke(proj, *i) == value)} for \tcode{ranges::find_last}; +\item +\tcode{bool(invoke(pred, invoke(proj, *i)))} for \tcode{ranges::find_last_if}; +\item +\tcode{bool(!invoke(pred, invoke(proj, *i)))} for \tcode{ranges::find_last_if_not}. +\end{itemize} + +\pnum +\returns +Let \tcode{i} be the last iterator in the range \range{first}{last} +for which $E$ is \tcode{true}. +Returns \tcode{\{i, last\}}, or +\tcode{\{last, last\}} if no such iterator is found. + +\pnum +\complexity +At most \tcode{last - first} applications of +the corresponding predicate and projection. +\end{itemdescr} + \rSec2[alg.find.end]{Find end} \indexlibraryglobal{find_end}% diff --git a/source/support.tex b/source/support.tex index cdcdaf1bbe..181fdf754f 100644 --- a/source/support.tex +++ b/source/support.tex @@ -616,6 +616,7 @@ #define @\defnlibxname{cpp_lib_execution}@ 201902L // also in \libheader{execution} #define @\defnlibxname{cpp_lib_expected}@ 202202L // also in \libheader{expected} #define @\defnlibxname{cpp_lib_filesystem}@ 201703L // also in \libheader{filesystem} +#define @\defnlibxname{cpp_lib_find_last}@ 202207L // also in \libheader{algorithm} #define @\defnlibxname{cpp_lib_flat_map}@ 202207L // also in \libheader{flat_map} #define @\defnlibxname{cpp_lib_format}@ 202110L // also in \libheader{format} #define @\defnlibxname{cpp_lib_gcd_lcm}@ 201606L // also in \libheader{numeric} From bedf8ccbc1c5fd2ee696525416b8d9d34835d9b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Mon, 15 Aug 2022 01:23:28 +0100 Subject: [PATCH 193/430] [actions] Use Ubuntu 22.04 (up from 20.04) --- .github/workflows/check.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 2c1415675c..4135d1d0f2 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -12,7 +12,7 @@ defaults: jobs: run-checks: name: Run checks - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - name: checkout From 283c483d814ae1ecce936f4c228c532ef4fe17d9 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Fri, 5 Aug 2022 21:28:05 -0700 Subject: [PATCH 194/430] P1642R11 Freestanding Library: Easy [utilities], [ranges], and [iterators] Also mark ATOMIC_FLAG_INIT as freestanding (added by LWG3659). --- source/concepts.tex | 1 + source/intro.tex | 14 +- source/iterators.tex | 289 ++++++++++++++++++++------------------- source/lib-intro.tex | 93 +++++++++---- source/memory.tex | 213 +++++++++++++++-------------- source/meta.tex | 2 + source/ranges.tex | 314 ++++++++++++++++++++++++------------------- source/support.tex | 42 ++++-- source/threads.tex | 310 ++++++++++++++++++++++-------------------- source/utilities.tex | 152 +++++++++++---------- 10 files changed, 793 insertions(+), 637 deletions(-) diff --git a/source/concepts.tex b/source/concepts.tex index bdd3512057..0cf400e29e 100644 --- a/source/concepts.tex +++ b/source/concepts.tex @@ -169,6 +169,7 @@ \indexheader{concepts}% \begin{codeblock} +// all freestanding namespace std { // \ref{concepts.lang}, language-related concepts // \ref{concept.same}, concept \libconcept{same_as} diff --git a/source/intro.tex b/source/intro.tex index f24ffd011f..cce294040a 100644 --- a/source/intro.tex +++ b/source/intro.tex @@ -844,12 +844,16 @@ \pnum Two kinds of implementations are defined: a \defnadj{hosted}{implementation} and a -\defnadj{freestanding}{implementation}. For a hosted implementation, this -document defines the set of available libraries. A freestanding +\defnadj{freestanding}{implementation}. +A freestanding implementation is one in which execution may take place without the benefit of -an operating system, and has an \impldef{required libraries for freestanding -implementation} set of libraries that includes certain language-support -libraries\iref{compliance}. +an operating system. +A hosted implementation +supports all the facilities described in this document, while +a freestanding implementation +supports the entire \Cpp{} language +described in \ref{lex} through \ref{cpp} and +the subset of the library facilities described in \ref{compliance}. \pnum A conforming implementation may have extensions (including diff --git a/source/iterators.tex b/source/iterators.tex index 9c9606b0ae..e8887b29f7 100644 --- a/source/iterators.tex +++ b/source/iterators.tex @@ -45,30 +45,30 @@ // \ref{iterator.assoc.types}, associated types // \ref{incrementable.traits}, incrementable traits - template struct incrementable_traits; + template struct incrementable_traits; // freestanding template - using iter_difference_t = @\seebelow@; + using iter_difference_t = @\seebelow@; // freestanding // \ref{readable.traits}, indirectly readable traits - template struct indirectly_readable_traits; + template struct indirectly_readable_traits; // freestanding template - using iter_value_t = @\seebelow@; + using iter_value_t = @\seebelow@; // freestanding // \ref{iterator.traits}, iterator traits - template struct iterator_traits; - template requires is_object_v struct iterator_traits; + template struct iterator_traits; // freestanding + template requires is_object_v struct iterator_traits; // freestanding template<@\exposconcept{dereferenceable}@ T> - using iter_reference_t = decltype(*declval()); + using iter_reference_t = decltype(*declval()); // freestanding namespace ranges { // \ref{iterator.cust}, customization point objects inline namespace @\unspec@ { // \ref{iterator.cust.move}, \tcode{ranges::iter_move} - inline constexpr @\unspec@ iter_move = @\unspec@; + inline constexpr @\unspec@ iter_move = @\unspec@; // freestanding // \ref{iterator.cust.swap}, \tcode{ranges::iter_swap} - inline constexpr @\unspec@ iter_swap = @\unspec@; + inline constexpr @\unspec@ iter_swap = @\unspec@; // freestanding } } @@ -76,324 +76,325 @@ requires requires(T& t) { { ranges::iter_move(t) } -> @\exposconcept{can-reference}@; } - using iter_rvalue_reference_t + using iter_rvalue_reference_t // freestanding = decltype(ranges::iter_move(declval())); // \ref{iterator.concepts}, iterator concepts // \ref{iterator.concept.readable}, concept \libconcept{indirectly_readable} template - concept indirectly_readable = @\seebelow@; + concept indirectly_readable = @\seebelow@; // freestanding template<@\libconcept{indirectly_readable}@ T> - using iter_common_reference_t = + using iter_common_reference_t = // freestanding common_reference_t, iter_value_t&>; // \ref{iterator.concept.writable}, concept \libconcept{indirectly_writable} template - concept indirectly_writable = @\seebelow@; + concept indirectly_writable = @\seebelow@; // freestanding // \ref{iterator.concept.winc}, concept \libconcept{weakly_incrementable} template - concept weakly_incrementable = @\seebelow@; + concept weakly_incrementable = @\seebelow@; // freestanding // \ref{iterator.concept.inc}, concept \libconcept{incrementable} template - concept incrementable = @\seebelow@; + concept incrementable = @\seebelow@; // freestanding // \ref{iterator.concept.iterator}, concept \libconcept{input_or_output_iterator} template - concept input_or_output_iterator = @\seebelow@; + concept input_or_output_iterator = @\seebelow@; // freestanding // \ref{iterator.concept.sentinel}, concept \libconcept{sentinel_for} template - concept sentinel_for = @\seebelow@; + concept sentinel_for = @\seebelow@; // freestanding // \ref{iterator.concept.sizedsentinel}, concept \libconcept{sized_sentinel_for} template - inline constexpr bool disable_sized_sentinel_for = false; + inline constexpr bool disable_sized_sentinel_for = false; // freestanding template - concept sized_sentinel_for = @\seebelow@; + concept sized_sentinel_for = @\seebelow@; // freestanding // \ref{iterator.concept.input}, concept \libconcept{input_iterator} template - concept input_iterator = @\seebelow@; + concept input_iterator = @\seebelow@; // freestanding // \ref{iterator.concept.output}, concept \libconcept{output_iterator} template - concept output_iterator = @\seebelow@; + concept output_iterator = @\seebelow@; // freestanding // \ref{iterator.concept.forward}, concept \libconcept{forward_iterator} template - concept forward_iterator = @\seebelow@; + concept forward_iterator = @\seebelow@; // freestanding // \ref{iterator.concept.bidir}, concept \libconcept{bidirectional_iterator} template - concept bidirectional_iterator = @\seebelow@; + concept bidirectional_iterator = @\seebelow@; // freestanding // \ref{iterator.concept.random.access}, concept \libconcept{random_access_iterator} template - concept random_access_iterator = @\seebelow@; + concept random_access_iterator = @\seebelow@; // freestanding // \ref{iterator.concept.contiguous}, concept \libconcept{contiguous_iterator} template - concept contiguous_iterator = @\seebelow@; + concept contiguous_iterator = @\seebelow@; // freestanding // \ref{indirectcallable}, indirect callable requirements // \ref{indirectcallable.indirectinvocable}, indirect callables template - concept indirectly_unary_invocable = @\seebelow@; + concept indirectly_unary_invocable = @\seebelow@; // freestanding template - concept indirectly_regular_unary_invocable = @\seebelow@; + concept indirectly_regular_unary_invocable = @\seebelow@; // freestanding template - concept indirect_unary_predicate = @\seebelow@; + concept indirect_unary_predicate = @\seebelow@; // freestanding template - concept indirect_binary_predicate = @\seebelow@; + concept indirect_binary_predicate = @\seebelow@; // freestanding template - concept indirect_equivalence_relation = @\seebelow@; + concept indirect_equivalence_relation = @\seebelow@; // freestanding template - concept indirect_strict_weak_order = @\seebelow@; + concept indirect_strict_weak_order = @\seebelow@; // freestanding template requires (@\libconcept{indirectly_readable}@ && ...) && @\libconcept{invocable}@...> - using indirect_result_t = invoke_result_t...>; + using indirect_result_t = invoke_result_t...>; // freestanding // \ref{projected}, projected template<@\libconcept{indirectly_readable}@ I, @\libconcept{indirectly_regular_unary_invocable}@ Proj> - struct projected; + struct projected; // freestanding template<@\libconcept{weakly_incrementable}@ I, class Proj> - struct incrementable_traits>; + struct incrementable_traits>; // freestanding // \ref{alg.req}, common algorithm requirements // \ref{alg.req.ind.move}, concept \libconcept{indirectly_movable} template - concept indirectly_movable = @\seebelow@; + concept indirectly_movable = @\seebelow@; // freestanding template - concept indirectly_movable_storable = @\seebelow@; + concept indirectly_movable_storable = @\seebelow@; // freestanding // \ref{alg.req.ind.copy}, concept \libconcept{indirectly_copyable} template - concept indirectly_copyable = @\seebelow@; + concept indirectly_copyable = @\seebelow@; // freestanding template - concept indirectly_copyable_storable = @\seebelow@; + concept indirectly_copyable_storable = @\seebelow@; // freestanding // \ref{alg.req.ind.swap}, concept \libconcept{indirectly_swappable} template - concept indirectly_swappable = @\seebelow@; + concept indirectly_swappable = @\seebelow@; // freestanding // \ref{alg.req.ind.cmp}, concept \libconcept{indirectly_comparable} template - concept indirectly_comparable = @\seebelow@; + concept indirectly_comparable = @\seebelow@; // freestanding // \ref{alg.req.permutable}, concept \libconcept{permutable} template - concept permutable = @\seebelow@; + concept permutable = @\seebelow@; // freestanding // \ref{alg.req.mergeable}, concept \libconcept{mergeable} template - concept mergeable = @\seebelow@; + concept mergeable = @\seebelow@; // freestanding // \ref{alg.req.sortable}, concept \libconcept{sortable} template - concept sortable = @\seebelow@; + concept sortable = @\seebelow@; // freestanding // \ref{iterator.primitives}, primitives // \ref{std.iterator.tags}, iterator tags - struct input_iterator_tag { }; - struct output_iterator_tag { }; - struct forward_iterator_tag: public input_iterator_tag { }; - struct bidirectional_iterator_tag: public forward_iterator_tag { }; - struct random_access_iterator_tag: public bidirectional_iterator_tag { }; - struct contiguous_iterator_tag: public random_access_iterator_tag { }; + struct input_iterator_tag { }; // freestanding + struct output_iterator_tag { }; // freestanding + struct forward_iterator_tag: public input_iterator_tag { }; // freestanding + struct bidirectional_iterator_tag: public forward_iterator_tag { }; // freestanding + struct random_access_iterator_tag: public bidirectional_iterator_tag { }; // freestanding + struct contiguous_iterator_tag: public random_access_iterator_tag { }; // freestanding // \ref{iterator.operations}, iterator operations template constexpr void - advance(InputIterator& i, Distance n); + advance(InputIterator& i, Distance n); // freestanding template constexpr typename iterator_traits::difference_type - distance(InputIterator first, InputIterator last); + distance(InputIterator first, InputIterator last); // freestanding template constexpr InputIterator - next(InputIterator x, + next(InputIterator x, // freestanding typename iterator_traits::difference_type n = 1); template constexpr BidirectionalIterator - prev(BidirectionalIterator x, + prev(BidirectionalIterator x, // freestanding typename iterator_traits::difference_type n = 1); // \ref{range.iter.ops}, range iterator operations namespace ranges { // \ref{range.iter.op.advance}, \tcode{ranges::advance} template<@\libconcept{input_or_output_iterator}@ I> - constexpr void advance(I& i, iter_difference_t n); + constexpr void advance(I& i, iter_difference_t n); // freestanding template<@\libconcept{input_or_output_iterator}@ I, @\libconcept{sentinel_for}@ S> - constexpr void advance(I& i, S bound); + constexpr void advance(I& i, S bound); // freestanding template<@\libconcept{input_or_output_iterator}@ I, @\libconcept{sentinel_for}@ S> - constexpr iter_difference_t advance(I& i, iter_difference_t n, S bound); + constexpr iter_difference_t advance(I& i, iter_difference_t n, // freestanding + S bound); // \ref{range.iter.op.distance}, \tcode{ranges::distance} template<@\libconcept{input_or_output_iterator}@ I, @\libconcept{sentinel_for}@ S> requires (!@\libconcept{sized_sentinel_for}@) - constexpr iter_difference_t distance(I first, S last); + constexpr iter_difference_t distance(I first, S last); // freestanding template<@\libconcept{input_or_output_iterator}@ I, @\libconcept{sized_sentinel_for}@ S> - constexpr iter_difference_t distance(const I& first, const S& last); + constexpr iter_difference_t distance(const I& first, const S& last); // freestanding template<@\libconcept{range}@ R> - constexpr range_difference_t distance(R&& r); + constexpr range_difference_t distance(R&& r); // freestanding // \ref{range.iter.op.next}, \tcode{ranges::next} template<@\libconcept{input_or_output_iterator}@ I> - constexpr I next(I x); + constexpr I next(I x); // freestanding template<@\libconcept{input_or_output_iterator}@ I> - constexpr I next(I x, iter_difference_t n); + constexpr I next(I x, iter_difference_t n); // freestanding template<@\libconcept{input_or_output_iterator}@ I, @\libconcept{sentinel_for}@ S> - constexpr I next(I x, S bound); + constexpr I next(I x, S bound); // freestanding template<@\libconcept{input_or_output_iterator}@ I, @\libconcept{sentinel_for}@ S> - constexpr I next(I x, iter_difference_t n, S bound); + constexpr I next(I x, iter_difference_t n, S bound); // freestanding // \ref{range.iter.op.prev}, \tcode{ranges::prev} template<@\libconcept{bidirectional_iterator}@ I> - constexpr I prev(I x); + constexpr I prev(I x); // freestanding template<@\libconcept{bidirectional_iterator}@ I> - constexpr I prev(I x, iter_difference_t n); + constexpr I prev(I x, iter_difference_t n); // freestanding template<@\libconcept{bidirectional_iterator}@ I> - constexpr I prev(I x, iter_difference_t n, I bound); + constexpr I prev(I x, iter_difference_t n, I bound); // freestanding } // \ref{predef.iterators}, predefined iterators and sentinels // \ref{reverse.iterators}, reverse iterators - template class reverse_iterator; + template class reverse_iterator; // freestanding template - constexpr bool operator==( + constexpr bool operator==( // freestanding const reverse_iterator& x, const reverse_iterator& y); template - constexpr bool operator!=( + constexpr bool operator!=( // freestanding const reverse_iterator& x, const reverse_iterator& y); template - constexpr bool operator<( + constexpr bool operator<( // freestanding const reverse_iterator& x, const reverse_iterator& y); template - constexpr bool operator>( + constexpr bool operator>( // freestanding const reverse_iterator& x, const reverse_iterator& y); template - constexpr bool operator<=( + constexpr bool operator<=( // freestanding const reverse_iterator& x, const reverse_iterator& y); template - constexpr bool operator>=( + constexpr bool operator>=( // freestanding const reverse_iterator& x, const reverse_iterator& y); template Iterator2> constexpr compare_three_way_result_t - operator<=>(const reverse_iterator& x, + operator<=>(const reverse_iterator& x, // freestanding const reverse_iterator& y); template - constexpr auto operator-( + constexpr auto operator-( // freestanding const reverse_iterator& x, const reverse_iterator& y) -> decltype(y.base() - x.base()); template - constexpr reverse_iterator operator+( + constexpr reverse_iterator operator+( // freestanding iter_difference_t n, const reverse_iterator& x); template - constexpr reverse_iterator make_reverse_iterator(Iterator i); + constexpr reverse_iterator make_reverse_iterator(Iterator i); // freestanding template requires (!@\libconcept{sized_sentinel_for}@) - inline constexpr bool disable_sized_sentinel_for, + inline constexpr bool disable_sized_sentinel_for, // freestanding reverse_iterator> = true; // \ref{insert.iterators}, insert iterators - template class back_insert_iterator; + template class back_insert_iterator; // freestanding template - constexpr back_insert_iterator back_inserter(Container& x); + constexpr back_insert_iterator back_inserter(Container& x); // freestanding - template class front_insert_iterator; + template class front_insert_iterator; // freestanding template - constexpr front_insert_iterator front_inserter(Container& x); + constexpr front_insert_iterator front_inserter(Container& x); // freestanding - template class insert_iterator; + template class insert_iterator; // freestanding template constexpr insert_iterator - inserter(Container& x, ranges::iterator_t i); + inserter(Container& x, ranges::iterator_t i); // freestanding // \ref{move.iterators}, move iterators and sentinels - template class move_iterator; + template class move_iterator; // freestanding template - constexpr bool operator==( + constexpr bool operator==( // freestanding const move_iterator& x, const move_iterator& y); template - constexpr bool operator<( + constexpr bool operator<( // freestanding const move_iterator& x, const move_iterator& y); template - constexpr bool operator>( + constexpr bool operator>( // freestanding const move_iterator& x, const move_iterator& y); template - constexpr bool operator<=( + constexpr bool operator<=( // freestanding const move_iterator& x, const move_iterator& y); template - constexpr bool operator>=( + constexpr bool operator>=( // freestanding const move_iterator& x, const move_iterator& y); template Iterator2> constexpr compare_three_way_result_t - operator<=>(const move_iterator& x, + operator<=>(const move_iterator& x, // freestanding const move_iterator& y); template - constexpr auto operator-( + constexpr auto operator-( // freestanding const move_iterator& x, const move_iterator& y) -> decltype(x.base() - y.base()); template constexpr move_iterator - operator+(iter_difference_t n, const move_iterator& x); + operator+(iter_difference_t n, const move_iterator& x); // freestanding template - constexpr move_iterator make_move_iterator(Iterator i); + constexpr move_iterator make_move_iterator(Iterator i); // freestanding - template<@\libconcept{semiregular}@ S> class move_sentinel; + template<@\libconcept{semiregular}@ S> class move_sentinel; // freestanding // \ref{iterators.common}, common iterators template<@\libconcept{input_or_output_iterator}@ I, @\libconcept{sentinel_for}@ S> requires (!@\libconcept{same_as}@ && @\libconcept{copyable}@) - class common_iterator; + class common_iterator; // freestanding template - struct incrementable_traits>; + struct incrementable_traits>; // freestanding template<@\libconcept{input_iterator}@ I, class S> - struct iterator_traits>; + struct iterator_traits>; // freestanding // \ref{default.sentinel}, default sentinel - struct default_sentinel_t; - inline constexpr default_sentinel_t @\libglobal{default_sentinel}@{}; + struct default_sentinel_t; // freestanding + inline constexpr default_sentinel_t @\libglobal{default_sentinel}@{}; // freestanding // \ref{iterators.counted}, counted iterators - template<@\libconcept{input_or_output_iterator}@ I> class counted_iterator; + template<@\libconcept{input_or_output_iterator}@ I> class counted_iterator; // freestanding template<@\libconcept{input_iterator}@ I> requires @\seebelow@ - struct iterator_traits>; + struct iterator_traits>; // freestanding // \ref{unreachable.sentinel}, unreachable sentinel - struct unreachable_sentinel_t; - inline constexpr unreachable_sentinel_t @\libglobal{unreachable_sentinel}@{}; + struct unreachable_sentinel_t; // freestanding + inline constexpr unreachable_sentinel_t @\libglobal{unreachable_sentinel}@{}; // freestanding // \ref{stream.iterators}, stream iterators template, @@ -416,39 +417,53 @@ class ostreambuf_iterator; // \ref{iterator.range}, range access - template constexpr auto begin(C& c) -> decltype(c.begin()); - template constexpr auto begin(const C& c) -> decltype(c.begin()); - template constexpr auto end(C& c) -> decltype(c.end()); - template constexpr auto end(const C& c) -> decltype(c.end()); - template constexpr T* begin(T (&array)[N]) noexcept; - template constexpr T* end(T (&array)[N]) noexcept; - template constexpr auto cbegin(const C& c) noexcept(noexcept(std::begin(c))) - -> decltype(std::begin(c)); - template constexpr auto cend(const C& c) noexcept(noexcept(std::end(c))) - -> decltype(std::end(c)); - template constexpr auto rbegin(C& c) -> decltype(c.rbegin()); - template constexpr auto rbegin(const C& c) -> decltype(c.rbegin()); - template constexpr auto rend(C& c) -> decltype(c.rend()); - template constexpr auto rend(const C& c) -> decltype(c.rend()); - template constexpr reverse_iterator rbegin(T (&array)[N]); - template constexpr reverse_iterator rend(T (&array)[N]); - template constexpr reverse_iterator rbegin(initializer_list il); - template constexpr reverse_iterator rend(initializer_list il); - template constexpr auto crbegin(const C& c) -> decltype(std::rbegin(c)); - template constexpr auto crend(const C& c) -> decltype(std::rend(c)); - - template constexpr auto size(const C& c) -> decltype(c.size()); - template constexpr size_t size(const T (&array)[N]) noexcept; - template constexpr auto ssize(const C& c) - -> common_type_t>; - template constexpr ptrdiff_t ssize(const T (&array)[N]) noexcept; - template [[nodiscard]] constexpr auto empty(const C& c) -> decltype(c.empty()); - template [[nodiscard]] constexpr bool empty(const T (&array)[N]) noexcept; - template [[nodiscard]] constexpr bool empty(initializer_list il) noexcept; - template constexpr auto data(C& c) -> decltype(c.data()); - template constexpr auto data(const C& c) -> decltype(c.data()); - template constexpr T* data(T (&array)[N]) noexcept; - template constexpr const E* data(initializer_list il) noexcept; + template constexpr auto begin(C& c) -> decltype(c.begin()); // freestanding + template constexpr auto begin(const C& c) -> decltype(c.begin()); // freestanding + template constexpr auto end(C& c) -> decltype(c.end()); // freestanding + template constexpr auto end(const C& c) -> decltype(c.end()); // freestanding + template constexpr T* begin(T (&array)[N]) noexcept; // freestanding + template constexpr T* end(T (&array)[N]) noexcept; // freestanding + template constexpr auto cbegin(const C& c) // freestanding + noexcept(noexcept(std::begin(c))) -> decltype(std::begin(c)); + template constexpr auto cend(const C& c) // freestanding + noexcept(noexcept(std::end(c))) -> decltype(std::end(c)); + template constexpr auto rbegin(C& c) -> decltype(c.rbegin()); // freestanding + template constexpr auto rbegin(const C& c) -> decltype(c.rbegin()); // freestanding + template constexpr auto rend(C& c) -> decltype(c.rend()); // freestanding + template constexpr auto rend(const C& c) -> decltype(c.rend()); // freestanding + template constexpr reverse_iterator rbegin(T (&array)[N]) // freestanding + template constexpr reverse_iterator rend(T (&array)[N]); // freestanding + template constexpr reverse_iterator + rbegin(initializer_list il); // freestanding + template constexpr reverse_iterator + rend(initializer_list il); // freestanding + template constexpr auto + crbegin(const C& c) -> decltype(std::rbegin(c)); // freestanding + template constexpr auto + crend(const C& c) -> decltype(std::rend(c)); // freestanding + + template constexpr auto + size(const C& c) -> decltype(c.size()); // freestanding + template constexpr size_t + size(const T (&array)[N]) noexcept; // freestanding + + template constexpr auto + ssize(const C& c) + -> common_type_t>; // freestanding + template constexpr ptrdiff_t + ssize(const T (&array)[N]) noexcept; // freestanding + + template [[nodiscard]] constexpr auto + empty(const C& c) -> decltype(c.empty()); // freestanding + template [[nodiscard]] constexpr bool + empty(const T (&array)[N]) noexcept; // freestanding + template [[nodiscard]] constexpr bool + empty(initializer_list il) noexcept; // freestanding + + template constexpr auto data(C& c) -> decltype(c.data()); // freestanding + template constexpr auto data(const C& c) -> decltype(c.data()); // freestanding + template constexpr T* data(T (&array)[N]) noexcept; // freestanding + template constexpr const E* data(initializer_list il) noexcept; // freestanding } \end{codeblock} diff --git a/source/lib-intro.tex b/source/lib-intro.tex index dfef1f18ae..d42071dc91 100644 --- a/source/lib-intro.tex +++ b/source/lib-intro.tex @@ -908,6 +908,52 @@ \pnum An implementation may use any technique that provides equivalent observable behavior. +\rSec3[freestanding.entity]{Freestanding entities} + +\pnum +\indextext{entity!freestanding|see{freestanding entity}}% +A \defn{freestanding entity} is a declaration or macro definition +that is present in a freestanding implementation and a hosted implementation. + +\pnum +Unless otherwise specified, +the requirements on freestanding entities on a freestanding implementation +are the same as the corresponding requirements in a hosted implementation. + +\pnum +In a header synopsis, entities followed with a comment +that includes \textit{freestanding} are freestanding entities. +\begin{example} +\begin{codeblock} +#define NULL @\seebelow@ // freestanding +\end{codeblock} +\end{example} + +\pnum +If a header synopsis begins with a comment +that includes \textit{all freestanding}, +then all of the declarations and macro definitions in the header synopsis +are freestanding entities. +\begin{example} +\begin{codeblock} +// all freestanding +namespace std { +\end{codeblock} +\end{example} + +\pnum +Deduction guides for freestanding entity class templates are freestanding entities. + +\pnum +Enclosing namespaces of freestanding entities are freestanding entities. + +\pnum +Friends of freestanding entities are freestanding entities. + +\pnum +Entities denoted by freestanding entity \grammarterm{typedef-name}{s} and +freestanding entity alias templates are freestanding entities. + \rSec1[requirements]{Library-wide requirements} \rSec2[requirements.general]{General} @@ -1350,38 +1396,31 @@ \ref{concepts} & Concepts library & \tcode{} \\ \rowsep \ref{type.traits} & Type traits & \tcode{} \\ \rowsep \ref{bit} & Bit manipulation & \tcode{} \\ \rowsep -\ref{atomics} & Atomics & \tcode{} \\ +\ref{atomics} & Atomics & \tcode{} \\ \rowsep +\ref{utility} & Utility components & \tcode{} \\ \rowsep +\ref{tuple} & Tuples & \tcode{} \\ \rowsep +\ref{memory} & Memory & \tcode{} \\ \rowsep +\ref{function.objects} & Function objects & \tcode{} \\ \rowsep +\ref{ratio} & Compile-time rational arithmetic & \tcode{} \\ \rowsep +\ref{iterators} & Iterators library & \tcode{} \\ \rowsep +\ref{ranges} & Ranges library & \tcode{} \\ \end{libsumtab} \pnum -The supplied version of the header \libheaderref{cstdlib} -shall declare at least the functions -\indexlibraryglobal{abort}% -\tcode{abort}, -\indexlibraryglobal{atexit}% -\tcode{atexit}, -\indexlibraryglobal{at_quick_exit}% -\tcode{at_quick_exit}, -\indexlibraryglobal{exit}% -\tcode{exit}, -and -\indexlibraryglobal{quick_exit}% -\tcode{quick_exit}\iref{support.start.term}. -\indextext{implementation!hosted}% -The supplied version of the header \libheaderrefx{atomic}{atomics.syn} -shall meet the same requirements as for a hosted implementation -except that support for -always lock-free integral atomic types\iref{atomics.lockfree} -is \impldef{support for always lock-free integral atomic types in -freestanding environments}, and -whether or not the type aliases \tcode{atomic_signed_lock_free} and -\tcode{atomic_unsigned_lock_free} are defined\iref{atomics.alias} -is \impldef{type aliases \tcode{atomic_signed_lock_free} and -\tcode{atomic_unsigned_lock_free} in freestanding environments}. -The other headers listed in this table -shall meet the same requirements as for a hosted implementation. +For each of the headers listed in \tref{headers.cpp.fs}, +a freestanding implementation provides at least +the freestanding entities\iref{freestanding.entity} declared in the header. \indextext{implementation!freestanding|)}% +\pnum +\begin{note} +Throwing a standard library provided exception +is not observably different from \tcode{terminate()} +if the implementation does not +unwind the stack during exception handling\iref{except.handle} and +the user's program contains no catch blocks. +\end{note} + \rSec2[using]{Using the library} \rSec3[using.overview]{Overview} diff --git a/source/memory.tex b/source/memory.tex index 8491e64339..7c5f586fee 100644 --- a/source/memory.tex +++ b/source/memory.tex @@ -70,75 +70,79 @@ namespace std { // \ref{pointer.traits}, pointer traits - template struct pointer_traits; - template struct pointer_traits; + template struct pointer_traits; // freestanding + template struct pointer_traits; // freestanding // \ref{pointer.conversion}, pointer conversion template - constexpr T* to_address(T* p) noexcept; + constexpr T* to_address(T* p) noexcept; // freestanding template - constexpr auto to_address(const Ptr& p) noexcept; + constexpr auto to_address(const Ptr& p) noexcept; // freestanding // \ref{ptr.align}, pointer alignment - void* align(size_t alignment, size_t size, void*& ptr, size_t& space); + void* align(size_t alignment, size_t size, void*& ptr, size_t& space); // freestanding template - [[nodiscard]] constexpr T* assume_aligned(T* ptr); + [[nodiscard]] constexpr T* assume_aligned(T* ptr); // freestanding // \ref{allocator.tag}, allocator argument tag - struct allocator_arg_t { explicit allocator_arg_t() = default; }; - inline constexpr allocator_arg_t allocator_arg{}; + struct allocator_arg_t { // freestanding + explicit allocator_arg_t() = default; // freestanding + }; + inline constexpr allocator_arg_t allocator_arg{}; // freestanding // \ref{allocator.uses}, \tcode{uses_allocator} - template struct uses_allocator; + template struct uses_allocator; // freestanding // \ref{allocator.uses.trait}, \tcode{uses_allocator} template - inline constexpr bool @\libglobal{uses_allocator_v}@ = uses_allocator::value; + inline constexpr bool @\libglobal{uses_allocator_v}@ = uses_allocator::value; // freestanding // \ref{allocator.uses.construction}, uses-allocator construction template - constexpr auto uses_allocator_construction_args(const Alloc& alloc, + constexpr auto uses_allocator_construction_args(const Alloc& alloc, // freestanding Args&&... args) noexcept; template - constexpr auto uses_allocator_construction_args(const Alloc& alloc, piecewise_construct_t, + constexpr auto uses_allocator_construction_args(const Alloc& alloc, // freestanding + piecewise_construct_t, Tuple1&& x, Tuple2&& y) noexcept; template - constexpr auto uses_allocator_construction_args(const Alloc& alloc) noexcept; + constexpr auto uses_allocator_construction_args(const Alloc& alloc) noexcept; // freestanding template - constexpr auto uses_allocator_construction_args(const Alloc& alloc, + constexpr auto uses_allocator_construction_args(const Alloc& alloc, // freestanding U&& u, V&& v) noexcept; template - constexpr auto uses_allocator_construction_args(const Alloc& alloc, + constexpr auto uses_allocator_construction_args(const Alloc& alloc, // freestanding pair& pr) noexcept; template - constexpr auto uses_allocator_construction_args(const Alloc& alloc, + constexpr auto uses_allocator_construction_args(const Alloc& alloc, // freestanding const pair& pr) noexcept; template - constexpr auto uses_allocator_construction_args(const Alloc& alloc, + constexpr auto uses_allocator_construction_args(const Alloc& alloc, // freestanding pair&& pr) noexcept; template - constexpr auto uses_allocator_construction_args(const Alloc& alloc, + constexpr auto uses_allocator_construction_args(const Alloc& alloc, // freestanding const pair&& pr) noexcept; template - constexpr auto uses_allocator_construction_args(const Alloc& alloc, U&& u) noexcept; + constexpr auto uses_allocator_construction_args(const Alloc& alloc, // freestanding + U&& u) noexcept; template - constexpr T make_obj_using_allocator(const Alloc& alloc, Args&&... args); + constexpr T make_obj_using_allocator(const Alloc& alloc, Args&&... args); // freestanding template - constexpr T* uninitialized_construct_using_allocator(T* p, const Alloc& alloc, - Args&&... args); + constexpr T* uninitialized_construct_using_allocator(T* p, // freestanding + const Alloc& alloc, Args&&... args); // \ref{allocator.traits}, allocator traits - template struct allocator_traits; + template struct allocator_traits; // freestanding template - struct allocation_result { + struct allocation_result { // freestanding Pointer ptr; size_t count; }; template [[nodiscard]] constexpr allocation_result::pointer> - allocate_at_least(Allocator& a, size_t n); + allocate_at_least(Allocator& a, size_t n); // freestanding // \ref{default.allocator}, the default allocator template class allocator; @@ -147,9 +151,9 @@ // \ref{specialized.addressof}, addressof template - constexpr T* addressof(T& r) noexcept; + constexpr T* addressof(T& r) noexcept; // freestanding template - const T* addressof(const T&&) = delete; + const T* addressof(const T&&) = delete; // freestanding // \ref{specialized.algorithms}, specialized algorithms // \ref{special.mem.concepts}, special memory concepts @@ -165,208 +169,214 @@ concept @\exposconcept{nothrow-forward-range}@ = @\seebelow@; // \expos template - void uninitialized_default_construct(NoThrowForwardIterator first, + void uninitialized_default_construct(NoThrowForwardIterator first, // freestanding NoThrowForwardIterator last); template - void uninitialized_default_construct(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + void uninitialized_default_construct(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} NoThrowForwardIterator first, NoThrowForwardIterator last); template NoThrowForwardIterator - uninitialized_default_construct_n(NoThrowForwardIterator first, Size n); + uninitialized_default_construct_n(NoThrowForwardIterator first, Size n); // freestanding template NoThrowForwardIterator - uninitialized_default_construct_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + uninitialized_default_construct_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} NoThrowForwardIterator first, Size n); namespace ranges { template<@\exposconcept{nothrow-forward-iterator}@ I, @\exposconcept{nothrow-sentinel-for}@ S> requires @\libconcept{default_initializable}@> - I uninitialized_default_construct(I first, S last); + I uninitialized_default_construct(I first, S last); // freestanding template<@\exposconcept{nothrow-forward-range}@ R> requires @\libconcept{default_initializable}@> - borrowed_iterator_t uninitialized_default_construct(R&& r); + borrowed_iterator_t uninitialized_default_construct(R&& r); // freestanding template<@\exposconcept{nothrow-forward-iterator}@ I> requires @\libconcept{default_initializable}@> - I uninitialized_default_construct_n(I first, iter_difference_t n); + I uninitialized_default_construct_n(I first, iter_difference_t n); // freestanding } template - void uninitialized_value_construct(NoThrowForwardIterator first, + void uninitialized_value_construct(NoThrowForwardIterator first, // freestanding NoThrowForwardIterator last); template - void uninitialized_value_construct(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + void uninitialized_value_construct(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} NoThrowForwardIterator first, NoThrowForwardIterator last); template NoThrowForwardIterator - uninitialized_value_construct_n(NoThrowForwardIterator first, Size n); + uninitialized_value_construct_n(NoThrowForwardIterator first, Size n); // freestanding template NoThrowForwardIterator - uninitialized_value_construct_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + uninitialized_value_construct_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} NoThrowForwardIterator first, Size n); namespace ranges { template<@\exposconcept{nothrow-forward-iterator}@ I, @\exposconcept{nothrow-sentinel-for}@ S> requires @\libconcept{default_initializable}@> - I uninitialized_value_construct(I first, S last); + I uninitialized_value_construct(I first, S last); // freestanding template<@\exposconcept{nothrow-forward-range}@ R> requires @\libconcept{default_initializable}@> - borrowed_iterator_t uninitialized_value_construct(R&& r); + borrowed_iterator_t uninitialized_value_construct(R&& r); // freestanding template<@\exposconcept{nothrow-forward-iterator}@ I> requires @\libconcept{default_initializable}@> - I uninitialized_value_construct_n(I first, iter_difference_t n); + I uninitialized_value_construct_n(I first, iter_difference_t n); // freestanding } template - NoThrowForwardIterator uninitialized_copy(InputIterator first, InputIterator last, + NoThrowForwardIterator uninitialized_copy(InputIterator first, // freestanding + InputIterator last, NoThrowForwardIterator result); template - NoThrowForwardIterator uninitialized_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + NoThrowForwardIterator uninitialized_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, NoThrowForwardIterator result); template - NoThrowForwardIterator uninitialized_copy_n(InputIterator first, Size n, + NoThrowForwardIterator uninitialized_copy_n(InputIterator first, Size n, // freestanding NoThrowForwardIterator result); template - NoThrowForwardIterator uninitialized_copy_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + NoThrowForwardIterator uninitialized_copy_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator first, Size n, NoThrowForwardIterator result); namespace ranges { template - using uninitialized_copy_result = in_out_result; + using uninitialized_copy_result = in_out_result; // freestanding template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S1, @\exposconcept{nothrow-forward-iterator}@ O, @\exposconcept{nothrow-sentinel-for}@ S2> requires @\libconcept{constructible_from}@, iter_reference_t> uninitialized_copy_result - uninitialized_copy(I ifirst, S1 ilast, O ofirst, S2 olast); + uninitialized_copy(I ifirst, S1 ilast, O ofirst, S2 olast); // freestanding template<@\libconcept{input_range}@ IR, @\exposconcept{nothrow-forward-range}@ OR> requires @\libconcept{constructible_from}@, range_reference_t> uninitialized_copy_result, borrowed_iterator_t> - uninitialized_copy(IR&& in_range, OR&& out_range); + uninitialized_copy(IR&& in_range, OR&& out_range); // freestanding template - using uninitialized_copy_n_result = in_out_result; + using uninitialized_copy_n_result = in_out_result; // freestanding template<@\libconcept{input_iterator}@ I, @\exposconcept{nothrow-forward-iterator}@ O, @\exposconcept{nothrow-sentinel-for}@ S> requires @\libconcept{constructible_from}@, iter_reference_t> uninitialized_copy_n_result - uninitialized_copy_n(I ifirst, iter_difference_t n, O ofirst, S olast); + uninitialized_copy_n(I ifirst, iter_difference_t n, // freestanding + O ofirst, S olast); } template - NoThrowForwardIterator uninitialized_move(InputIterator first, InputIterator last, + NoThrowForwardIterator uninitialized_move(InputIterator first, // freestanding + InputIterator last, NoThrowForwardIterator result); template - NoThrowForwardIterator uninitialized_move(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + NoThrowForwardIterator uninitialized_move(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, NoThrowForwardIterator result); template pair - uninitialized_move_n(InputIterator first, Size n, NoThrowForwardIterator result); + uninitialized_move_n(InputIterator first, Size n, // freestanding + NoThrowForwardIterator result); template pair - uninitialized_move_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + uninitialized_move_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator first, Size n, NoThrowForwardIterator result); namespace ranges { template - using uninitialized_move_result = in_out_result; + using uninitialized_move_result = in_out_result; // freestanding template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S1, @\exposconcept{nothrow-forward-iterator}@ O, @\exposconcept{nothrow-sentinel-for}@ S2> requires @\libconcept{constructible_from}@, iter_rvalue_reference_t> uninitialized_move_result - uninitialized_move(I ifirst, S1 ilast, O ofirst, S2 olast); + uninitialized_move(I ifirst, S1 ilast, O ofirst, S2 olast); // freestanding template<@\libconcept{input_range}@ IR, @\exposconcept{nothrow-forward-range}@ OR> requires @\libconcept{constructible_from}@, range_rvalue_reference_t> uninitialized_move_result, borrowed_iterator_t> - uninitialized_move(IR&& in_range, OR&& out_range); + uninitialized_move(IR&& in_range, OR&& out_range); // freestanding template - using uninitialized_move_n_result = in_out_result; + using uninitialized_move_n_result = in_out_result; // freestanding template<@\libconcept{input_iterator}@ I, @\exposconcept{nothrow-forward-iterator}@ O, @\exposconcept{nothrow-sentinel-for}@ S> requires @\libconcept{constructible_from}@, iter_rvalue_reference_t> uninitialized_move_n_result - uninitialized_move_n(I ifirst, iter_difference_t n, O ofirst, S olast); + uninitialized_move_n(I ifirst, iter_difference_t n, // freestanding + O ofirst, S olast); } template - void uninitialized_fill(NoThrowForwardIterator first, NoThrowForwardIterator last, - const T& x); + void uninitialized_fill(NoThrowForwardIterator first, // freestanding + NoThrowForwardIterator last, const T& x); template - void uninitialized_fill(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + void uninitialized_fill(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} NoThrowForwardIterator first, NoThrowForwardIterator last, const T& x); template NoThrowForwardIterator - uninitialized_fill_n(NoThrowForwardIterator first, Size n, const T& x); + uninitialized_fill_n(NoThrowForwardIterator first, Size n, const T& x); // freestanding template NoThrowForwardIterator - uninitialized_fill_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + uninitialized_fill_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} NoThrowForwardIterator first, Size n, const T& x); namespace ranges { template<@\exposconcept{nothrow-forward-iterator}@ I, @\exposconcept{nothrow-sentinel-for}@ S, class T> requires @\libconcept{constructible_from}@, const T&> - I uninitialized_fill(I first, S last, const T& x); + I uninitialized_fill(I first, S last, const T& x); // freestanding template<@\exposconcept{nothrow-forward-range}@ R, class T> requires @\libconcept{constructible_from}@, const T&> - borrowed_iterator_t uninitialized_fill(R&& r, const T& x); + borrowed_iterator_t uninitialized_fill(R&& r, const T& x); // freestanding template<@\exposconcept{nothrow-forward-iterator}@ I, class T> requires @\libconcept{constructible_from}@, const T&> - I uninitialized_fill_n(I first, iter_difference_t n, const T& x); + I uninitialized_fill_n(I first, iter_difference_t n, const T& x); // freestanding } // \ref{specialized.construct}, \tcode{construct_at} template - constexpr T* construct_at(T* location, Args&&... args); + constexpr T* construct_at(T* location, Args&&... args); // freestanding namespace ranges { template - constexpr T* construct_at(T* location, Args&&... args); + constexpr T* construct_at(T* location, Args&&... args); // freestanding } // \ref{specialized.destroy}, \tcode{destroy} template - constexpr void destroy_at(T* location); + constexpr void destroy_at(T* location); // freestanding template constexpr void destroy(NoThrowForwardIterator first, NoThrowForwardIterator last); template - void destroy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + void destroy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} NoThrowForwardIterator first, NoThrowForwardIterator last); template - constexpr NoThrowForwardIterator destroy_n(NoThrowForwardIterator first, Size n); + constexpr NoThrowForwardIterator destroy_n(NoThrowForwardIterator first, // freestanding + Size n); template - NoThrowForwardIterator destroy_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + NoThrowForwardIterator destroy_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} NoThrowForwardIterator first, Size n); namespace ranges { template<@\libconcept{destructible}@ T> - constexpr void destroy_at(T* location) noexcept; + constexpr void destroy_at(T* location) noexcept; // freestanding template<@\exposconcept{nothrow-input-iterator}@ I, @\exposconcept{nothrow-sentinel-for}@ S> requires @\libconcept{destructible}@> - constexpr I destroy(I first, S last) noexcept; + constexpr I destroy(I first, S last) noexcept; // freestanding template<@\exposconcept{nothrow-input-range}@ R> requires @\libconcept{destructible}@> - constexpr borrowed_iterator_t destroy(R&& r) noexcept; + constexpr borrowed_iterator_t destroy(R&& r) noexcept; // freestanding template<@\exposconcept{nothrow-input-iterator}@ I> requires @\libconcept{destructible}@> - constexpr I destroy_n(I first, iter_difference_t n) noexcept; + constexpr I destroy_n(I first, iter_difference_t n) noexcept; // freestanding } // \ref{unique.ptr}, class template \tcode{unique_ptr} - template struct default_delete; - template struct default_delete; - template> class unique_ptr; - template class unique_ptr; + template struct default_delete; // freestanding + template struct default_delete; // freestanding + template> class unique_ptr; // freestanding + template class unique_ptr; // freestanding template constexpr unique_ptr make_unique(Args&&... args); // \tcode{T} is not array @@ -383,47 +393,48 @@ @\unspecnc@ make_unique_for_overwrite(Args&&...) = delete; // \tcode{T} is \tcode{U[N]} template - constexpr void swap(unique_ptr& x, unique_ptr& y) noexcept; + constexpr void swap(unique_ptr& x, unique_ptr& y) noexcept; // freestanding template - constexpr bool operator==(const unique_ptr& x, const unique_ptr& y); + constexpr bool operator==(const unique_ptr& x, // freestanding + const unique_ptr& y); template - bool operator<(const unique_ptr& x, const unique_ptr& y); + bool operator<(const unique_ptr& x, const unique_ptr& y); // freestanding template - bool operator>(const unique_ptr& x, const unique_ptr& y); + bool operator>(const unique_ptr& x, const unique_ptr& y); // freestanding template - bool operator<=(const unique_ptr& x, const unique_ptr& y); + bool operator<=(const unique_ptr& x, const unique_ptr& y); // freestanding template - bool operator>=(const unique_ptr& x, const unique_ptr& y); + bool operator>=(const unique_ptr& x, const unique_ptr& y); // freestanding template requires @\libconcept{three_way_comparable_with}@::pointer, typename unique_ptr::pointer> compare_three_way_result_t::pointer, typename unique_ptr::pointer> - operator<=>(const unique_ptr& x, const unique_ptr& y); + operator<=>(const unique_ptr& x, const unique_ptr& y); // freestanding template - constexpr bool operator==(const unique_ptr& x, nullptr_t) noexcept; + constexpr bool operator==(const unique_ptr& x, nullptr_t) noexcept; // freestanding template - constexpr bool operator<(const unique_ptr& x, nullptr_t); + constexpr bool operator<(const unique_ptr& x, nullptr_t); // freestanding template - constexpr bool operator<(nullptr_t, const unique_ptr& y); + constexpr bool operator<(nullptr_t, const unique_ptr& y); // freestanding template - constexpr bool operator>(const unique_ptr& x, nullptr_t); + constexpr bool operator>(const unique_ptr& x, nullptr_t); // freestanding template - constexpr bool operator>(nullptr_t, const unique_ptr& y); + constexpr bool operator>(nullptr_t, const unique_ptr& y); // freestanding template - constexpr bool operator<=(const unique_ptr& x, nullptr_t); + constexpr bool operator<=(const unique_ptr& x, nullptr_t); // freestanding template - constexpr bool operator<=(nullptr_t, const unique_ptr& y); + constexpr bool operator<=(nullptr_t, const unique_ptr& y); // freestanding template - constexpr bool operator>=(const unique_ptr& x, nullptr_t); + constexpr bool operator>=(const unique_ptr& x, nullptr_t); // freestanding template - constexpr bool operator>=(nullptr_t, const unique_ptr& y); + constexpr bool operator>=(nullptr_t, const unique_ptr& y); // freestanding template requires @\libconcept{three_way_comparable}@::pointer> constexpr compare_three_way_result_t::pointer> - operator<=>(const unique_ptr& x, nullptr_t); + operator<=>(const unique_ptr& x, nullptr_t); // freestanding template basic_ostream& operator<<(basic_ostream& os, const unique_ptr& p); @@ -525,12 +536,12 @@ template class enable_shared_from_this; // \ref{util.smartptr.hash}, hash support - template struct hash; - template struct hash>; + template struct hash; // freestanding + template struct hash>; // freestanding template struct hash>; // \ref{util.smartptr.atomic}, atomic smart pointers - template struct atomic; + template struct atomic; // freestanding template struct atomic>; template struct atomic>; diff --git a/source/meta.tex b/source/meta.tex index 87836cacbe..e14e0bf049 100644 --- a/source/meta.tex +++ b/source/meta.tex @@ -154,6 +154,7 @@ \indexheader{type_traits}% % FIXME: Many index entries missing. \begin{codeblock} +// all freestanding namespace std { // \ref{meta.help}, helper class template struct integral_constant; @@ -2413,6 +2414,7 @@ \indexheader{ratio}% \begin{codeblockdigitsep} +// all freestanding namespace std { // \ref{ratio.ratio}, class template \tcode{ratio} template class ratio; diff --git a/source/ranges.tex b/source/ranges.tex index ead1940263..40041e8568 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -33,141 +33,143 @@ namespace std::ranges { inline namespace @\unspec@ { // \ref{range.access}, range access - inline constexpr @\unspec@ begin = @\unspec@; - inline constexpr @\unspec@ end = @\unspec@; - inline constexpr @\unspec@ cbegin = @\unspec@; - inline constexpr @\unspec@ cend = @\unspec@; - inline constexpr @\unspec@ rbegin = @\unspec@; - inline constexpr @\unspec@ rend = @\unspec@; - inline constexpr @\unspec@ crbegin = @\unspec@; - inline constexpr @\unspec@ crend = @\unspec@; - - inline constexpr @\unspec@ size = @\unspec@; - inline constexpr @\unspec@ ssize = @\unspec@; - inline constexpr @\unspec@ empty = @\unspec@; - inline constexpr @\unspec@ data = @\unspec@; - inline constexpr @\unspec@ cdata = @\unspec@; + inline constexpr @\unspec@ begin = @\unspec@; // freestanding + inline constexpr @\unspec@ end = @\unspec@; // freestanding + inline constexpr @\unspec@ cbegin = @\unspec@; // freestanding + inline constexpr @\unspec@ cend = @\unspec@; // freestanding + inline constexpr @\unspec@ rbegin = @\unspec@; // freestanding + inline constexpr @\unspec@ rend = @\unspec@; // freestanding + inline constexpr @\unspec@ crbegin = @\unspec@; // freestanding + inline constexpr @\unspec@ crend = @\unspec@; // freestanding + + inline constexpr @\unspec@ size = @\unspec@; // freestanding + inline constexpr @\unspec@ ssize = @\unspec@; // freestanding + inline constexpr @\unspec@ empty = @\unspec@; // freestanding + inline constexpr @\unspec@ data = @\unspec@; // freestanding + inline constexpr @\unspec@ cdata = @\unspec@; // freestanding } // \ref{range.range}, ranges template - concept range = @\seebelow@; + concept range = @\seebelow@; // freestanding template - inline constexpr bool enable_borrowed_range = false; + inline constexpr bool enable_borrowed_range = false; // freestanding template - concept borrowed_range = @\seebelow@; + concept borrowed_range = @\seebelow@; // freestanding template - using iterator_t = decltype(ranges::begin(declval())); + using iterator_t = decltype(ranges::begin(declval())); // freestanding template<@\libconcept{range}@ R> - using sentinel_t = decltype(ranges::end(declval())); + using sentinel_t = decltype(ranges::end(declval())); // freestanding template<@\libconcept{range}@ R> - using range_difference_t = iter_difference_t>; + using range_difference_t = iter_difference_t>; // freestanding template<@\libconcept{sized_range}@ R> - using range_size_t = decltype(ranges::size(declval())); + using range_size_t = decltype(ranges::size(declval())); // freestanding template<@\libconcept{range}@ R> - using range_value_t = iter_value_t>; + using range_value_t = iter_value_t>; // freestanding template<@\libconcept{range}@ R> - using range_reference_t = iter_reference_t>; + using range_reference_t = iter_reference_t>; // freestanding template<@\libconcept{range}@ R> - using range_rvalue_reference_t = iter_rvalue_reference_t>; + using range_rvalue_reference_t = iter_rvalue_reference_t>; // freestanding // \ref{range.sized}, sized ranges template - inline constexpr bool disable_sized_range = false; + inline constexpr bool disable_sized_range = false; // freestanding template - concept sized_range = @\seebelow@; + concept sized_range = @\seebelow@; // freestanding // \ref{range.view}, views template - inline constexpr bool enable_view = @\seebelow@; + inline constexpr bool enable_view = @\seebelow@; // freestanding - struct view_base {}; + struct view_base {}; // freestanding template - concept view = @\seebelow@; + concept view = @\seebelow@; // freestanding // \ref{range.refinements}, other range refinements template - concept output_range = @\seebelow@; + concept output_range = @\seebelow@; // freestanding template - concept input_range = @\seebelow@; + concept input_range = @\seebelow@; // freestanding template - concept forward_range = @\seebelow@; + concept forward_range = @\seebelow@; // freestanding template - concept bidirectional_range = @\seebelow@; + concept bidirectional_range = @\seebelow@; // freestanding template - concept random_access_range = @\seebelow@; + concept random_access_range = @\seebelow@; // freestanding template - concept contiguous_range = @\seebelow@; + concept contiguous_range = @\seebelow@; // freestanding template - concept common_range = @\seebelow@; + concept common_range = @\seebelow@; // freestanding template - concept viewable_range = @\seebelow@; + concept viewable_range = @\seebelow@; // freestanding // \ref{view.interface}, class template \tcode{view_interface} template requires is_class_v && @\libconcept{same_as}@> - class view_interface; + class view_interface; // freestanding // \ref{range.subrange}, sub-ranges - enum class subrange_kind : bool { unsized, sized }; + enum class subrange_kind : bool { unsized, sized }; // freestanding template<@\libconcept{input_or_output_iterator}@ I, @\libconcept{sentinel_for}@ S = I, subrange_kind K = @\seebelow@> requires (K == subrange_kind::sized || !@\libconcept{sized_sentinel_for}@) - class subrange; + class subrange; // freestanding template - inline constexpr bool enable_borrowed_range> = true; + inline constexpr bool enable_borrowed_range> = true; // freestanding // \ref{range.dangling}, dangling iterator handling - struct dangling; + struct dangling; // freestanding template<@\libconcept{range}@ R> - using borrowed_iterator_t = @\seebelow@; + using borrowed_iterator_t = @\seebelow@; // freestanding template<@\libconcept{range}@ R> - using borrowed_subrange_t = @\seebelow@; + using borrowed_subrange_t = @\seebelow@; // freestanding // \ref{range.utility.conv}, range conversions template requires (!@\libconcept{view}@) - constexpr C to(R&& r, Args&&... args); + constexpr C to(R&& r, Args&&... args); // freestanding template class C, @\libconcept{input_range}@ R, class... Args> - constexpr auto to(R&& r, Args&&... args); + constexpr auto to(R&& r, Args&&... args); // freestanding template requires (!@\libconcept{view}@) - constexpr auto to(Args&&... args); + constexpr auto to(Args&&... args); // freestanding template class C, class... Args> - constexpr auto to(Args&&... args); + constexpr auto to(Args&&... args); // freestanding // \ref{range.empty}, empty view template requires is_object_v - class empty_view; + class empty_view; // freestanding template - inline constexpr bool enable_borrowed_range> = true; + inline constexpr bool enable_borrowed_range> = true; // freestanding namespace views { template - inline constexpr empty_view @\libmember{empty}{views}@{}; + inline constexpr empty_view @\libmember{empty}{views}@{}; // freestanding } // \ref{range.single}, single view template<@\libconcept{copy_constructible}@ T> requires is_object_v - class single_view; + class single_view; // freestanding - namespace views { inline constexpr @\unspec@ single = @\unspec@; } + namespace views { + inline constexpr @\unspec@ single = @\unspec@; // freestanding + } template using @\exposidnc{maybe-const}@ = conditional_t; // \expos @@ -175,12 +177,14 @@ // \ref{range.iota}, iota view template<@\libconcept{weakly_incrementable}@ W, @\libconcept{semiregular}@ Bound = unreachable_sentinel_t> requires @\exposconcept{weakly-equality-comparable-with}@ && @\libconcept{copyable}@ - class iota_view; + class iota_view; // freestanding template - inline constexpr bool enable_borrowed_range> = true; + inline constexpr bool enable_borrowed_range> = true; // freestanding - namespace views { inline constexpr @\unspec@ iota = @\unspec@; } + namespace views { + inline constexpr @\unspec@ iota = @\unspec@; // freestanding + } // \ref{range.istream}, istream view template<@\libconcept{movable}@ Val, class CharT, class Traits = char_traits> @@ -196,91 +200,108 @@ // \ref{range.adaptor.object}, range adaptor objects template requires is_class_v && @\libconcept{same_as}@> - class range_adaptor_closure { }; + class range_adaptor_closure { }; // freestanding // \ref{range.all}, all view namespace views { - inline constexpr @\unspec@ all = @\unspec@; + inline constexpr @\unspec@ all = @\unspec@; // freestanding template<@\libconcept{viewable_range}@ R> - using all_t = decltype(all(declval())); + using all_t = decltype(all(declval())); // freestanding } // \ref{range.ref.view}, ref view template<@\libconcept{range}@ R> requires is_object_v - class ref_view; + class ref_view; // freestanding template - inline constexpr bool enable_borrowed_range> = true; + inline constexpr bool enable_borrowed_range> = true; // freestanding // \ref{range.owning.view}, owning view template<@\libconcept{range}@ R> requires @\seebelow@ - class owning_view; + class owning_view; // freestanding template - inline constexpr bool enable_borrowed_range> = enable_borrowed_range; + inline constexpr bool enable_borrowed_range> = // freestanding + enable_borrowed_range; // \ref{range.filter}, filter view template<@\libconcept{input_range}@ V, @\libconcept{indirect_unary_predicate}@> Pred> requires @\libconcept{view}@ && is_object_v - class filter_view; + class filter_view; // freestanding - namespace views { inline constexpr @\unspec@ filter = @\unspec@; } + namespace views { + inline constexpr @\unspec@ filter = @\unspec@; // freestanding + } // \ref{range.transform}, transform view template<@\libconcept{input_range}@ V, @\libconcept{copy_constructible}@ F> requires @\libconcept{view}@ && is_object_v && @\libconcept{regular_invocable}@> && @\exposconcept{can-reference}@>> - class transform_view; + class transform_view; // freestanding - namespace views { inline constexpr @\unspec@ transform = @\unspec@; } + namespace views { + inline constexpr @\unspec@ transform = @\unspec@; // freestanding + } // \ref{range.take}, take view - template<@\libconcept{view}@> class take_view; + template<@\libconcept{view}@> class take_view; // freestanding template - inline constexpr bool enable_borrowed_range> = enable_borrowed_range; + inline constexpr bool enable_borrowed_range> = // freestanding + enable_borrowed_range; - namespace views { inline constexpr @\unspec@ take = @\unspec@; } + namespace views { + inline constexpr @\unspec@ take = @\unspec@; // freestanding + } // \ref{range.take.while}, take while view template<@\libconcept{view}@ V, class Pred> requires @\libconcept{input_range}@ && is_object_v && @\libconcept{indirect_unary_predicate}@> - class take_while_view; + class take_while_view; // freestanding - namespace views { inline constexpr @\unspec@ take_while = @\unspec@; } + namespace views { + inline constexpr @\unspec@ take_while = @\unspec@; // freestanding + } // \ref{range.drop}, drop view template<@\libconcept{view}@ V> - class drop_view; + class drop_view; // freestanding template - inline constexpr bool enable_borrowed_range> = enable_borrowed_range; + inline constexpr bool enable_borrowed_range> = // freestanding + enable_borrowed_range; - namespace views { inline constexpr @\unspec@ drop = @\unspec@; } + namespace views { + inline constexpr @\unspec@ drop = @\unspec@; // freestanding + } // \ref{range.drop.while}, drop while view template<@\libconcept{view}@ V, class Pred> requires @\libconcept{input_range}@ && is_object_v && @\libconcept{indirect_unary_predicate}@> - class drop_while_view; + class drop_while_view; // freestanding template - inline constexpr bool enable_borrowed_range> = + inline constexpr bool enable_borrowed_range> = // freestanding enable_borrowed_range; - namespace views { inline constexpr @\unspec@ drop_while = @\unspec@; } + namespace views { + inline constexpr @\unspec@ drop_while = @\unspec@; // freestanding + } // \ref{range.join}, join view template<@\libconcept{input_range}@ V> requires @\libconcept{view}@ && @\libconcept{input_range}@> - class join_view; + class join_view; // freestanding - namespace views { inline constexpr @\unspec@ join = @\unspec@; } + namespace views { + inline constexpr @\unspec@ join = @\unspec@; // freestanding + } // \ref{range.join.with}, join with view template @@ -290,9 +311,11 @@ requires @\libconcept{view}@ && @\libconcept{input_range}@> && @\libconcept{view}@ && @\exposconcept{compatible-joinable-ranges}@, Pattern> - class join_with_view; + class join_with_view; // freestanding - namespace views { inline constexpr @\unspec@ join_with = @\unspec@; } + namespace views { + inline constexpr @\unspec@ join_with = @\unspec@; // freestanding + } // \ref{range.lazy.split}, lazy split view template @@ -302,170 +325,191 @@ requires @\libconcept{view}@ && @\libconcept{view}@ && @\libconcept{indirectly_comparable}@, iterator_t, ranges::equal_to> && (@\libconcept{forward_range}@ || @\exposconcept{tiny-range}@) - class lazy_split_view; + class lazy_split_view; // freestanding // \ref{range.split}, split view template<@\libconcept{forward_range}@ V, @\libconcept{forward_range}@ Pattern> requires @\libconcept{view}@ && @\libconcept{view}@ && @\libconcept{indirectly_comparable}@, iterator_t, ranges::equal_to> - class split_view; + class split_view; // freestanding namespace views { - inline constexpr @\unspec@ lazy_split = @\unspec@; - inline constexpr @\unspec@ split = @\unspec@; + inline constexpr @\unspec@ lazy_split = @\unspec@; // freestanding + inline constexpr @\unspec@ split = @\unspec@; // freestanding } // \ref{range.counted}, counted view - namespace views { inline constexpr @\unspec@ counted = @\unspec@; } + namespace views { + inline constexpr @\unspec@ counted = @\unspec@; // freestanding + } // \ref{range.common}, common view template<@\libconcept{view}@ V> requires (!@\libconcept{common_range}@ && @\libconcept{copyable}@>) - class common_view; + class common_view; // freestanding template - inline constexpr bool enable_borrowed_range> = enable_borrowed_range; + inline constexpr bool enable_borrowed_range> = // freestanding + enable_borrowed_range; - namespace views { inline constexpr @\unspec@ common = @\unspec@; } + namespace views { + inline constexpr @\unspec@ common = @\unspec@; // freestanding + } // \ref{range.reverse}, reverse view template<@\libconcept{view}@ V> requires @\libconcept{bidirectional_range}@ - class reverse_view; + class reverse_view; // freestanding template - inline constexpr bool enable_borrowed_range> = enable_borrowed_range; + inline constexpr bool enable_borrowed_range> = // freestanding + enable_borrowed_range; - namespace views { inline constexpr @\unspec@ reverse = @\unspec@; } + namespace views { + inline constexpr @\unspec@ reverse = @\unspec@; // freestanding + } // \ref{range.elements}, elements view template<@\libconcept{input_range}@ V, size_t N> requires @\seebelow@ - class elements_view; + class elements_view; // freestanding template - inline constexpr bool enable_borrowed_range> = enable_borrowed_range; + inline constexpr bool enable_borrowed_range> = // freestanding + enable_borrowed_range; template - using @\libglobal{keys_view}@ = elements_view; + using @\libglobal{keys_view}@ = elements_view; // freestanding template - using @\libglobal{values_view}@ = elements_view; + using @\libglobal{values_view}@ = elements_view; // freestanding namespace views { template - inline constexpr @\unspec@ elements = @\unspec@; - inline constexpr auto @\libmember{keys}{views}@ = elements<0>; - inline constexpr auto @\libmember{values}{views}@ = elements<1>; + inline constexpr @\unspec@ elements = @\unspec@; // freestanding + inline constexpr auto @\libmember{keys}{views}@ = elements<0>; // freestanding + inline constexpr auto @\libmember{values}{views}@ = elements<1>; // freestanding } // \ref{range.zip}, zip view template<@\libconcept{input_range}@... Views> requires (@\libconcept{view}@ && ...) && (sizeof...(Views) > 0) - class zip_view; + class zip_view; // freestanding template - inline constexpr bool enable_borrowed_range> = + inline constexpr bool enable_borrowed_range> = // freestanding (enable_borrowed_range && ...); - namespace views { inline constexpr @\unspec@ zip = @\unspec@; } + namespace views { + inline constexpr @\unspec@ zip = @\unspec@; // freestanding + } // \ref{range.zip.transform}, zip transform view template<@\libconcept{copy_constructible}@ F, @\libconcept{input_range}@... Views> requires (@\libconcept{view}@ && ...) && (sizeof...(Views) > 0) && is_object_v && @\libconcept{regular_invocable}@...> && @\exposconcept{can-reference}@...>> - class zip_transform_view; + class zip_transform_view; // freestanding - namespace views { inline constexpr @\unspec@ zip_transform = @\unspec@; } + namespace views { + inline constexpr @\unspec@ zip_transform = @\unspec@; // freestanding + } // \ref{range.adjacent}, adjacent view template<@\libconcept{forward_range}@ V, size_t N> requires @\libconcept{view}@ && (N > 0) - class adjacent_view; + class adjacent_view; // freestanding template - inline constexpr bool enable_borrowed_range> = + inline constexpr bool enable_borrowed_range> = // freestanding enable_borrowed_range; namespace views { template - inline constexpr @\unspec@ adjacent = @\unspec@ ; - inline constexpr auto @\libmember{pairwise}{views}@ = adjacent<2>; + inline constexpr @\unspec@ adjacent = @\unspec@ ; // freestanding + inline constexpr auto @\libmember{pairwise}{views}@ = adjacent<2>; // freestanding } // \ref{range.adjacent.transform}, adjacent transform view template<@\libconcept{forward_range}@ V, @\libconcept{copy_constructible}@ F, size_t N> requires @\seebelow@ - class adjacent_transform_view; + class adjacent_transform_view; // freestanding namespace views { template - inline constexpr @\unspec@ adjacent_transform = @\unspec@; - inline constexpr auto @\libmember{pairwise_transform}{views}@ = adjacent_transform<2>; + inline constexpr @\unspec@ adjacent_transform = @\unspec@; // freestanding + inline constexpr auto @\libmember{pairwise_transform}{views}@ = adjacent_transform<2>; // freestanding } // \ref{range.chunk}, chunk view template<@\libconcept{view}@ V> requires @\libconcept{input_range}@ - class chunk_view; + class chunk_view; // freestanding template<@\libconcept{view}@ V> requires @\libconcept{forward_range}@ - class chunk_view; + class chunk_view; // freestanding template - inline constexpr bool enable_borrowed_range> = + inline constexpr bool enable_borrowed_range> = // freestanding @\libconcept{forward_range}@ && enable_borrowed_range; - namespace views { inline constexpr @\unspec@ chunk = @\unspec@; } + namespace views { + inline constexpr @\unspec@ chunk = @\unspec@; // freestanding + } // \ref{range.slide}, slide view template<@\libconcept{forward_range}@ V> requires @\libconcept{view}@ - class slide_view; + class slide_view; // freestanding template inline constexpr bool enable_borrowed_range> = - enable_borrowed_range; + enable_borrowed_range; // freestanding - namespace views { inline constexpr @\unspec@ slide = @\unspec@; } + namespace views { + inline constexpr @\unspec@ slide = @\unspec@; // freestanding + } // \ref{range.chunk.by}, chunk by view template<@\libconcept{forward_range}@ V, @\libconcept{indirect_binary_predicate}@, iterator_t> Pred> requires @\libconcept{view}@ && is_object_v - class chunk_by_view; + class chunk_by_view; // freestanding - namespace views { inline constexpr @\unspec@ chunk_by = @\unspec@; } + namespace views { // freestanding + inline constexpr @\unspec@ chunk_by = @\unspec@; // freestanding + } } namespace std { - namespace views = ranges::views; + namespace views = ranges::views; // freestanding - template struct tuple_size; - template struct tuple_element; + template struct tuple_size; // freestanding + template struct tuple_element; // freestanding template - struct tuple_size> + struct tuple_size> // freestanding : integral_constant {}; template - struct tuple_element<0, ranges::subrange> { - using type = I; + struct tuple_element<0, ranges::subrange> { // freestanding + using type = I; // freestanding }; template - struct tuple_element<1, ranges::subrange> { - using type = S; + struct tuple_element<1, ranges::subrange> { // freestanding + using type = S; // freestanding }; template - struct tuple_element<0, const ranges::subrange> { - using type = I; + struct tuple_element<0, const ranges::subrange> { // freestanding + using type = I; // freestanding }; template - struct tuple_element<1, const ranges::subrange> { - using type = S; + struct tuple_element<1, const ranges::subrange> { // freestanding + using type = S; // freestanding }; - struct from_range_t { explicit from_range_t() = default; }; - inline constexpr from_range_t from_range{}; + struct from_range_t { // freestanding + explicit from_range_t() = default; // freestanding + }; + inline constexpr from_range_t from_range{}; // freestanding } \end{codeblock} diff --git a/source/support.tex b/source/support.tex index 181fdf754f..6cd1d6d08b 100644 --- a/source/support.tex +++ b/source/support.tex @@ -52,6 +52,7 @@ \indexlibraryglobal{nullptr_t}% \indexlibraryglobal{byte}% \begin{codeblock} +// all freestanding namespace std { using ptrdiff_t = @\seebelow@; using size_t = @\seebelow@; @@ -149,13 +150,13 @@ \indexlibraryglobal{wctomb}% \begin{codeblock} namespace std { - using size_t = @\seebelow@; + using size_t = @\seebelow@; // freestanding using div_t = @\seebelow@; using ldiv_t = @\seebelow@; using lldiv_t = @\seebelow@; } -#define NULL @\seebelow@ +#define NULL @\seebelow@ // freestanding #define EXIT_FAILURE @\seebelow@ #define EXIT_SUCCESS @\seebelow@ #define RAND_MAX @\seebelow@ @@ -163,20 +164,20 @@ namespace std { // Exposition-only function type aliases - extern "C" using @\placeholdernc{c-atexit-handler}@ = void(); // \expos - extern "C++" using @\placeholdernc{atexit-handler}@ = void(); // \expos - extern "C" using @\placeholdernc{c-compare-pred}@ = int(const void*, const void*); // \expos - extern "C++" using @\placeholdernc{compare-pred}@ = int(const void*, const void*); // \expos + extern "C" using @\placeholdernc{c-atexit-handler}@ = void(); // \expos + extern "C++" using @\placeholdernc{atexit-handler}@ = void(); // \expos + extern "C" using @\placeholdernc{c-compare-pred}@ = int(const void*, const void*); // \expos + extern "C++" using @\placeholdernc{compare-pred}@ = int(const void*, const void*); // \expos // \ref{support.start.term}, start and termination - [[noreturn]] void abort() noexcept; - int atexit(@\placeholder{c-atexit-handler}@* func) noexcept; - int atexit(@\placeholder{atexit-handler}@* func) noexcept; - int at_quick_exit(@\placeholder{c-atexit-handler}@* func) noexcept; - int at_quick_exit(@\placeholder{atexit-handler}@* func) noexcept; - [[noreturn]] void exit(int status); - [[noreturn]] void _Exit(int status) noexcept; - [[noreturn]] void quick_exit(int status) noexcept; + [[noreturn]] void abort() noexcept; // freestanding + int atexit(@\placeholder{c-atexit-handler}@* func) noexcept; // freestanding + int atexit(@\placeholder{atexit-handler}@* func) noexcept; // freestanding + int at_quick_exit(@\placeholder{c-atexit-handler}@* func) noexcept; // freestanding + int at_quick_exit(@\placeholder{atexit-handler}@* func) noexcept; // freestanding + [[noreturn]] void exit(int status); // freestanding + [[noreturn]] void _Exit(int status) noexcept; // freestanding + [[noreturn]] void quick_exit(int status) noexcept; // freestanding char* getenv(const char* name); int system(const char* string); @@ -550,6 +551,7 @@ \end{note} \begin{codeblock} +// all freestanding #define @\defnlibxname{cpp_lib_addressof_constexpr}@ 201603L // also in \libheader{memory} #define @\defnlibxname{cpp_lib_allocate_at_least}@ 202106L // also in \libheader{memory} #define @\defnlibxname{cpp_lib_allocator_traits_is_always_equal}@ 201411L @@ -735,6 +737,7 @@ \indexlibraryglobal{float_denorm_style}% \begin{codeblock} +// all freestanding namespace std { // \ref{fp.style}, floating-point type properties enum float_round_style; @@ -1696,6 +1699,7 @@ \indexlibraryglobal{LLONG_MAX}% \indexlibraryglobal{ULLONG_MAX}% \begin{codeblock} +// all freestanding #define CHAR_BIT @\seebelow@ #define SCHAR_MIN @\seebelow@ #define SCHAR_MAX @\seebelow@ @@ -1771,6 +1775,7 @@ \indexlibraryglobal{LDBL_MIN_EXP}% \indexlibraryglobal{LDBL_TRUE_MIN}% \begin{codeblock} +// all freestanding #define FLT_ROUNDS @\seebelow@ #define FLT_EVAL_METHOD @\seebelow@ #define FLT_HAS_SUBNORM @\seebelow@ @@ -1861,6 +1866,7 @@ \indexlibraryglobal{uintmax_t}% \indexlibraryglobal{uintptr_t}% \begin{codeblock} +// all freestanding namespace std { using int8_t = @\textit{signed integer type}@; // optional using int16_t = @\textit{signed integer type}@; // optional @@ -2218,6 +2224,7 @@ \rSec2[new.syn]{Header \tcode{} synopsis} \begin{codeblock} +// all freestanding namespace std { // \ref{alloc.errors}, storage allocation errors class bad_alloc; @@ -3151,6 +3158,7 @@ \indexlibraryglobal{bad_cast}% \indexlibraryglobal{bad_typeid}% \begin{codeblock} +// all freestanding namespace std { class type_info; class bad_cast; @@ -3335,6 +3343,7 @@ that provides a means to obtain source location information. \begin{codeblock} +// all freestanding namespace std { struct source_location; } @@ -3560,6 +3569,7 @@ \rSec2[exception.syn]{Header \tcode{} synopsis} \begin{codeblock} +// all freestanding namespace std { class exception; class bad_exception; @@ -4072,6 +4082,7 @@ \indexlibraryglobal{end}% \begin{codeblock} +// all freestanding namespace std { template class initializer_list { public: @@ -4207,6 +4218,7 @@ \indexlibraryglobal{is_gteq}% \indexlibraryglobal{common_comparison_category_t}% \begin{codeblock} +// all freestanding namespace std { // \ref{cmp.categories}, comparison category types class partial_ordering; @@ -5111,6 +5123,7 @@ \begin{codeblock} #include // see \ref{compare.syn} +// all freestanding namespace std { // \ref{coroutine.traits}, coroutine traits template @@ -5734,6 +5747,7 @@ \indexlibraryglobal{va_end}% \indexlibraryglobal{va_arg}% \begin{codeblock} +// all freestanding namespace std { using va_list = @\seebelow@; } diff --git a/source/threads.tex b/source/threads.tex index 020915bf95..9ce34c9939 100644 --- a/source/threads.tex +++ b/source/threads.tex @@ -2048,261 +2048,278 @@ \begin{codeblock} namespace std { // \ref{atomics.order}, order and consistency - enum class memory_order : @\unspec@; + enum class memory_order : @\unspec@; // freestanding template - T kill_dependency(T y) noexcept; + T kill_dependency(T y) noexcept; // freestanding } // \ref{atomics.lockfree}, lock-free property -#define ATOMIC_BOOL_LOCK_FREE @\unspec@ -#define ATOMIC_CHAR_LOCK_FREE @\unspec@ -#define ATOMIC_CHAR8_T_LOCK_FREE @\unspec@ -#define ATOMIC_CHAR16_T_LOCK_FREE @\unspec@ -#define ATOMIC_CHAR32_T_LOCK_FREE @\unspec@ -#define ATOMIC_WCHAR_T_LOCK_FREE @\unspec@ -#define ATOMIC_SHORT_LOCK_FREE @\unspec@ -#define ATOMIC_INT_LOCK_FREE @\unspec@ -#define ATOMIC_LONG_LOCK_FREE @\unspec@ -#define ATOMIC_LLONG_LOCK_FREE @\unspec@ -#define ATOMIC_POINTER_LOCK_FREE @\unspec@ +#define ATOMIC_BOOL_LOCK_FREE @\unspecnc@ // freestanding +#define ATOMIC_CHAR_LOCK_FREE @\unspecnc@ // freestanding +#define ATOMIC_CHAR8_T_LOCK_FREE @\unspecnc@ // freestanding +#define ATOMIC_CHAR16_T_LOCK_FREE @\unspecnc@ // freestanding +#define ATOMIC_CHAR32_T_LOCK_FREE @\unspecnc@ // freestanding +#define ATOMIC_WCHAR_T_LOCK_FREE @\unspecnc@ // freestanding +#define ATOMIC_SHORT_LOCK_FREE @\unspecnc@ // freestanding +#define ATOMIC_INT_LOCK_FREE @\unspecnc@ // freestanding +#define ATOMIC_LONG_LOCK_FREE @\unspecnc@ // freestanding +#define ATOMIC_LLONG_LOCK_FREE @\unspecnc@ // freestanding +#define ATOMIC_POINTER_LOCK_FREE @\unspecnc@ // freestanding namespace std { // \ref{atomics.ref.generic}, class template \tcode{atomic_ref} - template struct atomic_ref; + template struct atomic_ref; // freestanding // \ref{atomics.ref.pointer}, partial specialization for pointers - template struct atomic_ref; + template struct atomic_ref; // freestanding // \ref{atomics.types.generic}, class template \tcode{atomic} - template struct atomic; + template struct atomic; // freestanding // \ref{atomics.types.pointer}, partial specialization for pointers - template struct atomic; + template struct atomic; // freestanding // \ref{atomics.nonmembers}, non-member functions template - bool atomic_is_lock_free(const volatile atomic*) noexcept; + bool atomic_is_lock_free(const volatile atomic*) noexcept; // freestanding template - bool atomic_is_lock_free(const atomic*) noexcept; + bool atomic_is_lock_free(const atomic*) noexcept; // freestanding template - void atomic_store(volatile atomic*, typename atomic::value_type) noexcept; + void atomic_store(volatile atomic*, // freestanding + typename atomic::value_type) noexcept; template - void atomic_store(atomic*, typename atomic::value_type) noexcept; + void atomic_store(atomic*, typename atomic::value_type) noexcept; // freestanding template - void atomic_store_explicit(volatile atomic*, typename atomic::value_type, + void atomic_store_explicit(volatile atomic*, // freestanding + typename atomic::value_type, memory_order) noexcept; template - void atomic_store_explicit(atomic*, typename atomic::value_type, + void atomic_store_explicit(atomic*, typename atomic::value_type, // freestanding memory_order) noexcept; template - T atomic_load(const volatile atomic*) noexcept; + T atomic_load(const volatile atomic*) noexcept; // freestanding template - T atomic_load(const atomic*) noexcept; + T atomic_load(const atomic*) noexcept; // freestanding template - T atomic_load_explicit(const volatile atomic*, memory_order) noexcept; + T atomic_load_explicit(const volatile atomic*, memory_order) noexcept; // freestanding template - T atomic_load_explicit(const atomic*, memory_order) noexcept; + T atomic_load_explicit(const atomic*, memory_order) noexcept; // freestanding template - T atomic_exchange(volatile atomic*, typename atomic::value_type) noexcept; + T atomic_exchange(volatile atomic*, // freestanding + typename atomic::value_type) noexcept; template - T atomic_exchange(atomic*, typename atomic::value_type) noexcept; + T atomic_exchange(atomic*, typename atomic::value_type) noexcept; // freestanding template - T atomic_exchange_explicit(volatile atomic*, typename atomic::value_type, + T atomic_exchange_explicit(volatile atomic*, // freestanding + typename atomic::value_type, memory_order) noexcept; template - T atomic_exchange_explicit(atomic*, typename atomic::value_type, + T atomic_exchange_explicit(atomic*, typename atomic::value_type, // freestanding memory_order) noexcept; template - bool atomic_compare_exchange_weak(volatile atomic*, + bool atomic_compare_exchange_weak(volatile atomic*, // freestanding typename atomic::value_type*, typename atomic::value_type) noexcept; template - bool atomic_compare_exchange_weak(atomic*, + bool atomic_compare_exchange_weak(atomic*, // freestanding typename atomic::value_type*, typename atomic::value_type) noexcept; template - bool atomic_compare_exchange_strong(volatile atomic*, + bool atomic_compare_exchange_strong(volatile atomic*, // freestanding typename atomic::value_type*, typename atomic::value_type) noexcept; template - bool atomic_compare_exchange_strong(atomic*, + bool atomic_compare_exchange_strong(atomic*, // freestanding typename atomic::value_type*, typename atomic::value_type) noexcept; template - bool atomic_compare_exchange_weak_explicit(volatile atomic*, + bool atomic_compare_exchange_weak_explicit(volatile atomic*, // freestanding typename atomic::value_type*, typename atomic::value_type, memory_order, memory_order) noexcept; template - bool atomic_compare_exchange_weak_explicit(atomic*, + bool atomic_compare_exchange_weak_explicit(atomic*, // freestanding typename atomic::value_type*, typename atomic::value_type, memory_order, memory_order) noexcept; template - bool atomic_compare_exchange_strong_explicit(volatile atomic*, + bool atomic_compare_exchange_strong_explicit(volatile atomic*, // freestanding typename atomic::value_type*, typename atomic::value_type, memory_order, memory_order) noexcept; template - bool atomic_compare_exchange_strong_explicit(atomic*, + bool atomic_compare_exchange_strong_explicit(atomic*, // freestanding typename atomic::value_type*, typename atomic::value_type, memory_order, memory_order) noexcept; template - T atomic_fetch_add(volatile atomic*, typename atomic::difference_type) noexcept; + T atomic_fetch_add(volatile atomic*, // freestanding + typename atomic::difference_type) noexcept; template - T atomic_fetch_add(atomic*, typename atomic::difference_type) noexcept; + T atomic_fetch_add(atomic*, typename atomic::difference_type) noexcept; // freestanding template - T atomic_fetch_add_explicit(volatile atomic*, typename atomic::difference_type, + T atomic_fetch_add_explicit(volatile atomic*, // freestanding + typename atomic::difference_type, memory_order) noexcept; template - T atomic_fetch_add_explicit(atomic*, typename atomic::difference_type, + T atomic_fetch_add_explicit(atomic*, typename atomic::difference_type, // freestanding memory_order) noexcept; template - T atomic_fetch_sub(volatile atomic*, typename atomic::difference_type) noexcept; + T atomic_fetch_sub(volatile atomic*, // freestanding + typename atomic::difference_type) noexcept; template - T atomic_fetch_sub(atomic*, typename atomic::difference_type) noexcept; + T atomic_fetch_sub(atomic*, typename atomic::difference_type) noexcept; // freestanding template - T atomic_fetch_sub_explicit(volatile atomic*, typename atomic::difference_type, + T atomic_fetch_sub_explicit(volatile atomic*, // freestanding + typename atomic::difference_type, memory_order) noexcept; template - T atomic_fetch_sub_explicit(atomic*, typename atomic::difference_type, + T atomic_fetch_sub_explicit(atomic*, typename atomic::difference_type, // freestanding memory_order) noexcept; template - T atomic_fetch_and(volatile atomic*, typename atomic::value_type) noexcept; + T atomic_fetch_and(volatile atomic*, // freestanding + typename atomic::value_type) noexcept; template - T atomic_fetch_and(atomic*, typename atomic::value_type) noexcept; + T atomic_fetch_and(atomic*, typename atomic::value_type) noexcept; // freestanding template - T atomic_fetch_and_explicit(volatile atomic*, typename atomic::value_type, + T atomic_fetch_and_explicit(volatile atomic*, // freestanding + typename atomic::value_type, memory_order) noexcept; template - T atomic_fetch_and_explicit(atomic*, typename atomic::value_type, + T atomic_fetch_and_explicit(atomic*, typename atomic::value_type, // freestanding memory_order) noexcept; template - T atomic_fetch_or(volatile atomic*, typename atomic::value_type) noexcept; + T atomic_fetch_or(volatile atomic*, // freestanding + typename atomic::value_type) noexcept; template - T atomic_fetch_or(atomic*, typename atomic::value_type) noexcept; + T atomic_fetch_or(atomic*, typename atomic::value_type) noexcept; // freestanding template - T atomic_fetch_or_explicit(volatile atomic*, typename atomic::value_type, + T atomic_fetch_or_explicit(volatile atomic*, // freestanding + typename atomic::value_type, memory_order) noexcept; template - T atomic_fetch_or_explicit(atomic*, typename atomic::value_type, + T atomic_fetch_or_explicit(atomic*, typename atomic::value_type, // freestanding memory_order) noexcept; template - T atomic_fetch_xor(volatile atomic*, typename atomic::value_type) noexcept; + T atomic_fetch_xor(volatile atomic*, // freestanding + typename atomic::value_type) noexcept; template - T atomic_fetch_xor(atomic*, typename atomic::value_type) noexcept; + T atomic_fetch_xor(atomic*, typename atomic::value_type) noexcept; // freestanding template - T atomic_fetch_xor_explicit(volatile atomic*, typename atomic::value_type, + T atomic_fetch_xor_explicit(volatile atomic*, // freestanding + typename atomic::value_type, memory_order) noexcept; template - T atomic_fetch_xor_explicit(atomic*, typename atomic::value_type, + T atomic_fetch_xor_explicit(atomic*, typename atomic::value_type, // freestanding memory_order) noexcept; template - void atomic_wait(const volatile atomic*, typename atomic::value_type); + void atomic_wait(const volatile atomic*, typename atomic::value_type); // freestanding template - void atomic_wait(const atomic*, typename atomic::value_type); + void atomic_wait(const atomic*, typename atomic::value_type); // freestanding template - void atomic_wait_explicit(const volatile atomic*, typename atomic::value_type, + void atomic_wait_explicit(const volatile atomic*, // freestanding + typename atomic::value_type, memory_order); template - void atomic_wait_explicit(const atomic*, typename atomic::value_type, + void atomic_wait_explicit(const atomic*, typename atomic::value_type, // freestanding memory_order); template - void atomic_notify_one(volatile atomic*); + void atomic_notify_one(volatile atomic*); // freestanding template - void atomic_notify_one(atomic*); + void atomic_notify_one(atomic*); // freestanding template - void atomic_notify_all(volatile atomic*); + void atomic_notify_all(volatile atomic*); // freestanding template - void atomic_notify_all(atomic*); + void atomic_notify_all(atomic*); // freestanding // \ref{atomics.alias}, type aliases - using atomic_bool = atomic; - using atomic_char = atomic; - using atomic_schar = atomic; - using atomic_uchar = atomic; - using atomic_short = atomic; - using atomic_ushort = atomic; - using atomic_int = atomic; - using atomic_uint = atomic; - using atomic_long = atomic; - using atomic_ulong = atomic; - using atomic_llong = atomic; - using atomic_ullong = atomic; - using atomic_char8_t = atomic; - using atomic_char16_t = atomic; - using atomic_char32_t = atomic; - using atomic_wchar_t = atomic; - - using atomic_int8_t = atomic; - using atomic_uint8_t = atomic; - using atomic_int16_t = atomic; - using atomic_uint16_t = atomic; - using atomic_int32_t = atomic; - using atomic_uint32_t = atomic; - using atomic_int64_t = atomic; - using atomic_uint64_t = atomic; - - using atomic_int_least8_t = atomic; - using atomic_uint_least8_t = atomic; - using atomic_int_least16_t = atomic; - using atomic_uint_least16_t = atomic; - using atomic_int_least32_t = atomic; - using atomic_uint_least32_t = atomic; - using atomic_int_least64_t = atomic; - using atomic_uint_least64_t = atomic; - - using atomic_int_fast8_t = atomic; - using atomic_uint_fast8_t = atomic; - using atomic_int_fast16_t = atomic; - using atomic_uint_fast16_t = atomic; - using atomic_int_fast32_t = atomic; - using atomic_uint_fast32_t = atomic; - using atomic_int_fast64_t = atomic; - using atomic_uint_fast64_t = atomic; - - using atomic_intptr_t = atomic; - using atomic_uintptr_t = atomic; - using atomic_size_t = atomic; - using atomic_ptrdiff_t = atomic; - using atomic_intmax_t = atomic; - using atomic_uintmax_t = atomic; + using atomic_bool = atomic; // freestanding + using atomic_char = atomic; // freestanding + using atomic_schar = atomic; // freestanding + using atomic_uchar = atomic; // freestanding + using atomic_short = atomic; // freestanding + using atomic_ushort = atomic; // freestanding + using atomic_int = atomic; // freestanding + using atomic_uint = atomic; // freestanding + using atomic_long = atomic; // freestanding + using atomic_ulong = atomic; // freestanding + using atomic_llong = atomic; // freestanding + using atomic_ullong = atomic; // freestanding + using atomic_char8_t = atomic; // freestanding + using atomic_char16_t = atomic; // freestanding + using atomic_char32_t = atomic; // freestanding + using atomic_wchar_t = atomic; // freestanding + + using atomic_int8_t = atomic; // freestanding + using atomic_uint8_t = atomic; // freestanding + using atomic_int16_t = atomic; // freestanding + using atomic_uint16_t = atomic; // freestanding + using atomic_int32_t = atomic; // freestanding + using atomic_uint32_t = atomic; // freestanding + using atomic_int64_t = atomic; // freestanding + using atomic_uint64_t = atomic; // freestanding + + using atomic_int_least8_t = atomic; // freestanding + using atomic_uint_least8_t = atomic; // freestanding + using atomic_int_least16_t = atomic; // freestanding + using atomic_uint_least16_t = atomic; // freestanding + using atomic_int_least32_t = atomic; // freestanding + using atomic_uint_least32_t = atomic; // freestanding + using atomic_int_least64_t = atomic; // freestanding + using atomic_uint_least64_t = atomic; // freestanding + + using atomic_int_fast8_t = atomic; // freestanding + using atomic_uint_fast8_t = atomic; // freestanding + using atomic_int_fast16_t = atomic; // freestanding + using atomic_uint_fast16_t = atomic; // freestanding + using atomic_int_fast32_t = atomic; // freestanding + using atomic_uint_fast32_t = atomic; // freestanding + using atomic_int_fast64_t = atomic; // freestanding + using atomic_uint_fast64_t = atomic; // freestanding + + using atomic_intptr_t = atomic; // freestanding + using atomic_uintptr_t = atomic; // freestanding + using atomic_size_t = atomic; // freestanding + using atomic_ptrdiff_t = atomic; // freestanding + using atomic_intmax_t = atomic; // freestanding + using atomic_uintmax_t = atomic; // freestanding using atomic_signed_lock_free = @\seebelow@; using atomic_unsigned_lock_free = @\seebelow@; // \ref{atomics.flag}, flag type and operations - struct atomic_flag; - - bool atomic_flag_test(const volatile atomic_flag*) noexcept; - bool atomic_flag_test(const atomic_flag*) noexcept; - bool atomic_flag_test_explicit(const volatile atomic_flag*, memory_order) noexcept; - bool atomic_flag_test_explicit(const atomic_flag*, memory_order) noexcept; - bool atomic_flag_test_and_set(volatile atomic_flag*) noexcept; - bool atomic_flag_test_and_set(atomic_flag*) noexcept; - bool atomic_flag_test_and_set_explicit(volatile atomic_flag*, memory_order) noexcept; - bool atomic_flag_test_and_set_explicit(atomic_flag*, memory_order) noexcept; - void atomic_flag_clear(volatile atomic_flag*) noexcept; - void atomic_flag_clear(atomic_flag*) noexcept; - void atomic_flag_clear_explicit(volatile atomic_flag*, memory_order) noexcept; - void atomic_flag_clear_explicit(atomic_flag*, memory_order) noexcept; - - void atomic_flag_wait(const volatile atomic_flag*, bool) noexcept; - void atomic_flag_wait(const atomic_flag*, bool) noexcept; - void atomic_flag_wait_explicit(const volatile atomic_flag*, + struct atomic_flag; // freestanding + + bool atomic_flag_test(const volatile atomic_flag*) noexcept; // freestanding + bool atomic_flag_test(const atomic_flag*) noexcept; // freestanding + bool atomic_flag_test_explicit(const volatile atomic_flag*, // freestanding + memory_order) noexcept; + bool atomic_flag_test_explicit(const atomic_flag*, memory_order) noexcept; // freestanding + bool atomic_flag_test_and_set(volatile atomic_flag*) noexcept; // freestanding + bool atomic_flag_test_and_set(atomic_flag*) noexcept; // freestanding + bool atomic_flag_test_and_set_explicit(volatile atomic_flag*, // freestanding + memory_order) noexcept; + bool atomic_flag_test_and_set_explicit(atomic_flag*, memory_order) noexcept; // freestanding + void atomic_flag_clear(volatile atomic_flag*) noexcept; // freestanding + void atomic_flag_clear(atomic_flag*) noexcept; // freestanding + void atomic_flag_clear_explicit(volatile atomic_flag*, memory_order) noexcept; // freestanding + void atomic_flag_clear_explicit(atomic_flag*, memory_order) noexcept; // freestanding + + void atomic_flag_wait(const volatile atomic_flag*, bool) noexcept; // freestanding + void atomic_flag_wait(const atomic_flag*, bool) noexcept; // freestanding + void atomic_flag_wait_explicit(const volatile atomic_flag*, // freestanding bool, memory_order) noexcept; - void atomic_flag_wait_explicit(const atomic_flag*, + void atomic_flag_wait_explicit(const atomic_flag*, // freestanding bool, memory_order) noexcept; - void atomic_flag_notify_one(volatile atomic_flag*) noexcept; - void atomic_flag_notify_one(atomic_flag*) noexcept; - void atomic_flag_notify_all(volatile atomic_flag*) noexcept; - void atomic_flag_notify_all(atomic_flag*) noexcept; - #define ATOMIC_FLAG_INIT @\seebelow@ + void atomic_flag_notify_one(volatile atomic_flag*) noexcept; // freestanding + void atomic_flag_notify_one(atomic_flag*) noexcept; // freestanding + void atomic_flag_notify_all(volatile atomic_flag*) noexcept; // freestanding + void atomic_flag_notify_all(atomic_flag*) noexcept; // freestanding + #define ATOMIC_FLAG_INIT @\seebelownc@ // freestanding // \ref{atomics.fences}, fences - extern "C" void atomic_thread_fence(memory_order) noexcept; - extern "C" void atomic_signal_fence(memory_order) noexcept; + extern "C" void atomic_thread_fence(memory_order) noexcept; // freestanding + extern "C" void atomic_signal_fence(memory_order) noexcept; // freestanding } \end{codeblock} @@ -2638,14 +2655,11 @@ value of 2 indicates that the types are always lock-free. \pnum -At least one signed integral specialization of the \tcode{atomic} template, +On a hosted implementation\iref{compliance}, +at least one signed integral specialization of the \tcode{atomic} template, along with the specialization for the corresponding unsigned type\iref{basic.fundamental}, is always lock-free. -\begin{note} -\indextext{implementation!freestanding}% -This requirement is optional in freestanding implementations\iref{compliance}. -\end{note} \pnum The functions \tcode{atomic::is_lock_free} and diff --git a/source/utilities.tex b/source/utilities.tex index 642efdf2c9..e915e30195 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -35,6 +35,7 @@ throughout the rest of the library. \begin{codeblock} +// all freestanding #include // see \ref{compare.syn} #include // see \ref{initializer.list.syn} @@ -1350,6 +1351,7 @@ \indexheader{tuple}% \begin{codeblock} +// all freestanding #include // see \ref{compare.syn} namespace std { @@ -9396,109 +9398,115 @@ namespace std { // \ref{func.invoke}, invoke template - constexpr invoke_result_t invoke(F&& f, Args&&... args) + constexpr invoke_result_t invoke(F&& f, Args&&... args) // freestanding noexcept(is_nothrow_invocable_v); template - constexpr R invoke_r(F&& f, Args&&... args) + constexpr R invoke_r(F&& f, Args&&... args) // freestanding noexcept(is_nothrow_invocable_r_v); // \ref{refwrap}, \tcode{reference_wrapper} - template class reference_wrapper; + template class reference_wrapper; // freestanding - template constexpr reference_wrapper ref(T&) noexcept; - template constexpr reference_wrapper cref(const T&) noexcept; - template void ref(const T&&) = delete; - template void cref(const T&&) = delete; + template constexpr reference_wrapper ref(T&) noexcept; // freestanding + template constexpr reference_wrapper cref(const T&) noexcept; // freestanding + template void ref(const T&&) = delete; // freestanding + template void cref(const T&&) = delete; // freestanding - template constexpr reference_wrapper ref(reference_wrapper) noexcept; - template constexpr reference_wrapper cref(reference_wrapper) noexcept; + template + constexpr reference_wrapper ref(reference_wrapper) noexcept; // freestanding + template + constexpr reference_wrapper cref(reference_wrapper) noexcept; // freestanding // \ref{arithmetic.operations}, arithmetic operations - template struct plus; - template struct minus; - template struct multiplies; - template struct divides; - template struct modulus; - template struct negate; - template<> struct plus; - template<> struct minus; - template<> struct multiplies; - template<> struct divides; - template<> struct modulus; - template<> struct negate; + template struct plus; // freestanding + template struct minus; // freestanding + template struct multiplies; // freestanding + template struct divides; // freestanding + template struct modulus; // freestanding + template struct negate; // freestanding + template<> struct plus; // freestanding + template<> struct minus; // freestanding + template<> struct multiplies; // freestanding + template<> struct divides; // freestanding + template<> struct modulus; // freestanding + template<> struct negate; // freestanding // \ref{comparisons}, comparisons - template struct equal_to; - template struct not_equal_to; - template struct greater; - template struct less; - template struct greater_equal; - template struct less_equal; - template<> struct equal_to; - template<> struct not_equal_to; - template<> struct greater; - template<> struct less; - template<> struct greater_equal; - template<> struct less_equal; + template struct equal_to; // freestanding + template struct not_equal_to; // freestanding + template struct greater; // freestanding + template struct less; // freestanding + template struct greater_equal; // freestanding + template struct less_equal; // freestanding + template<> struct equal_to; // freestanding + template<> struct not_equal_to; // freestanding + template<> struct greater; // freestanding + template<> struct less; // freestanding + template<> struct greater_equal; // freestanding + template<> struct less_equal; // freestanding // \ref{comparisons.three.way}, class \tcode{compare_three_way} - struct compare_three_way; + struct compare_three_way; // freestanding // \ref{logical.operations}, logical operations - template struct logical_and; - template struct logical_or; - template struct logical_not; - template<> struct logical_and; - template<> struct logical_or; - template<> struct logical_not; + template struct logical_and; // freestanding + template struct logical_or; // freestanding + template struct logical_not; // freestanding + template<> struct logical_and; // freestanding + template<> struct logical_or; // freestanding + template<> struct logical_not; // freestanding // \ref{bitwise.operations}, bitwise operations - template struct bit_and; - template struct bit_or; - template struct bit_xor; - template struct bit_not; - template<> struct bit_and; - template<> struct bit_or; - template<> struct bit_xor; - template<> struct bit_not; + template struct bit_and; // freestanding + template struct bit_or; // freestanding + template struct bit_xor; // freestanding + template struct bit_not; // freestanding + template<> struct bit_and; // freestanding + template<> struct bit_or; // freestanding + template<> struct bit_xor; // freestanding + template<> struct bit_not; // freestanding // \ref{func.identity}, identity - struct identity; + struct identity; // freestanding // \ref{func.not.fn}, function template \tcode{not_fn} - template constexpr @\unspec@ not_fn(F&& f); + template constexpr @\unspec@ not_fn(F&& f); // freestanding // \ref{func.bind.partial}, function templates \tcode{bind_front} and \tcode{bind_back} - template constexpr @\unspec@ bind_front(F&&, Args&&...); - template constexpr @\unspec@ bind_back(F&&, Args&&...); + template + constexpr @\unspec@ bind_front(F&&, Args&&...); // freestanding + template + constexpr @\unspec@ bind_back(F&&, Args&&...); // freestanding // \ref{func.bind}, bind - template struct is_bind_expression; + template struct is_bind_expression; // freestanding template - inline constexpr bool @\libglobal{is_bind_expression_v}@ = is_bind_expression::value; - template struct is_placeholder; + inline constexpr bool @\libglobal{is_bind_expression_v}@ = // freestanding + is_bind_expression::value; + template struct is_placeholder; // freestanding template - inline constexpr int @\libglobal{is_placeholder_v}@ = is_placeholder::value; + inline constexpr int @\libglobal{is_placeholder_v}@ = // freestanding + is_placeholder::value; template - constexpr @\unspec@ bind(F&&, BoundArgs&&...); + constexpr @\unspec@ bind(F&&, BoundArgs&&...); // freestanding template - constexpr @\unspec@ bind(F&&, BoundArgs&&...); + constexpr @\unspec@ bind(F&&, BoundArgs&&...); // freestanding namespace placeholders { // \tcode{\placeholder{M}} is the \impldef{number of placeholders for bind expressions} number of placeholders - @\seebelownc@ _1; - @\seebelownc@ _2; + @\seebelownc@ _1; // freestanding + @\seebelownc@ _2; // freestanding . . . - @\seebelownc@ _@\placeholdernc{M}@; + @\seebelownc@ _@\placeholdernc{M}@; // freestanding } // \ref{func.memfn}, member function adaptors template - constexpr @\unspec@ mem_fn(R T::*) noexcept; + constexpr @\unspec@ mem_fn(R T::*) noexcept; // freestanding // \ref{func.wrap}, polymorphic function wrappers class bad_function_call; @@ -9521,7 +9529,7 @@ // \ref{func.search}, searchers template> - class default_searcher; + class default_searcher; // freestanding template::value_type>, @@ -9535,16 +9543,16 @@ // \ref{unord.hash}, class template hash template - struct hash; + struct hash; // freestanding namespace ranges { // \ref{range.cmp}, concept-constrained comparisons - struct equal_to; - struct not_equal_to; - struct greater; - struct less; - struct greater_equal; - struct less_equal; + struct equal_to; // freestanding + struct not_equal_to; // freestanding + struct greater; // freestanding + struct less; // freestanding + struct greater_equal; // freestanding + struct less_equal; // freestanding } } \end{codeblock} @@ -11403,6 +11411,9 @@ \end{codeblock}% \indextext{function object!binders|)} +\pnum +Placeholders are freestanding entities\iref{freestanding.entity}. + \rSec2[func.memfn]{Function template \tcode{mem_fn}}% \indextext{function object!\idxcode{mem_fn}|(} @@ -15509,6 +15520,7 @@ \rSec2[bit.syn]{Header \tcode{} synopsis} \begin{codeblock} +// all freestanding namespace std { // \ref{bit.cast}, \tcode{bit_cast} template From 5e0de8beff2c050174b09b6cdd4747ad19e147f1 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sun, 7 Aug 2022 21:57:41 -0700 Subject: [PATCH 195/430] [ranges.syn] Colapse freestanding entities to fit on a single line --- source/ranges.tex | 90 ++++++++++++++--------------------------------- 1 file changed, 26 insertions(+), 64 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index 40041e8568..337a85fff0 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -167,9 +167,7 @@ requires is_object_v class single_view; // freestanding - namespace views { - inline constexpr @\unspec@ single = @\unspec@; // freestanding - } + namespace views { inline constexpr @\unspecnc@ single = @\unspecnc@; } // freestanding template using @\exposidnc{maybe-const}@ = conditional_t; // \expos @@ -182,9 +180,7 @@ template inline constexpr bool enable_borrowed_range> = true; // freestanding - namespace views { - inline constexpr @\unspec@ iota = @\unspec@; // freestanding - } + namespace views { inline constexpr @\unspecnc@ iota = @\unspecnc@; } // freestanding // \ref{range.istream}, istream view template<@\libconcept{movable}@ Val, class CharT, class Traits = char_traits> @@ -195,7 +191,7 @@ template using wistream_view = basic_istream_view; - namespace views { template inline constexpr @\unspec@ istream = @\unspec@; } + namespace views { template inline constexpr @\unspecnc@ istream = @\unspecnc@; } // \ref{range.adaptor.object}, range adaptor objects template @@ -204,7 +200,7 @@ // \ref{range.all}, all view namespace views { - inline constexpr @\unspec@ all = @\unspec@; // freestanding + inline constexpr @\unspecnc@ all = @\unspecnc@; // freestanding template<@\libconcept{viewable_range}@ R> using all_t = decltype(all(declval())); // freestanding @@ -232,9 +228,7 @@ requires @\libconcept{view}@ && is_object_v class filter_view; // freestanding - namespace views { - inline constexpr @\unspec@ filter = @\unspec@; // freestanding - } + namespace views { inline constexpr @\unspecnc@ filter = @\unspecnc@; } // freestanding // \ref{range.transform}, transform view template<@\libconcept{input_range}@ V, @\libconcept{copy_constructible}@ F> @@ -243,9 +237,7 @@ @\exposconcept{can-reference}@>> class transform_view; // freestanding - namespace views { - inline constexpr @\unspec@ transform = @\unspec@; // freestanding - } + namespace views { inline constexpr @\unspecnc@ transform = @\unspecnc@; } // freestanding // \ref{range.take}, take view template<@\libconcept{view}@> class take_view; // freestanding @@ -254,9 +246,7 @@ inline constexpr bool enable_borrowed_range> = // freestanding enable_borrowed_range; - namespace views { - inline constexpr @\unspec@ take = @\unspec@; // freestanding - } + namespace views { inline constexpr @\unspecnc@ take = @\unspecnc@; } // freestanding // \ref{range.take.while}, take while view template<@\libconcept{view}@ V, class Pred> @@ -264,9 +254,7 @@ @\libconcept{indirect_unary_predicate}@> class take_while_view; // freestanding - namespace views { - inline constexpr @\unspec@ take_while = @\unspec@; // freestanding - } + namespace views { inline constexpr @\unspecnc@ take_while = @\unspecnc@; } // freestanding // \ref{range.drop}, drop view template<@\libconcept{view}@ V> @@ -276,9 +264,7 @@ inline constexpr bool enable_borrowed_range> = // freestanding enable_borrowed_range; - namespace views { - inline constexpr @\unspec@ drop = @\unspec@; // freestanding - } + namespace views { inline constexpr @\unspecnc@ drop = @\unspecnc@; } // freestanding // \ref{range.drop.while}, drop while view template<@\libconcept{view}@ V, class Pred> @@ -290,18 +276,14 @@ inline constexpr bool enable_borrowed_range> = // freestanding enable_borrowed_range; - namespace views { - inline constexpr @\unspec@ drop_while = @\unspec@; // freestanding - } + namespace views { inline constexpr @\unspecnc@ drop_while = @\unspecnc@; } // freestanding // \ref{range.join}, join view template<@\libconcept{input_range}@ V> requires @\libconcept{view}@ && @\libconcept{input_range}@> class join_view; // freestanding - namespace views { - inline constexpr @\unspec@ join = @\unspec@; // freestanding - } + namespace views { inline constexpr @\unspecnc@ join = @\unspecnc@; } // freestanding // \ref{range.join.with}, join with view template @@ -313,9 +295,7 @@ && @\exposconcept{compatible-joinable-ranges}@, Pattern> class join_with_view; // freestanding - namespace views { - inline constexpr @\unspec@ join_with = @\unspec@; // freestanding - } + namespace views { inline constexpr @\unspecnc@ join_with = @\unspecnc@; } // freestanding // \ref{range.lazy.split}, lazy split view template @@ -334,14 +314,12 @@ class split_view; // freestanding namespace views { - inline constexpr @\unspec@ lazy_split = @\unspec@; // freestanding - inline constexpr @\unspec@ split = @\unspec@; // freestanding + inline constexpr @\unspecnc@ lazy_split = @\unspecnc@; // freestanding + inline constexpr @\unspecnc@ split = @\unspecnc@; // freestanding } // \ref{range.counted}, counted view - namespace views { - inline constexpr @\unspec@ counted = @\unspec@; // freestanding - } + namespace views { inline constexpr @\unspecnc@ counted = @\unspecnc@; } // freestanding // \ref{range.common}, common view template<@\libconcept{view}@ V> @@ -352,9 +330,7 @@ inline constexpr bool enable_borrowed_range> = // freestanding enable_borrowed_range; - namespace views { - inline constexpr @\unspec@ common = @\unspec@; // freestanding - } + namespace views { inline constexpr @\unspecnc@ common = @\unspecnc@; } // freestanding // \ref{range.reverse}, reverse view template<@\libconcept{view}@ V> @@ -365,9 +341,7 @@ inline constexpr bool enable_borrowed_range> = // freestanding enable_borrowed_range; - namespace views { - inline constexpr @\unspec@ reverse = @\unspec@; // freestanding - } + namespace views { inline constexpr @\unspecnc@ reverse = @\unspecnc@; } // freestanding // \ref{range.elements}, elements view template<@\libconcept{input_range}@ V, size_t N> @@ -385,7 +359,7 @@ namespace views { template - inline constexpr @\unspec@ elements = @\unspec@; // freestanding + inline constexpr @\unspecnc@ elements = @\unspecnc@; // freestanding inline constexpr auto @\libmember{keys}{views}@ = elements<0>; // freestanding inline constexpr auto @\libmember{values}{views}@ = elements<1>; // freestanding } @@ -399,9 +373,7 @@ inline constexpr bool enable_borrowed_range> = // freestanding (enable_borrowed_range && ...); - namespace views { - inline constexpr @\unspec@ zip = @\unspec@; // freestanding - } + namespace views { inline constexpr @\unspecnc@ zip = @\unspecnc@; } // freestanding // \ref{range.zip.transform}, zip transform view template<@\libconcept{copy_constructible}@ F, @\libconcept{input_range}@... Views> @@ -410,9 +382,7 @@ @\exposconcept{can-reference}@...>> class zip_transform_view; // freestanding - namespace views { - inline constexpr @\unspec@ zip_transform = @\unspec@; // freestanding - } + namespace views { inline constexpr @\unspecnc@ zip_transform = @\unspecnc@; } // freestanding // \ref{range.adjacent}, adjacent view template<@\libconcept{forward_range}@ V, size_t N> @@ -425,7 +395,7 @@ namespace views { template - inline constexpr @\unspec@ adjacent = @\unspec@ ; // freestanding + inline constexpr @\unspecnc@ adjacent = @\unspecnc@; // freestanding inline constexpr auto @\libmember{pairwise}{views}@ = adjacent<2>; // freestanding } @@ -436,7 +406,7 @@ namespace views { template - inline constexpr @\unspec@ adjacent_transform = @\unspec@; // freestanding + inline constexpr @\unspecnc@ adjacent_transform = @\unspecnc@; // freestanding inline constexpr auto @\libmember{pairwise_transform}{views}@ = adjacent_transform<2>; // freestanding } @@ -453,9 +423,7 @@ inline constexpr bool enable_borrowed_range> = // freestanding @\libconcept{forward_range}@ && enable_borrowed_range; - namespace views { - inline constexpr @\unspec@ chunk = @\unspec@; // freestanding - } + namespace views { inline constexpr @\unspecnc@ chunk = @\unspecnc@; } // freestanding // \ref{range.slide}, slide view template<@\libconcept{forward_range}@ V> @@ -466,18 +434,14 @@ inline constexpr bool enable_borrowed_range> = enable_borrowed_range; // freestanding - namespace views { - inline constexpr @\unspec@ slide = @\unspec@; // freestanding - } + namespace views { inline constexpr @\unspecnc@ slide = @\unspecnc@; } // freestanding // \ref{range.chunk.by}, chunk by view template<@\libconcept{forward_range}@ V, @\libconcept{indirect_binary_predicate}@, iterator_t> Pred> requires @\libconcept{view}@ && is_object_v class chunk_by_view; // freestanding - namespace views { // freestanding - inline constexpr @\unspec@ chunk_by = @\unspec@; // freestanding - } + namespace views { inline constexpr @\unspecnc@ chunk_by = @\unspecnc@; } // freestanding } namespace std { @@ -506,9 +470,7 @@ using type = S; // freestanding }; - struct from_range_t { // freestanding - explicit from_range_t() = default; // freestanding - }; + struct from_range_t { explicit from_range_t() = default; }; // freestanding inline constexpr from_range_t from_range{}; // freestanding } \end{codeblock} From ea25443e8982cecfe8fbeb6f627eb9d6d34cd119 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sun, 24 Jul 2022 09:02:14 +0200 Subject: [PATCH 196/430] P1899R3 stride_view Editorial changes: * The return types of operator+ and operator- had been misspelled in the synopsis (but not in the detailed specification), and they have been fixed. * The view typedef-name views::stride has been marked freestanding as per P1642R11. --- source/ranges.tex | 623 +++++++++++++++++++++++++++++++++++++++++++++ source/support.tex | 1 + 2 files changed, 624 insertions(+) diff --git a/source/ranges.tex b/source/ranges.tex index 337a85fff0..9f5aa0fabc 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -442,6 +442,16 @@ class chunk_by_view; // freestanding namespace views { inline constexpr @\unspecnc@ chunk_by = @\unspecnc@; } // freestanding + + // \ref{range.stride}, stride view + template<@\libconcept{input_range}@ V> + requires @\libconcept{view}@ + class stride_view; + + template + inline constexpr bool enable_borrowed_range> = enable_borrowed_range; + + namespace views { inline constexpr @\unspecnc@ stride = @\unspecnc@; } // freestanding } namespace std { @@ -12827,3 +12837,616 @@ \returns \tcode{x.\exposid{current_} == x.\exposid{next_}}. \end{itemdescr} + +\rSec2[range.stride]{Stride view} + +\rSec3[range.stride.overview]{Overview} + +\pnum +\tcode{stride_view} presents a \libconcept{view} of an underlying sequence, +advancing over $n$ elements at a time, +as opposed to the usual single-step succession. + +\pnum +The name \tcode{views::stride} denotes +a range adaptor object\iref{range.adaptor.object}. +Given subexpressions \tcode{E} and \tcode{N}, +the expression \tcode{views::stride(E, N)} +is expression-equivalent to \tcode{stride_view(E, N)}. + +\pnum +\begin{example} +\begin{codeblock} +auto input = views::iota(0, 12) | views::stride(3); +ranges::copy(input, ostream_iterator(cout, " ")); // prints 0 3 6 9 +ranges::copy(input | views::reverse, ostream_iterator(cout, " ")); // prints 9 6 3 0 +\end{codeblock} +\end{example} + +\rSec3[range.stride.view]{Class template \tcode{stride_view}} + +\begin{codeblock} +namespace std::ranges { + template<@\libconcept{input_range}@ V> + requires @\libconcept{view}@ + class stride_view : public view_interface> { + V @\exposid{base_}@; // \expos + range_difference_t @\exposid{stride_}@; // \expos + // \ref{range.stride.iterator}, class template \tcode{stride_view::\exposid{iterator}} + template class @\exposid{iterator}@; // \expos + public: + constexpr explicit stride_view(V base, range_difference_t stride); + + constexpr V base() const & requires @\libconcept{copy_constructible}@ { return @\exposid{base_}@; } + constexpr V base() && { return std::move(@\exposid{base_}@); } + + constexpr range_difference_t stride() const noexcept; + + constexpr auto begin() requires (!@\exposconcept{simple-view}@) { + return @\exposid{iterator}@(this, ranges::begin(@\exposid{base_}@)); + } + + constexpr auto begin() const requires @\libconcept{range}@ { + return @\exposid{iterator}@(this, ranges::begin(@\exposid{base_}@)); + } + + constexpr auto end() requires (!@\exposconcept{simple-view}@) { + if constexpr (@\libconcept{common_range}@ && @\libconcept{sized_range}@ && @\libconcept{forward_range}@) { + auto missing = (@\exposid{stride_}@ - ranges::distance(@\exposid{base_}@) % @\exposid{stride_}@) % @\exposid{stride_}@; + return @\exposid{iterator}@(this, ranges::end(@\exposid{base_}@), missing); + } else if constexpr (@\libconcept{common_range}@ && !@\libconcept{bidirectional_range}@) { + return @\exposid{iterator}@(this, ranges::end(@\exposid{base_}@)); + } else { + return default_sentinel; + } + } + + constexpr auto end() const requires @\libconcept{range}@ { + if constexpr (@\libconcept{common_range}@ && @\libconcept{sized_range}@ && @\libconcept{forward_range}@) { + auto missing = (@\exposid{stride_}@ - ranges::distance(@\exposid{base_}@) % @\exposid{stride_}@) % @\exposid{stride_}@; + return @\exposid{iterator}@(this, ranges::end(@\exposid{base_}@), missing); + } else if constexpr (@\libconcept{common_range}@ && !@\libconcept{bidirectional_range}@) { + return @\exposid{iterator}@(this, ranges::end(@\exposid{base_}@)); + } else { + return default_sentinel; + } + } + + constexpr auto size() requires @\libconcept{sized_range}@; + constexpr auto size() const requires @\libconcept{sized_range}@; + }; + + template + stride_view(R&&, range_difference_t) -> stride_view>; +} +\end{codeblock} + +\indexlibraryctor{stride_view}% +\begin{itemdecl} +constexpr stride_view(V base, range_difference_t stride); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{stride > 0} is \tcode{true}. + +\pnum +\effects +Initializes \exposid{base_} with \tcode{std::move(base)} and +\exposid{stride_} with \tcode{stride}. +\end{itemdescr} + +\indexlibrarymember{stride}{stride_view}% +\begin{itemdecl} +constexpr range_difference_t stride() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\exposid{stride_}. +\end{itemdescr} + +\indexlibrarymember{size}{stride_view}% +\begin{itemdecl} +constexpr auto size() requires @\libconcept{sized_range}@; +constexpr auto size() const requires @\libconcept{sized_range}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return @\exposid{to-unsigned-like}@(@\exposid{div-ceil}@(ranges::distance(@\exposid{base_}@), @\exposid{stride_}@)); +\end{codeblock} +\end{itemdescr} + +\rSec3[range.stride.iterator]{Class template \tcode{stride_view::\exposid{iterator}}} + +\begin{codeblock} +namespace std::ranges { + template<@\libconcept{input_range}@ V> + requires @\libconcept{view}@ + template + class stride_view::@\exposid{iterator}@ { + using @\exposid{Parent}@ = @\exposid{maybe-const}@; // \expos + using @\exposid{Base}@ = @\exposid{maybe-const}@; // \expos + + iterator_t<@\exposid{Base}@> @\exposid{current_}@ = iterator_t<@\exposid{Base}@>(); // \expos + sentinel_t<@\exposid{Base}@> @\exposid{end_}@ = sentinel_t<@\exposid{Base}@>(); // \expos + range_difference_t<@\exposid{Base}@> @\exposid{stride_}@ = 0; // \expos + range_difference_t<@\exposid{Base}@> @\exposid{missing_}@ = 0; // \expos + + constexpr @\exposid{iterator}@(@\exposid{Parent}@* parent, iterator_t<@\exposid{Base}@> current, // \expos + range_difference_t<@\exposid{Base}@> missing = 0); + public: + using difference_type = range_difference_t<@\exposid{Base}@>; + using value_type = range_value_t<@\exposid{Base}@>; + using iterator_concept = @\seebelow@; + using iterator_category = @\seebelow@; // not always present + + iterator() requires @\libconcept{default_initializable}@> = default; + + constexpr @\exposid{iterator}@(@\exposid{iterator}@ other) + requires Const && @\libconcept{convertible_to}@, iterator_t<@\exposid{Base}@>> + && @\libconcept{convertible_to}@, sentinel_t<@\exposid{Base}@>>; + + constexpr iterator_t<@\exposid{Base}@> base() &&; + constexpr const iterator_t<@\exposid{Base}@>& base() const & noexcept; + + constexpr decltype(auto) operator*() const { return *@\exposid{current_}@; } + + constexpr @\exposid{iterator}@& operator++(); + constexpr void operator++(int); + constexpr @\exposid{iterator}@ operator++(int) requires @\libconcept{forward_range}@<@\exposid{Base}@>; + + constexpr @\exposid{iterator}@& operator--() requires @\libconcept{bidirectional_range}@<@\exposid{Base}@>; + constexpr @\exposid{iterator}@ operator--(int) requires @\libconcept{bidirectional_range}@<@\exposid{Base}@>; + + constexpr @\exposid{iterator}@& operator+=(difference_type n) requires @\libconcept{random_access_range}@<@\exposid{Base}@>; + constexpr @\exposid{iterator}@& operator-=(difference_type n) requires @\libconcept{random_access_range}@<@\exposid{Base}@>; + + constexpr decltype(auto) operator[](difference_type n) const + requires @\libconcept{random_access_range}@<@\exposid{Base}@> + { return *(*this + n); } + + friend constexpr bool operator==(const @\exposid{iterator}@& x, default_sentinel_t); + + friend constexpr bool operator==(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) + requires @\libconcept{equality_comparable}@>; + + friend constexpr bool operator<(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) + requires @\libconcept{random_access_range}@<@\exposid{Base}@>; + + friend constexpr bool operator>(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) + requires @\libconcept{random_access_range}@<@\exposid{Base}@>; + + friend constexpr bool operator<=(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) + requires @\libconcept{random_access_range}@<@\exposid{Base}@>; + + friend constexpr bool operator>=(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) + requires @\libconcept{random_access_range}@<@\exposid{Base}@>; + + friend constexpr auto operator<=>(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) + requires @\libconcept{random_access_range}@<@\exposid{Base}@> && @\libconcept{three_way_comparable}@>; + + friend constexpr @\exposid{iterator}@ operator+(const @\exposid{iterator}@& x, difference_type n) + requires @\libconcept{random_access_range}@<@\exposid{Base}@>; + friend constexpr @\exposid{iterator}@ operator+(difference_type n, const @\exposid{iterator}@& x) + requires @\libconcept{random_access_range}@<@\exposid{Base}@>; + friend constexpr @\exposid{iterator}@ operator-(const @\exposid{iterator}@& x, difference_type n) + requires @\libconcept{random_access_range}@<@\exposid{Base}@>; + friend constexpr difference_type operator-(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) + requires @\libconcept{sized_sentinel_for}@, iterator_t<@\exposid{Base}@>>; + + friend constexpr difference_type operator-(default_sentinel_t y, const @\exposid{iterator}@& x) + requires @\libconcept{sized_sentinel_for}@, iterator_t<@\exposid{Base}@>>; + friend constexpr difference_type operator-(const @\exposid{iterator}@& x, default_sentinel_t y) + requires @\libconcept{sized_sentinel_for}@, iterator_t<@\exposid{Base}@>>; + + friend constexpr range_rvalue_reference_t<@\exposid{Base}@> iter_move(const @\exposid{iterator}@& i) + noexcept(noexcept(ranges::iter_move(i.@\exposid{current_}@))); + + friend constexpr void iter_swap(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) + noexcept(noexcept(ranges::iter_swap(x.@\exposid{current_}@, y.@\exposid{current_}@))) + requires @\libconcept{indirectly_swappable}@>; + }; +} +\end{codeblock} + +\pnum +\tcode{\exposid{iterator}::iterator_concept} is defined as follows: +\begin{itemize} +\item +If \exposid{Base} models \libconcept{random_access_range}, +then \tcode{iterator_concept} denotes \tcode{random_access_iterator_tag}. +\item +Otherwise, if \exposid{Base} models \libconcept{bidirectional_range}, +then \tcode{iterator_concept} denotes \tcode{bidirectional_iterator_tag}. +\item +Otherwise, if \exposid{Base} models \libconcept{forward_range}, +then \tcode{iterator_concept} denotes \tcode{forward_iterator_tag}. +\item +Otherwise, \tcode{iterator_concept} denotes \tcode{input_iterator_tag}. +\end{itemize} + +\pnum +The member \grammarterm{typedef-name} \tcode{iterator_category} is defined +if and only if \exposid{Base} models \libconcept{forward_range}. +In that case, +\tcode{\exposid{iterator}::iterator_category} is defined as follows: +\begin{itemize} +\item +Let \tcode{C} denote +the type \tcode{iterator_traits>::iterator_category}. +\item +If \tcode{C} models +\tcode{\libconcept{derived_from}}, +then \tcode{iterator_category} denotes \tcode{ran\-dom_access_iterator_tag}. +\item +Otherwise, \tcode{iterator_category} denotes \tcode{C}. +\end{itemize} + +\indexlibraryctor{stride_view::iterator}% +\begin{itemdecl} +constexpr @\exposid{iterator}@(@\exposid{Parent}@* parent, iterator_t<@\exposid{Base}@> current, + range_difference_t<@\exposid{Base}@> missing = 0); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \exposid{current_} with \tcode{std::move(current)}, +\exposid{end_} with \tcode{ranges::end(parent->\exposid{base_})}, +\exposid{stride_} with \tcode{parent->\exposid{stride_}}, and +\exposid{missing_} with \tcode{missing}. +\end{itemdescr} + +\indexlibraryctor{stride_view::iterator}% +\begin{itemdecl} +constexpr @\exposid{iterator}@(@\exposid{iterator}@ i) + requires Const && @\libconcept{convertible_to}@, iterator_t<@\exposid{Base}@>> + && @\libconcept{convertible_to}@, sentinel_t<@\exposid{Base}@>>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \exposid{current_} with \tcode{std::move(i.\exposid{current_})}, +\exposid{end_} with \tcode{std::move(i.\exposid{end_})}, +\exposid{stride_} with \tcode{i.\exposid{stride_}}, and +\exposid{missing_} with \tcode{i.\exposid{missing_}}. +\end{itemdescr} + +\indexlibrarymember{base}{stride_view::iterator}% +\begin{itemdecl} +constexpr iterator_t<@\exposid{Base}@> base() &&; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{std::move(\exposid{current_})}. +\end{itemdescr} + +\indexlibrarymember{base}{stride_view::iterator}% +\begin{itemdecl} +constexpr const iterator_t<@\exposid{Base}@>& base() const & noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\exposid{current_}. +\end{itemdescr} + +\indexlibrarymember{operator++}{stride_view::iterator}% +\begin{itemdecl} +constexpr @\exposid{iterator}@& operator++(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{\exposid{current_} != \exposid{end_}} is \tcode{true}. + +\pnum +\effects +Equivalent to: +\begin{codeblock} +@\exposid{missing_}@ = ranges::advance(@\exposid{current_}@, @\exposid{stride_}@, @\exposid{end_}@); +return *this; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator++}{stride_view::iterator}% +\begin{itemdecl} +constexpr void operator++(int); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{++*this;} +\end{itemdescr} + +\indexlibrarymember{operator++}{stride_view::iterator}% +\begin{itemdecl} +constexpr @\exposid{iterator}@ operator++(int) requires @\libconcept{forward_range}@<@\exposid{Base}@>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto tmp = *this; +++*this; +return tmp; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator--}{stride_view::iterator}% +\begin{itemdecl} +constexpr @\exposid{iterator}@& operator--() requires @\libconcept{bidirectional_range}@<@\exposid{Base}@>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +ranges::advance(@\exposid{current_}@, @\exposid{missing_}@ - @\exposid{stride_}@); +@\exposid{missing_}@ = 0; +return *this; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator--}{stride_view::iterator}% +\begin{itemdecl} +constexpr @\exposid{iterator}@ operator--(int) requires @\libconcept{bidirectional_range}@<@\exposid{Base}@>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto tmp = *this; +--*this; +return tmp; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator+=}{stride_view::iterator}% +\begin{itemdecl} +constexpr @\exposid{iterator}@& operator+=(difference_type n) requires @\libconcept{random_access_range}@<@\exposid{Base}@>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +If \tcode{n} is positive, +\tcode{ranges::distance(\exposid{current_}, \exposid{end_}) > \exposid{stride_} * (n - 1)} +is \tcode{true}. +\begin{note} +If \tcode{n} is negative, the \Fundescx{Effects} paragraph implies a precondition. +\end{note} + +\pnum +\effects +Equivalent to: +\begin{codeblock} +if (n > 0) { + @\exposid{missing_}@ = ranges::advance(@\exposid{current_}@, @\exposid{stride_}@ * n, @\exposid{end_}@); +} else if (n < 0) { + ranges::advance(@\exposid{current_}@, @\exposid{stride_}@ * n + @\exposid{missing_}@); + @\exposid{missing_}@ = 0; +} +return *this; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator-=}{stride_view::iterator}% +\begin{itemdecl} +constexpr @\exposid{iterator}@& operator-=(difference_type x) + requires @\libconcept{random_access_range}@<@\exposid{Base}@>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return *this += -x;} +\end{itemdescr} + +\indexlibrarymember{operator==}{stride_view::iterator}% +\begin{itemdecl} +friend constexpr bool operator==(const @\exposid{iterator}@& x, default_sentinel_t); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{x.\exposid{current_} == x.\exposid{end_}}. +\end{itemdescr} + +\indexlibrarymember{operator==}{stride_view::iterator}% +\begin{itemdecl} +friend constexpr bool operator==(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) + requires @\libconcept{equality_comparable}@>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{x.\exposid{current_} == y.\exposid{current_}}. +\end{itemdescr} + +\indexlibrarymember{operator<}{stride_view::iterator}% +\begin{itemdecl} +friend constexpr bool operator<(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) + requires @\libconcept{random_access_range}@<@\exposid{Base}@>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{x.\exposid{current_} < y.\exposid{current_}}. +\end{itemdescr} + +\indexlibrarymember{operator>}{stride_view::iterator}% +\begin{itemdecl} +friend constexpr bool operator>(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) + requires @\libconcept{random_access_range}@<@\exposid{Base}@>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return y < x;} +\end{itemdescr} + +\indexlibrarymember{operator<=}{stride_view::iterator}% +\begin{itemdecl} +friend constexpr bool operator<=(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) + requires @\libconcept{random_access_range}@<@\exposid{Base}@>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return !(y < x);} +\end{itemdescr} + +\indexlibrarymember{operator>=}{stride_view::iterator}% +\begin{itemdecl} +friend constexpr bool operator>=(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) + requires @\libconcept{random_access_range}@<@\exposid{Base}@>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return !(x < y);} +\end{itemdescr} + +\indexlibrarymember{operator<=>}{stride_view::iterator}% +\begin{itemdecl} +friend constexpr auto operator<=>(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) + requires @\libconcept{random_access_range}@<@\exposid{Base}@> && @\libconcept{three_way_comparable}@>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{x.\exposid{current_} <=> y.\exposid{current_}}. +\end{itemdescr} + +\indexlibrarymember{operator+}{stride_view::iterator}% +\begin{itemdecl} +friend constexpr @\exposid{iterator}@ operator+(const @\exposid{iterator}@& i, difference_type n) + requires @\libconcept{random_access_range}@<@\exposid{Base}@>; +friend constexpr @\exposid{iterator}@ operator+(difference_type n, const @\exposid{iterator}@& i) + requires @\libconcept{random_access_range}@<@\exposid{Base}@>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto r = i; +r += n; +return r; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator-}{stride_view::iterator}% +\begin{itemdecl} +friend constexpr @\exposid{iterator}@ operator-(const @\exposid{iterator}@& i, difference_type n) + requires @\libconcept{random_access_range}@<@\exposid{Base}@>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto r = i; +r -= n; +return r; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator-}{stride_view::iterator}% +\begin{itemdecl} +friend constexpr difference_type operator-(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) + requires @\libconcept{sized_sentinel_for}@, iterator_t<@\exposid{Base}@>>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +Let \tcode{N} be \tcode{(x.\exposid{current_} - y.\exposid{current_})}. +\begin{itemize} +\item +If \exposid{Base} models \libconcept{forward_range}, +\tcode{(N + x.\exposid{missing_} - y.\exposid{missing_}) / x.\exposid{stride_}}. +\item +Otherwise, if \tcode{N} is negative, \tcode{-\exposid{div-ceil}(-N, x.\exposid{stride_})}. +\item +Otherwise, \tcode{\exposid{div-ceil}(N, x.\exposid{stride_})}. +\end{itemize} +\end{itemdescr} + +\indexlibrarymember{operator-}{stride_view::iterator}% +\begin{itemdecl} +friend constexpr difference_type operator-(default_sentinel_t y, const @\exposid{iterator}@& x) + requires @\libconcept{sized_sentinel_for}@, iterator_t<@\exposid{Base}@>>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{\exposid{div-ceil}(x.\exposid{end_} - x.\exposid{current_}, x.\exposid{stride_})}. +\end{itemdescr} + +\indexlibrarymember{operator-}{stride_view::iterator}% +\begin{itemdecl} +friend constexpr difference_type operator-(const @\exposid{iterator}@& x, default_sentinel_t y) + requires @\libconcept{sized_sentinel_for}@, iterator_t<@\exposid{Base}@>>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return -(y - x);} +\end{itemdescr} + +\indexlibrarymember{iter_move}{stride_view::iterator}% +\begin{itemdecl} +friend constexpr range_rvalue_reference_t<@\exposid{Base}@> iter_move(const @\exposid{iterator}@& i) + noexcept(noexcept(ranges::iter_move(i.@\exposid{current_}@))); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return ranges::iter_move(i.\exposid{current_});} +\end{itemdescr} + +\indexlibrarymember{iter_swap}{stride_view::iterator}% +\begin{itemdecl} +friend constexpr void iter_swap(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) + noexcept(noexcept(ranges::iter_swap(x.@\exposid{current_}@, y.@\exposid{current_}@))) + requires @\libconcept{indirectly_swappable}@>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\tcode{ranges::iter_swap(x.\exposid{current_}, y.\exposid{current_});} +\end{itemdescr} diff --git a/source/support.tex b/source/support.tex index 6cd1d6d08b..f0a71c7b9e 100644 --- a/source/support.tex +++ b/source/support.tex @@ -681,6 +681,7 @@ #define @\defnlibxname{cpp_lib_ranges_join_with}@ 202202L // also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_slide}@ 202202L // also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_starts_ends_with}@ 202106L // also in \libheader{algorithm} +#define @\defnlibxname{cpp_lib_ranges_stride}@ 202207L // also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_to_container}@ 202202L // also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_zip}@ 202110L // also in \libheader{ranges}, \libheader{tuple}, \libheader{utility} #define @\defnlibxname{cpp_lib_raw_memory_algorithms}@ 201606L // also in \libheader{memory} From 66b2a204bd4449c399e47fb30210824571975430 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Fri, 29 Jul 2022 14:22:47 -0700 Subject: [PATCH 197/430] P2093R14 Formatted output --- source/back.tex | 5 + source/iostreams.tex | 282 +++++++++++++++++++++++++++++++++++++++++++ source/lib-intro.tex | 1 + source/support.tex | 1 + 4 files changed, 289 insertions(+) diff --git a/source/back.tex b/source/back.tex index 60a20e7d51..dda5569dc8 100644 --- a/source/back.tex +++ b/source/back.tex @@ -31,6 +31,11 @@ \chapter{Bibliography} Edited by Mark Davis. Revision 33; issued for Unicode 13.0.0. 2020-02-13 [viewed 2021-06-08]. Available from: \url{https://www.unicode.org/reports/tr31/tr31-33.html} +\item + The Unicode Standard Version 14.0, + \doccite{Core Specification}. + Unicode Consortium, ISBN 978-1-936213-29-0, copyright \copyright 2021 Unicode, Inc. + Available from: \url{https://www.unicode.org/versions/Unicode14.0.0/UnicodeStandard-14.0.pdf} \item IANA Time Zone Database. Available from: \url{https://www.iana.org/time-zones} diff --git a/source/iostreams.tex b/source/iostreams.tex index 51e6fb05af..7425917019 100644 --- a/source/iostreams.tex +++ b/source/iostreams.tex @@ -4162,6 +4162,15 @@ template Ostream&& operator<<(Ostream&& os, const T& x); + + // \ref{ostream.formatted.print}, print functions + template + void print(ostream& os, @\exposid{format-string}@ fmt, Args&&... args); + template + void println(ostream& os, @\exposid{format-string}@ fmt, Args&&... args); + + void vprint_unicode(ostream& os, string_view fmt, format_args args); + void vprint_nonunicode(ostream& os, string_view fmt, format_args args); } \end{codeblock} @@ -4203,6 +4212,30 @@ } \end{codeblock} +\rSec2[print.syn]{Header \tcode{} synopsis} + +\indexheader{print}% +\begin{codeblock} +namespace std { + // \ref{print.fun}, print functions + template + void print(@\exposid{format-string}@ fmt, Args&&... args); + template + void print(FILE* stream, @\exposid{format-string}@ fmt, Args&&... args); + + template + void println(@\exposid{format-string}@ fmt, Args&&... args); + template + void println(FILE* stream, @\exposid{format-string}@ fmt, Args&&... args); + + void vprint_unicode(string_view fmt, format_args args); + void vprint_unicode(FILE* stream, string_view fmt, format_args args); + + void vprint_nonunicode(string_view fmt, format_args args); + void vprint_nonunicode(FILE* stream, string_view fmt, format_args args); +} +\end{codeblock} + \rSec2[input.streams]{Input streams} \rSec3[input.streams.general]{General} @@ -6767,6 +6800,92 @@ \tcode{out}. \end{itemdescr} +\rSec4[ostream.formatted.print]{Print} + +\indexlibraryglobal{print}% +\begin{itemdecl} +template + void print(ostream& os, @\exposid{format-string}@ fmt, Args&&... args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +If the ordinary literal encoding\iref{lex.charset} is UTF-8, equivalent to: +\begin{codeblock} +vprint_unicode(os, fmt.@\exposid{str}@, make_format_args(std::forward(args)...)); +\end{codeblock} +Otherwise, equivalent to: +\begin{codeblock} +vprint_nonunicode(os, fmt.@\exposid{str}@, make_format_args(std::forward(args)...)); +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{println}% +\begin{itemdecl} +template + void println(ostream& os, @\exposid{format-string}@ fmt, Args&&... args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +print(os, "{}\n", format(fmt, std::forward(args)...)); +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{vprint_unicode}% +\indexlibraryglobal{vprint_nonunicode}% +\begin{itemdecl} +void vprint_unicode(ostream& os, string_view fmt, format_args args); +void vprint_nonunicode(ostream& os, string_view fmt, format_args args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Behaves as a formatted output function\iref{ostream.formatted.reqmts} +of \tcode{os}, except that: +\begin{itemize} +\item +failure to generate output is reported as specified below, and +\item +any exception thrown by the call to \tcode{vformat} is propagated +without regard to the value of \tcode{os.exceptions()} and +without turning on \tcode{ios_base::badbit} in the error state of \tcode{os}. +\end{itemize} +After constructing a \tcode{sentry} object, +the function initializes an automatic variable via +\begin{codeblock} +string out = vformat(os.getloc(), fmt, args); +\end{codeblock} +If the function is \tcode{vprint_unicode} and +\tcode{os} is a stream that refers to a terminal capable of displaying Unicode +which is determined in an implementation-defined manner, +writes \tcode{out} to the terminal using the native Unicode API; +if \tcode{out} contains invalid code units, +\indextext{undefined}% +the behavior is undefined and +implementations are encouraged to diagnose it. +Otherwise (if \tcode{os} is not such a stream or +the function is \tcode{vprint_nonunicode}), +inserts the character sequence +\range{out.begin()}{out.end()} into \tcode{os}. +If writing to the terminal or inserting into \tcode{os} fails, +calls \tcode{os.setstate(ios_base::badbit)} +(which may throw \tcode{ios_base::failure}). + +\pnum +\recommended +For \tcode{vprint_unicode}, +if invoking the native Unicode API requires transcoding, +implementations should substitute invalid code units +with \unicode{fffd}{replacement character} per +The Unicode Standard Version 14.0 - Core Specification, Chapter 3.9. +\end{itemdescr} + \rSec3[ostream.unformatted]{Unformatted output functions} \pnum @@ -7573,6 +7692,169 @@ \end{itemize} \end{itemdescr} +\rSec2[print.fun]{Print functions} + +\indexlibraryglobal{print}% +\begin{itemdecl} +template + void print(@\exposid{format-string}@ fmt, Args&&... args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +print(stdout, fmt, std::forward(args)...); +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{print}% +\begin{itemdecl} +template + void print(FILE* stream, @\exposid{format-string}@ fmt, Args&&... args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +If the ordinary literal encoding\iref{lex.charset} is UTF-8, equivalent to: +\begin{codeblock} +vprint_unicode(stream, fmt.@\exposid{str}@, make_format_args(std::forward(args)...)); +\end{codeblock} +Otherwise, equivalent to: +\begin{codeblock} +vprint_nonunicode(stream, fmt.@\exposid{str}@, make_format_args(std::forward(args)...)); +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{println}% +\begin{itemdecl} +template + void println(@\exposid{format-string}@ fmt, Args&&... args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +println(stdout, fmt, std::forward(args)...); +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{println}% +\begin{itemdecl} +template + void println(FILE* stream, @\exposid{format-string}@ fmt, Args&&... args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +print(stream, "{}\n", format(fmt, std::forward(args)...)); +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{vprint_unicode}% +\begin{itemdecl} +void vprint_unicode(string_view fmt, format_args args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +vprint_unicode(stdout, fmt, args); +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{vprint_unicode}% +\begin{itemdecl} +void vprint_unicode(FILE* stream, string_view fmt, format_args args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{stream} is a valid pointer to an output C stream. + +\pnum +\effects +The function initializes an automatic variable via +\begin{codeblock} +string out = vformat(fmt, args); +\end{codeblock} +If \tcode{stream} refers to a terminal capable of displaying Unicode, +writes \tcode{out} to the terminal using the native Unicode API; +if \tcode{out} contains invalid code units, +\indextext{undefined}% +the behavior is undefined and +implementations are encouraged to diagnose it. +Otherwise writes \tcode{out} to \tcode{stream} unchanged. +\begin{note} +On POSIX and Windows, \tcode{stream} referring to a terminal means that, +respectively, +\tcode{isatty(fileno(\linebreak{}stream))} and +\tcode{GetConsoleMode(_get_osfhandle(_fileno(stream)), ...)} +return nonzero. +\end{note} +\begin{note} +On Windows, the native Unicode API is \tcode{WriteConsoleW}. +\end{note} + +\pnum +\throws +Any exception thrown by the call to \tcode{vformat}\iref{format.err.report}. +\tcode{system_error} if writing to the terminal or \tcode{stream} fails. +May throw \tcode{bad_alloc}. + +\pnum +\recommended +If invoking the native Unicode API requires transcoding, +implementations should substitute invalid code units +with \unicode{fffd}{replacement character} per +The Unicode Standard Version 14.0 - Core Specification, Chapter 3.9. +\end{itemdescr} + +\indexlibraryglobal{vprint_nonunicode}% +\begin{itemdecl} +void vprint_nonunicode(string_view fmt, format_args args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +vprint_nonunicode(stdout, fmt, args); +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{vprint_nonunicode}% +\begin{itemdecl} +void vprint_nonunicode(FILE* stream, string_view fmt, format_args args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{stream} is a valid pointer to an output C stream. + +\pnum +\effects +Writes the result of \tcode{vformat(fmt, args)} to \tcode{stream}. + +\pnum +\throws +Any exception thrown by the call to \tcode{vformat}\iref{format.err.report}. +\tcode{system_error} if writing to \tcode{stream} fails. +May throw \tcode{bad_alloc}. +\end{itemdescr} + \rSec1[string.streams]{String-based streams} \rSec2[sstream.syn]{Header \tcode{} synopsis} diff --git a/source/lib-intro.tex b/source/lib-intro.tex index d42071dc91..39dd9e1a7d 100644 --- a/source/lib-intro.tex +++ b/source/lib-intro.tex @@ -1109,6 +1109,7 @@ \tcode{} \\ \tcode{} \\ \tcode{} \\ +\tcode{} \\ \tcode{} \\ \tcode{} \\ \tcode{} \\ diff --git a/source/support.tex b/source/support.tex index f0a71c7b9e..ddf1fa3114 100644 --- a/source/support.tex +++ b/source/support.tex @@ -672,6 +672,7 @@ #define @\defnlibxname{cpp_lib_out_ptr}@ 202106L // also in \libheader{memory} #define @\defnlibxname{cpp_lib_parallel_algorithm}@ 201603L // also in \libheader{algorithm}, \libheader{numeric} #define @\defnlibxname{cpp_lib_polymorphic_allocator}@ 201902L // also in \libheader{memory_resource} +#define @\defnlibxname{cpp_lib_print}@ 202207L // also in \libheader{print}, \libheader{ostream} #define @\defnlibxname{cpp_lib_quoted_string_io}@ 201304L // also in \libheader{iomanip} #define @\defnlibxname{cpp_lib_ranges}@ 202202L // also in \libheader{algorithm}, \libheader{functional}, \libheader{iterator}, \libheader{memory}, \libheader{ranges} From 3d246121ed6c4b51ceec69139f1808c965b31937 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sat, 30 Jul 2022 05:03:49 -0700 Subject: [PATCH 198/430] P2165R4 Compatibility between tuple and tuple-like objects Editorial changes: * Added cross references in [tuple.rel] pointing at [basic.lookup.argdep]. * Addedd cross reference in [pairs.pair] pointing at [range.utility.helpers] for "different-from". * Reworded section title in [tuple.common.ref]. * Added references in synopsis. --- source/containers.tex | 8 +- source/ranges.tex | 52 ++--- source/support.tex | 2 + source/utilities.tex | 444 ++++++++++++++++++++++++++++++++++++------ 4 files changed, 399 insertions(+), 107 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index 5ff2b37d95..07f1f94ac4 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -9308,14 +9308,14 @@ typename iterator_traits::value_type; // \expos template using @\placeholder{iter-key-type}@ = remove_const_t< - typename iterator_traits::value_type::first_type>; // \expos + tuple_element_t<0, @\exposid{iter-value-type}@>>; // \expos template using @\placeholder{iter-mapped-type}@ = - typename iterator_traits::value_type::second_type; // \expos + tuple_element_t<1, @\exposid{iter-value-type}@>; // \expos template using @\placeholder{iter-to-alloc-type}@ = pair< - add_const_t::value_type::first_type>, - typename iterator_traits::value_type::second_type>; // \expos + add_const_t>>, + tuple_element_t<1, @\exposid{iter-value-type}@>>; // \expos template using @\exposid{range-key-type}@ = remove_const_t::first_type>; // \expos diff --git a/source/ranges.tex b/source/ranges.tex index 9f5aa0fabc..f04619dbf1 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -1677,20 +1677,9 @@ @\libconcept{convertible_to}@ && !@\exposconcept{uses-nonqualification-pointer-conversion}@, decay_t>; - template - concept @\defexposconceptnc{pair-like}@ = // \expos - !is_reference_v && requires(T t) { - typename tuple_size::type; // ensures \tcode{tuple_size} is complete - requires @\libconcept{derived_from}@, integral_constant>; - typename tuple_element_t<0, remove_const_t>; - typename tuple_element_t<1, remove_const_t>; - { std::get<0>(t) } -> @\libconcept{convertible_to}@&>; - { std::get<1>(t) } -> @\libconcept{convertible_to}@&>; - }; - template concept @\defexposconceptnc{pair-like-convertible-from}@ = // \expos - !@\libconcept{range}@ && @\exposconcept{pair-like}@ && + !@\libconcept{range}@ && !is_reference_v && @\exposconcept{pair-like}@ && @\libconcept{constructible_from}@ && @\exposconcept{convertible-to-non-slicing}@> && @\libconcept{convertible_to}@>; @@ -7959,12 +7948,7 @@ namespace std::ranges { template concept @\defexposconcept{has-tuple-element}@ = // \expos - requires(T t) { - typename tuple_size::type; - requires N < tuple_size_v; - typename tuple_element_t; - { std::get(t) } -> @\libconcept{convertible_to}@&>; - }; + @\exposconcept{tuple-like}@ && N < tuple_size_v; template concept @\defexposconcept{returnable-element}@ = // \expos @@ -8594,13 +8578,10 @@ (!(@\libconcept{bidirectional_range}@ && ...) && (@\libconcept{common_range}@ && ...)) || ((@\libconcept{random_access_range}@ && ...) && (@\libconcept{sized_range}@ && ...)); - template - using @\exposid{tuple-or-pair}@ = @\seebelow@; // \expos - template constexpr auto @\exposid{tuple-transform}@(F&& f, Tuple&& tuple) { // \expos return apply([&](Ts&&... elements) { - return @\exposid{tuple-or-pair}@...>( + return tuple...>( invoke(f, std::forward(elements))... ); }, std::forward(tuple)); @@ -8664,17 +8645,6 @@ } \end{codeblock} -\pnum -Given some pack of types \tcode{Ts}, -the alias template \exposid{tuple-or-pair} is defined as follows: -\begin{itemize} -\item -If \tcode{sizeof...(Ts)} is 2, -\tcode{\exposid{tuple-or-pair}} denotes \tcode{pair}. -\item -Otherwise, \tcode{\exposid{tuple-or-pair}} denotes \tcode{tuple}. -\end{itemize} - \pnum Two \tcode{zip_view} objects have the same underlying sequence if and only if the corresponding elements of \exposid{views_} are equal\iref{concepts.equality} @@ -8731,13 +8701,13 @@ requires (@\libconcept{view}@ && ...) && (sizeof...(Views) > 0) template class zip_view::@\exposid{iterator}@ { - @\exposid{tuple-or-pair}@>...> @\exposid{current_}@;@\itcorr[-1]@ // \expos - constexpr explicit @\exposidnc{iterator}@(@\exposid{tuple-or-pair}@>...>); + tuple>...> @\exposid{current_}@;@\itcorr[-1]@ // \expos + constexpr explicit @\exposidnc{iterator}@(tuple>...>); // \expos public: using iterator_category = input_iterator_tag; // not always present using iterator_concept = @\seebelow@; - using value_type = @\exposid{tuple-or-pair}@>...>; + using value_type = tuple>...>; using difference_type = common_type_t>...>; @\exposid{iterator}@() = default; @@ -8813,7 +8783,7 @@ the iterator acquires a singular value. \begin{itemdecl} -constexpr explicit @\exposid{iterator}@(@\exposid{tuple-or-pair}@>...> current); +constexpr explicit @\exposid{iterator}@(tuple>...> current); \end{itemdecl} \begin{itemdescr} @@ -9104,8 +9074,8 @@ requires (@\libconcept{view}@ && ...) && (sizeof...(Views) > 0) template class zip_view::@\exposid{sentinel}@ { - @\exposid{tuple-or-pair}@>...> @\exposid{end_}@;@\itcorr[-1]@ // \expos - constexpr explicit @\exposidnc{sentinel}@(@\exposid{tuple-or-pair}@>...> end); + tuple>...> @\exposid{end_}@;@\itcorr[-1]@ // \expos + constexpr explicit @\exposidnc{sentinel}@(tuple>...> end); // \expos public: @\exposid{sentinel}@() = default; @@ -9134,7 +9104,7 @@ \end{codeblock} \begin{itemdecl} -constexpr explicit @\exposid{sentinel}@(@\exposid{tuple-or-pair}@>...> end); +constexpr explicit @\exposid{sentinel}@(tuple>...> end); \end{itemdecl} \begin{itemdescr} @@ -9879,7 +9849,7 @@ public: using iterator_category = input_iterator_tag; using iterator_concept = @\seebelow@; - using value_type = @\exposid{tuple-or-pair}@<@\exposid{REPEAT}@(range_value_t<@\exposid{Base}@>, N)...>; + using value_type = tuple<@\exposid{REPEAT}@(range_value_t<@\exposid{Base}@>, N)...>; using difference_type = range_difference_t<@\exposid{Base}@>; @\exposid{iterator}@() = default; diff --git a/source/support.tex b/source/support.tex index ddf1fa3114..2c297c2c59 100644 --- a/source/support.tex +++ b/source/support.tex @@ -718,6 +718,8 @@ #define @\defnlibxname{cpp_lib_to_underlying}@ 202102L // also in \libheader{utility} #define @\defnlibxname{cpp_lib_transformation_trait_aliases}@ 201304L // also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_transparent_operators}@ 201510L // also in \libheader{memory}, \libheader{functional} +#define @\defnlibxname{cpp_lib_tuple_like}@ 202207L + // also in \libheader{utility}, \libheader{tuple}, \libheader{map}, \libheader{unordered_map} #define @\defnlibxname{cpp_lib_tuple_element_t}@ 201402L // also in \libheader{tuple} #define @\defnlibxname{cpp_lib_tuples_by_type}@ 201304L // also in \libheader{utility}, \libheader{tuple} #define @\defnlibxname{cpp_lib_type_identity}@ 201806L // also in \libheader{type_traits} diff --git a/source/utilities.tex b/source/utilities.tex index e915e30195..0acc625c6a 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -684,6 +684,8 @@ constexpr explicit(@\seebelow@) pair(pair&& p); template constexpr explicit(@\seebelow@) pair(const pair&& p); + template<@\exposconcept{pair-like}@ P> + constexpr explicit(@\seebelow@) pair(P&& p); template constexpr pair(piecewise_construct_t, tuple first_args, tuple second_args); @@ -700,6 +702,10 @@ constexpr pair& operator=(pair&& p); template constexpr const pair& operator=(pair&& p) const; + template<@\exposconcept{pair-like}@ P> + constexpr pair& operator=(P&& p); + template<@\exposconcept{pair-like}@ P> + constexpr const pair& operator=(P&& p) const; constexpr void swap(pair& p) noexcept(@\seebelow@); constexpr void swap(const pair& p) const noexcept(@\seebelow@); @@ -825,6 +831,7 @@ template constexpr explicit(@\seebelow@) pair(const pair& p); template constexpr explicit(@\seebelow@) pair(pair&& p); template constexpr explicit(@\seebelow@) pair(const pair&& p); +template<@\exposconcept{pair-like}@ P> constexpr explicit(@\seebelow@) pair(P&& p); \end{itemdecl} \begin{itemdescr} @@ -1063,6 +1070,70 @@ \tcode{*this}. \end{itemdescr} +\indexlibrarymember{operator=}{pair}% +\begin{itemdecl} +template<@\exposconcept{pair-like}@ P> constexpr pair& operator=(P&& p); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{\exposconcept{different-from}}\iref{range.utility.helpers} +is \tcode{true}, +\item +\tcode{remove_cvref_t

} is not a specialization of \tcode{ranges::subrange}, +\item +\tcode{is_assignable_v(std::forward

(p)))>} +is \tcode{true}, and +\item +\tcode{is_assignable_v(std::forward

(p)))>} +is \tcode{true}. +\end{itemize} + +\pnum +\effects +Assigns \tcode{get<0>(std::forward

(p))} to \tcode{first} and +\tcode{get<1>(std::forward

(p))} to \tcode{sec\-ond}. + +\pnum +\returns +\tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator=}{pair}% +\begin{itemdecl} +template<@\exposconcept{pair-like}@ P> constexpr const pair& operator=(P&& p) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{\exposconcept{different-from}}\iref{range.utility.helpers} +is \tcode{true}, +\item +\tcode{remove_cvref_t

} is not a specialization of \tcode{ranges::subrange}, +\item +\tcode{is_assignable_v(std::forward

(p)))>} +is \tcode{true}, and +\item +\tcode{is_assignable_v(std::forward

(p)))>} +is \tcode{true}. +\end{itemize} + +\pnum +\effects +Assigns \tcode{get<0>(std::forward

(p))} to \tcode{first} and +\tcode{get<1>(std::forward

(p))} to \tcode{sec\-ond}. + +\pnum +\returns +\tcode{*this}. +\end{itemdescr} + \indexlibrarymember{operator=}{pair}% \begin{itemdecl} template constexpr const pair& operator=(pair&& p) const; @@ -1359,18 +1430,19 @@ template class tuple; - template class TQual, - template class UQual> - requires requires { typename tuple, UQual>...>; } - struct basic_common_reference, tuple, TQual, UQual> { - using type = tuple, UQual>...>; - }; + // \ref{tuple.like}, concept \exposconcept{tuple-like} + template + concept @\exposconcept{tuple-like}@ = @\seebelownc@; // \expos + template + concept @\defexposconcept{pair-like}@ = // \expos + @\exposconcept{tuple-like}@ && tuple_size_v> == 2; - template - requires requires { typename tuple...>; } - struct common_type, tuple> { - using type = tuple...>; - }; + // \ref{tuple.common.ref}, \tcode{common_reference} related specializations + template<@\exposconceptnc{tuple-like}@ TTuple, @\exposconceptnc{tuple-like}@ UTuple, + template class TQual, template class UQual> + struct basic_common_reference; + template<@\exposconceptnc{tuple-like}@ TTuple, @\exposconceptnc{tuple-like}@ UTuple> + struct common_type; // \ref{tuple.creation}, tuple creation functions inline constexpr @\unspec@ ignore; @@ -1384,14 +1456,14 @@ template constexpr tuple tie(TTypes&...) noexcept; - template + template<@\exposconceptnc{tuple-like}@... Tuples> constexpr tuple tuple_cat(Tuples&&...); // \ref{tuple.apply}, calling a function with a tuple of arguments - template + template constexpr decltype(auto) apply(F&& f, Tuple&& t); - template + template constexpr T make_from_tuple(Tuple&& t); // \ref{tuple.helper}, tuple helper classes @@ -1430,9 +1502,13 @@ // \ref{tuple.rel}, relational operators template constexpr bool operator==(const tuple&, const tuple&); + template + constexpr bool operator==(const tuple&, const UTuple&); template - constexpr common_comparison_category_t<@\placeholder{synth-three-way-result}@...> + constexpr common_comparison_category_t<@\placeholdernc{synth-three-way-result}@...> operator<=>(const tuple&, const tuple&); + template + constexpr @\seebelownc@ operator<=>(const tuple&, const UTuple&); // \ref{tuple.traits}, allocator-related traits template @@ -1450,6 +1526,21 @@ } \end{codeblock} +\rSec2[tuple.like]{Concept \ecname{tuple-like}} + +\begin{itemdecl} +template + concept @\defexposconcept{tuple-like}@ = @\seebelownc@; // \expos +\end{itemdecl} + +\begin{itemdescr} +\pnum +A type \tcode{T} models and satisfies +the exposition-only concept \exposconcept{tuple-like} +if \tcode{std::remove_cvref_t} is a specialization of +\tcode{array}, \tcode{pair}, \tcode{tuple}, or \tcode{ranges::subrange}. +\end{itemdescr} + \rSec2[tuple.tuple]{Class template \tcode{tuple}} \indexlibraryglobal{tuple}% @@ -1485,6 +1576,9 @@ template constexpr explicit(@\seebelow@) tuple(const pair&&); // only if \tcode{sizeof...(Types) == 2} + template<@\exposconcept{tuple-like}@ UTuple> + constexpr explicit(@\seebelow@) tuple(UTuple&&); + // allocator-extended constructors template constexpr explicit(@\seebelow@) @@ -1524,6 +1618,9 @@ constexpr explicit(@\seebelow@) tuple(allocator_arg_t, const Alloc& a, const pair&&); + template + constexpr explicit(@\seebelow@) tuple(allocator_arg_t, const Alloc& a, UTuple&&); + // \ref{tuple.assign}, \tcode{tuple} assignment constexpr tuple& operator=(const tuple&); constexpr const tuple& operator=(const tuple&) const; @@ -1549,6 +1646,11 @@ template constexpr const tuple& operator=(pair&&) const; // only if \tcode{sizeof...(Types) == 2} + template<@\exposconceptnc{tuple-like}@ UTuple> + constexpr tuple& operator=(UTuple&&); + template<@\exposconceptnc{tuple-like}@ UTuple> + constexpr const tuple& operator=(UTuple&&) const; + // \ref{tuple.swap}, \tcode{tuple} swap constexpr void swap(tuple&) noexcept(@\seebelow@); constexpr void swap(const tuple&) const noexcept(@\seebelow@); @@ -1819,6 +1921,56 @@ is \tcode{true}. \end{itemdescr} +\indexlibraryctor{tuple}% +\begin{itemdecl} +template<@\exposconcept{tuple-like}@ UTuple> + constexpr explicit(@\seebelow@) tuple(UTuple&& u); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{I} be the pack \tcode{0, 1, \ldots, (sizeof...(Types) - 1)}. + +\pnum +\constraints +\begin{itemize} +\item +\tcode{\exposconcept{different-from}}\iref{range.utility.helpers} +is \tcode{true}, + +\item +\tcode{remove_cvref_t} +is not a specialization of \tcode{ranges::subrange}, + +\item +\tcode{sizeof...(Types)} +equals \tcode{tuple_size_v>}, + +\item +\tcode{(is_constructible_v(std::forward(u)))> \&\& ...)} +is\linebreak{} % Overfull +\tcode{true}, and + +\item +either \tcode{sizeof...(Types)} is not \tcode{1}, or +(when \tcode{Types...} expands to \tcode{T}) +\tcode{is_convertible_v} and +\tcode{is_constructible_v} are both \tcode{false}. +\end{itemize} + +\pnum +\effects +For all $i$, initializes the $i^\text{th}$ element of \tcode{*this} with +\tcode{get<$i$>(std::forward(u))}. + +\pnum +\remarks +The expression inside \tcode{explicit} is equivalent to: +\begin{codeblock} +!(is_convertible_v(std::forward(u))), Types> && ...) +\end{codeblock} +\end{itemdescr} + \indexlibraryctor{tuple}% \begin{itemdecl} template @@ -1858,6 +2010,9 @@ template constexpr explicit(@\seebelow@) tuple(allocator_arg_t, const Alloc& a, const pair&&); +template + constexpr explicit(@\seebelow@) + tuple(allocator_arg_t, const Alloc& a, UTuple&&); \end{itemdecl} \begin{itemdescr} @@ -2172,6 +2327,80 @@ \tcode{*this}. \end{itemdescr} +\indexlibrarymember{operator=}{tuple}% +\begin{itemdecl} +template<@\exposconcept{tuple-like}@ UTuple> + constexpr tuple& operator=(UTuple&& u); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{\exposconcept{different-from}}\iref{range.utility.helpers} +is \tcode{true}, + +\item +\tcode{remove_cvref_t} +is not a specialization of \tcode{ranges::subrange}, + +\item +\tcode{sizeof...(Types)} +equals \tcode{tuple_size_v>}, and, + +\item +\tcode{is_assignable_v<$\tcode{T}_i$\&, decltype(get<$i$>(std::forward(u)))>} +is \tcode{true} for all $i$. +\end{itemize} + +\pnum +\effects +For all $i$, assigns \tcode{get<$i$>(std::forward(u))} +to \tcode{get<$i$>(*this)}. + +\pnum +\returns +\tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator=}{tuple}% +\begin{itemdecl} +template<@\exposconcept{tuple-like}@ UTuple> + constexpr const tuple& operator=(UTuple&& u) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{\exposconcept{different-from}}\iref{range.utility.helpers} +is \tcode{true}, + +\item +\tcode{remove_cvref_t} +is not a specialization of \tcode{ranges::subrange}, + +\item +\tcode{sizeof...(Types)} +equals \tcode{tuple_size_v>}, and, + +\item +\tcode{is_assignable_v(std::forward(u)))>} +is \tcode{true} for all $i$. +\end{itemize} + +\pnum +\effects +For all $i$, assigns +\tcode{get<$i$>(std::forward(u))} to \tcode{get<$i$>(*this)}. + +\pnum +\returns +\tcode{*this}. +\end{itemdescr} + \rSec3[tuple.swap]{\tcode{swap}} \indexlibrarymember{swap}{tuple}% @@ -2292,62 +2521,54 @@ \indexlibraryglobal{tuple_cat} \begin{itemdecl} -template +template<@\exposconcept{tuple-like}@... Tuples> constexpr tuple tuple_cat(Tuples&&... tpls); \end{itemdecl} -\begin{itemdescr} % NOCHECK: order -\pnum -In the following paragraphs, let $\tcode{T}_i$ be the $i^\text{th}$ type in \tcode{Tuples}, -$\tcode{U}_i$ be \tcode{remove_reference_t}, and $\tcode{tp}_i$ be the $i^\text{th}$ -parameter in the function parameter pack \tcode{tpls}, where all indexing is -zero-based. - +\begin{itemdescr} \pnum -\expects -For all $i$, $\tcode{U}_i$ is the type -$\cv_i$ \tcode{tuple<$\tcode{Args}_i$...>}, where $\cv_i$ is the (possibly empty) $i^\text{th}$ -\grammarterm{cv-qualifier-seq} and $\tcode{Args}_i$ is the template parameter pack representing the element -types in $\tcode{U}_i$. Let $\tcode{A}_{ik}$ be the ${k}^\text{th}$ type in $\tcode{Args}_i$. For all -$\tcode{A}_{ik}$ the following requirements are met: +Let $n$ be \tcode{sizeof...(Tuples)}. +For every integer $0 \leq i < n$: \begin{itemize} -\item If $\tcode{T}_i$ is deduced as an lvalue reference type, then - \tcode{is_constructible_v<$\tcode{A}_{ik}$, $\cv{}_i\;\tcode{A}_{ik}$\&> == true}, otherwise -\item \tcode{is_constructible_v<$\tcode{A}_{ik}$, $\cv{}_i\;\tcode{A}_{ik}$\&\&> == true}. +\item +Let $\tcode{T}_i$ be the $i^\text{th}$ type in \tcode{Tuples}. +\item +Let $\tcode{U}_i$ be \tcode{remove_cvref_t<$\tcode{T}_i$>}. +\item +Let $\tcode{tp}_i$ be the $i^\text{th}$ element +in the function parameter pack \tcode{tpls}. +\item +Let $S_i$ be \tcode{tuple_size_v<$\tcode{U}_i$>}. +\item +Let $E_i^k$ be \tcode{tuple_element_t<$k$, $\tcode{U}_i$>}. +\item +Let $e_i^k$ be \tcode{get<$k$>(std::forward<$\tcode{T}_i$>($\tcode{tp}_i$))}. +\item +Let $Elems_i$ be a pack of the types $E_i^0, \dotsc, E_i^{S_{i-1}}$. +\item +Let $elems_i$ be a pack of the expressions $e_i^0, \dotsc, e_i^{S_{i-1}}$. \end{itemize} +The types in \tcode{CTypes} are equal to the ordered sequence of +the expanded packs of types +\tcode{$Elems_0$...}, \tcode{$Elems_1$...}, \ldots, \tcode{$Elems_{n-1}$...}. +Let \tcode{celems} be the ordered sequence of +the expanded packs of expressions +\tcode{$elems_0$...}, \ldots, \tcode{$elems_{n-1}$...}. \pnum -\remarks -The types in \tcode{CTypes} are equal to the ordered -sequence of the extended types -\tcode{$\tcode{Args}_0$..., $\tcode{Args}_1$..., $\dotsc$, $\tcode{Args}_{n-1}$...}, -where $n$ is -equal to \tcode{sizeof...(Tuples)}. Let \tcode{$\tcode{e}_i$...} be the $i^\text{th}$ -ordered sequence of tuple elements of the resulting \tcode{tuple} object -corresponding to the type sequence $\tcode{Args}_i$. +\mandates +\tcode{(is_constructible_v \&\& ...)} is \tcode{true}. \pnum \returns -A \tcode{tuple} object constructed by initializing the ${k_i}^\text{th}$ -type element $\tcode{e}_{ik}$ in \tcode{$\tcode{e}_i$...} with -\begin{codeblock} -get<@$k_i$@>(std::forward<@$\tcode{T}_i$@>(@$\tcode{tp}_i$@)) -\end{codeblock} -for each valid $k_i$ and each group $\tcode{e}_i$ in order. - -\pnum -\begin{note} -An implementation can support additional types in the template parameter -pack \tcode{Tuples} that support the \tcode{tuple}-like protocol, such as -\tcode{pair} and \tcode{array}. -\end{note} +\tcode{tuple(celems...)}. \end{itemdescr} \rSec2[tuple.apply]{Calling a function with a \tcode{tuple} of arguments} \indexlibraryglobal{apply}% \begin{itemdecl} -template +template constexpr decltype(auto) apply(F&& f, Tuple&& t); \end{itemdecl} @@ -2357,7 +2578,7 @@ Given the exposition-only function: \begin{codeblock} namespace std { - template + template constexpr decltype(auto) @\placeholdernc{apply-impl}@(F&& f, Tuple&& t, index_sequence) { // \expos return @\placeholdernc{INVOKE}@(std::forward(f), get(std::forward(t))...); // see \ref{func.require} @@ -2373,7 +2594,7 @@ \indexlibraryglobal{make_from_tuple}% \begin{itemdecl} -template +template constexpr T make_from_tuple(Tuple&& t); \end{itemdecl} @@ -2390,7 +2611,7 @@ Given the exposition-only function: \begin{codeblock} namespace std { - template + template requires is_constructible_v(declval()))...> constexpr T @\placeholdernc{make-from-tuple-impl}@(Tuple&& t, index_sequence) { // \expos return T(get(std::forward(t))...); @@ -2608,9 +2829,14 @@ \begin{itemdecl} template constexpr bool operator==(const tuple& t, const tuple& u); +template + constexpr bool operator==(const tuple& t, const UTuple& u); \end{itemdecl} \begin{itemdescr} +\pnum +For the first overload let \tcode{UTuple} be \tcode{tuple}. + \pnum \mandates For all \tcode{i}, @@ -2618,20 +2844,27 @@ \tcode{get(t) == get(u)} is a valid expression returning a type that is convertible to \tcode{bool}. \tcode{sizeof...(TTypes)} equals -\tcode{sizeof...(UTypes)}. +\tcode{tuple_size_v}. \pnum \returns \tcode{true} if \tcode{get(t) == get(u)} for all \tcode{i}, otherwise \tcode{false}. -For any two zero-length tuples \tcode{e} and \tcode{f}, \tcode{e == f} returns \tcode{true}. +\begin{note} +If \tcode{sizeof...(TTypes)} equals zero, returns \tcode{true}. +\end{note} \pnum \remarks +\begin{itemize} +\item The elementary comparisons are performed in order from the zeroth index upwards. No comparisons or element accesses are performed after the first equality comparison that evaluates to \tcode{false}. +\item +The second overload is to be found via argument-dependent lookup\iref{basic.lookup.argdep} only. +\end{itemize} \end{itemdescr} \indexlibrarymember{operator<=>}{tuple}% @@ -2639,21 +2872,34 @@ template constexpr common_comparison_category_t<@\placeholder{synth-three-way-result}@...> operator<=>(const tuple& t, const tuple& u); +template + constexpr common_comparison_category_t<@\placeholder{synth-three-way-result}@...> + operator<=>(const tuple& t, const UTuple& u); \end{itemdecl} \begin{itemdescr} +\pnum +For the second overload, \tcode{Elems} denotes the pack of types +\tcode{tuple_element_t<0, UTuple>}, +\tcode{tuple_element_t<1, UTuple>}, \ldots, +\tcode{tuple_element_t - 1, UTuple>}. + \pnum \effects Performs a lexicographical comparison between \tcode{t} and \tcode{u}. -For any two zero-length tuples \tcode{t} and \tcode{u}, -\tcode{t <=> u} returns \tcode{strong_ordering::equal}. +If \tcode{sizeof...(TTypes)} equals zero, +returns \tcode{strong_ordering::equal}. Otherwise, equivalent to: \begin{codeblock} if (auto c = @\placeholder{synth-three-way}@(get<0>(t), get<0>(u)); c != 0) return c; return @$\tcode{t}_\mathrm{tail}$@ <=> @$\tcode{u}_\mathrm{tail}$@; \end{codeblock} -where $\tcode{r}_\mathrm{tail}$ for some tuple \tcode{r} +where $\tcode{r}_\mathrm{tail}$ for some \tcode{r} is a tuple containing all but the first element of \tcode{r}. + +\pnum +\remarks +The second overload is to be found via argument-dependent lookup\iref{basic.lookup.argdep} only. \end{itemdescr} \pnum @@ -2666,6 +2912,80 @@ result of the comparison. \end{note} +\rSec2[tuple.common.ref]{\tcode{common_reference} related specializations} + +\pnum +In the descriptions that follow: +\begin{itemize} +\item +Let \tcode{TTypes} be a pack formed by +the sequence of \tcode{tuple_element_t<$i$, TTuple>} +for every integer $0 \leq i < \tcode{tuple_size_v}$. + +\item +Let \tcode{UTypes} be a pack formed by +the sequence of \tcode{tuple_element_t<$i$, UTuple>} +for every integer $0 \leq i < \tcode{tuple_size_v}$. +\end{itemize} + +\indexlibrarymember{basic_common_reference}{tuple}% +\begin{itemdecl} +template<@\exposconcept{tuple-like}@ TTuple, @\exposconcept{tuple-like}@ UTuple, + template class TQual, template class UQual> +struct basic_common_reference { + using type = @\seebelow@; +}; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{TTuple} is a specialization of \tcode{tuple} or +\tcode{UTuple} is a specialization of \tcode{tuple}. +\item +\tcode{is_same_v>} is \tcode{true}. +\item +\tcode{is_same_v>} is \tcode{true}. +\item +\tcode{tuple_size_v} equals \tcode{tuple_size_v}. +\item +\tcode{tuple, UQual>...>} +denotes a type. +\end{itemize} +The member \grammarterm{typedef-name} \tcode{type} denotes the type +\tcode{tuple, \linebreak{}UQual>...>}. +\end{itemdescr} + +\indexlibrarymember{common_type}{tuple}% +\begin{itemdecl} +template<@\exposconcept{tuple-like}@ TTuple, @\exposconcept{tuple-like}@ UTuple> +struct common_type { + using type = @\seebelow@; +}; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{TTuple} is a specialization of \tcode{tuple} or +\tcode{UTuple} is a specialization of \tcode{tuple}. +\item +\tcode{is_same_v>} is \tcode{true}. +\item +\tcode{is_same_v>} is \tcode{true}. +\item +\tcode{tuple_size_v} equals \tcode{tuple_size_v}. +\item +\tcode{tuple...>} denotes a type. +\end{itemize} +The member \grammarterm{typedef-name} \tcode{type} denotes the type +\tcode{tuple...>}. +\end{itemdescr} + \rSec2[tuple.traits]{Tuple traits} \indexlibraryglobal{uses_allocator}% From 32535186bc66b3485194b41d5b2107e15c6bd34a Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Mon, 1 Aug 2022 16:36:25 +0200 Subject: [PATCH 199/430] P2278R4 cbegin should always return a constant iterator --- source/containers.tex | 6 + source/iterators.tex | 565 ++++++++++++++++++++++++++++++++++++++++++ source/ranges.tex | 244 +++++++++++++++--- source/support.tex | 1 + 4 files changed, 785 insertions(+), 31 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index 07f1f94ac4..5b125d5e12 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -17373,7 +17373,9 @@ using reference = element_type&; using const_reference = const element_type&; using iterator = @\impdefx{type of \tcode{span::iterator}}@; // see \ref{span.iterators} + using const_iterator = std::const_iterator; using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::const_iterator; static constexpr size_type extent = Extent; // \ref{span.cons}, constructors, copy, and assignment @@ -17425,8 +17427,12 @@ // \ref{span.iterators}, iterator support constexpr iterator begin() const noexcept; constexpr iterator end() const noexcept; + constexpr const_iterator cbegin() const noexcept { return begin(); } + constexpr const_iterator cend() const noexcept { return end(); } constexpr reverse_iterator rbegin() const noexcept; constexpr reverse_iterator rend() const noexcept; + constexpr const_reverse_iterator crbegin() const noexcept { return rbegin(); } + constexpr const_reverse_iterator crend() const noexcept { return rend(); } private: pointer data_; // \expos diff --git a/source/iterators.tex b/source/iterators.tex index e8887b29f7..b08afe69ad 100644 --- a/source/iterators.tex +++ b/source/iterators.tex @@ -334,6 +334,40 @@ constexpr insert_iterator inserter(Container& x, ranges::iterator_t i); // freestanding + // \ref{const.iterators}, constant iterators and sentinels + template<@\libconcept{indirectly_readable}@ I> + using iter_const_reference_t = @\seebelow@; + template + concept @\exposconcept{constant-iterator}@ = @\seebelow@; // \expos + + template + class basic_const_iterator; + + template U> + struct common_type, U> { + using type = basic_const_iterator>; + }; + template U> + struct common_type> { + using type = basic_const_iterator>; + }; + template U> + struct common_type, basic_const_iterator> { + using type = basic_const_iterator>; + }; + + template<@\libconcept{input_iterator}@ I> + using const_iterator = @\seebelow@; + + template + using const_sentinel = @\seebelow@; + + template<@\libconcept{input_iterator}@ I> + constexpr const_iterator make_const_iterator(I it) { return it; } + + template + constexpr const_sentinel make_const_sentinel(S s) { return s; } + // \ref{move.iterators}, move iterators and sentinels template class move_iterator; // freestanding @@ -4121,6 +4155,537 @@ \tcode{insert_iterator(x, i)}. \end{itemdescr} +\rSec2[const.iterators]{Constant iterators and sentinels} + +\pnum +Class template \tcode{basic_const_iterator} is an iterator adaptor +with the same behavior as the underlying iterator +except that its indirection operator implicitly converts +the value returned by the underlying iterator's indirection operator +to a type such that the adapted iterator is +a constant iterator\iref{iterator.requirements}. +Some generic algorithms can be called with constant iterators to avoid mutation. + +\pnum +Specializations of \tcode{basic_const_iterator} are constant iterators. + +\begin{itemdecl} +template<@\libconcept{indirectly_readable}@ It> + using iter_const_reference_t = common_reference_t&&, + iter_reference_t>; + +template + concept @\defexposconcept{constant-iterator}@ = @\libconcept{input_iterator}@ && + @\libconcept{same_as}@, iter_reference_t>; + +template<@\libconcept{input_iterator}@ I> + using @\libglobal{const_iterator}@ = @\seebelow@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +If \tcode{I} models \exposconcept{constant-iterator}, \tcode{I}. +Otherwise, \tcode{basic_const_iterator}. +\end{itemdescr} + +\begin{itemdecl} +template + using @\libglobal{const_sentinel}@ = @\seebelow@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +If \tcode{S} models \tcode{input_iterator}, \tcode{const_iterator}. +Otherwise, \tcode{S}. +\end{itemdescr} + +\begin{codeblock} +template + concept @\exposconcept{not-a-const-iterator}@ = @\seebelow@; + +namespace std { + template<@\libconcept{input_iterator}@ Iterator> + class @\libglobal{basic_const_iterator}@ { + Iterator @\exposid{current_}@ = Iterator(); + using @\exposid{reference}@ = iter_const_reference_t; // \expos + + public: + using iterator_concept = @\seebelow@; + using iterator_category = @\seebelow@; // not always present + using value_type = iter_value_t; + using difference_type = iter_difference_t; + + basic_const_iterator() requires @\libconcept{default_initializable}@ = default; + constexpr basic_const_iterator(Iterator current); + template<@\libconcept{convertible_to}@ U> + constexpr basic_const_iterator(basic_const_iterator current); + template<@\exposconcept{different-from}@ T> + requires @\libconcept{convertible_to}@ + constexpr basic_const_iterator(T&& current); + + constexpr const Iterator& base() const & noexcept; + constexpr Iterator base() &&; + + constexpr @\exposid{reference}@ operator*() const; + constexpr const value_type* operator->() const + requires is_lvalue_reference_v> && + @\libconcept{same_as}@>, value_type>; + + constexpr basic_const_iterator& operator++(); + constexpr void operator++(int); + constexpr basic_const_iterator operator++(int) requires @\libconcept{forward_iterator}@; + + constexpr basic_const_iterator& operator--() requires @\libconcept{bidirectional_iterator}@; + constexpr basic_const_iterator operator--(int) requires @\libconcept{bidirectional_iterator}@; + + constexpr basic_const_iterator& operator+=(difference_type n) + requires @\libconcept{random_access_iterator}@; + constexpr basic_const_iterator& operator-=(difference_type n) + requires @\libconcept{random_access_iterator}@; + + constexpr @\exposid{reference}@ operator[](difference_type n) const + requires @\libconcept{random_access_iterator}@; + + template<@\libconcept{sentinel_for}@ S> + friend constexpr bool operator==(const basic_const_iterator& x, const S& s); + + friend constexpr bool operator<(const basic_const_iterator& x, const basic_const_iterator& y) + requires @\libconcept{random_access_iterator}@; + friend constexpr bool operator>(const basic_const_iterator& x, const basic_const_iterator& y) + requires @\libconcept{random_access_iterator}@; + friend constexpr bool operator<=(const basic_const_iterator& x, + const basic_const_iterator& y) + requires @\libconcept{random_access_iterator}@; + friend constexpr bool operator>=(const basic_const_iterator& x, + const basic_const_iterator& y) + requires @\libconcept{random_access_iterator}@; + friend constexpr auto operator<=>(const basic_const_iterator& x, + const basic_const_iterator& y) + requires @\libconcept{random_access_iterator}@ && @\libconcept{three_way_comparable}@; + + template<@\exposconcept{different-from}@ I> + friend constexpr bool operator<(const basic_const_iterator& x, const I& y) + requires @\libconcept{random_access_iterator}@ && @\libconcept{totally_ordered_with}@; + template<@\exposconcept{different-from}@ I> + friend constexpr bool operator>(const basic_const_iterator& x, const I& y) + requires @\libconcept{random_access_iterator}@ && @\libconcept{totally_ordered_with}@; + template<@\exposconcept{different-from}@ I> + friend constexpr bool operator<=(const basic_const_iterator& x, const I& y) + requires @\libconcept{random_access_iterator}@ && @\libconcept{totally_ordered_with}@; + template<@\exposconcept{different-from}@ I> + friend constexpr bool operator>=(const basic_const_iterator& x, const I& y) + requires @\libconcept{random_access_iterator}@ && @\libconcept{totally_ordered_with}@; + template<@\exposconcept{not-a-const-iterator}@ I> + friend constexpr bool operator<(const I& x, const basic_const_iterator& y) + requires @\libconcept{random_access_iterator}@ && @\libconcept{totally_ordered_with}@; + template<@\exposconcept{not-a-const-iterator}@ I> + friend constexpr bool operator>(const I& x, const basic_const_iterator& y) + requires @\libconcept{random_access_iterator}@ && @\libconcept{totally_ordered_with}@; + template<@\exposconcept{not-a-const-iterator}@ I> + friend constexpr bool operator<=(const I& x, const basic_const_iterator& y) + requires @\libconcept{random_access_iterator}@ && @\libconcept{totally_ordered_with}@; + template<@\exposconcept{not-a-const-iterator}@ I> + friend constexpr bool operator>=(const I& x, const basic_const_iterator& y) + requires @\libconcept{random_access_iterator}@ && @\libconcept{totally_ordered_with}@; + template<@\exposconcept{different-from}@ I> + friend constexpr auto operator<=>(const basic_const_iterator& x, const I& y) + requires @\libconcept{random_access_iterator}@ && @\libconcept{totally_ordered_with}@ && + @\libconcept{three_way_comparable_with}@; + + friend constexpr basic_const_iterator operator+(const basic_const_iterator& i, + difference_type n) + requires @\libconcept{random_access_iterator}@; + friend constexpr basic_const_iterator operator+(difference_type n, + const basic_const_iterator& i) + requires @\libconcept{random_access_iterator}@; + friend constexpr basic_const_iterator operator-(const basic_const_iterator& i, + difference_type n) + requires @\libconcept{random_access_iterator}@; + template<@\libconcept{sized_sentinel_for}@ S> + friend constexpr difference_type operator-(const basic_const_iterator& x, const S& y); + template<@\libconcept{sized_sentinel_for}@ S> + requires @\exposconcept{different-from}@ + friend constexpr difference_type operator-(const S& x, const basic_const_iterator& y); + }; +} +\end{codeblock} + +\pnum +Given some type \tcode{I}, +the concept \defexposconcept{not-a-const-iterator} is defined as \tcode{false} +if \tcode{I} is a specialization of \tcode{basic_const_iterator} and +\tcode{true} otherwise. + +\pnum +\tcode{basic_const_iterator::iterator_concept} is defined as follows: +\begin{itemize} +\item +If \tcode{Iterator} models \libconcept{contiguous_iterator}, +then \tcode{iterator_concept} denotes \tcode{contiguous_iterator_tag}. +\item +Otherwise, if \tcode{Iterator} models \tcode{random_access_iterator}, +then \tcode{iterator_concept} denotes \tcode{random_access_iterator_tag}. +\item +Otherwise, if \tcode{Iterator} models \tcode{bidirectional_iterator}, +then \tcode{iterator_concept} denotes \tcode{bidirec\-tional_iterator_tag}. +\item +Otherwise, if \tcode{Iterator} models \tcode{forward_iterator}, +then \tcode{iterator_concept} denotes \tcode{forward_itera\-tor_tag}. +\item +Otherwise, \tcode{iterator_concept} denotes \tcode{input_iterator_tag}. +\end{itemize} + +\pnum +The member \grammarterm{typedef-name} \tcode{iterator_category} is defined +if and only if \tcode{Iterator} models \tcode{forward_iterator}. +In that case, +\tcode{basic_const_iterator::iterator_category} denotes +the type \tcode{iterator_traits<\brk{}Iterator>::iterator_category}. + +\indexlibraryctor{basic_const_iterator}% +\begin{itemdecl} +constexpr basic_const_iterator(Iterator current); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \exposid{current_} with \tcode{std::move(current)}. +\end{itemdescr} + +\indexlibraryctor{basic_const_iterator}% +\begin{itemdecl} +template<@\libconcept{convertible_to}@ U> + constexpr basic_const_iterator(basic_const_iterator current); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \exposid{current_} +with \tcode{std::move(current.\exposid{current_})}. +\end{itemdescr} + +\indexlibraryctor{basic_const_iterator}% +\begin{itemdecl} +template<@\exposconcept{different-from}@ T> + requires @\libconcept{convertible_to}@ + constexpr basic_const_iterator(T&& current); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \exposid{current_} with \tcode{std::forward(current)}. +\end{itemdescr} + +\indexlibrarymember{base}{basic_const_iterator}% +\begin{itemdecl} +constexpr const Iterator& base() const & noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return \exposid{current_};} +\end{itemdescr} + +\indexlibrarymember{base}{basic_const_iterator}% +\begin{itemdecl} +constexpr Iterator base() &&; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return std::move(\exposid{current_});} +\end{itemdescr} + +\indexlibrarymember{operator*}{basic_const_iterator}% +\begin{itemdecl} +constexpr @\exposid{reference}@ operator*() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return static_cast<\exposid{reference}>(*\exposid{current_});} +\end{itemdescr} + +\indexlibrarymember{operator->}{basic_const_iterator}% +\begin{itemdecl} +constexpr const value_type* operator->() const + requires is_lvalue_reference_v> && + @\libconcept{same_as}@>, value_type>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +If \tcode{Iterator} models \tcode{contiguous_iterator}, +\tcode{to_address(\exposid{current_})}; +otherwise, \tcode{address\-of(*\exposid{current_})}. +\end{itemdescr} + +\indexlibrarymember{operator++}{basic_const_iterator}% +\begin{itemdecl} +constexpr basic_const_iterator& operator++(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +++@\exposid{current_}@; +return *this; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator++}{basic_const_iterator}% +\begin{itemdecl} +constexpr void operator++(int); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{++\exposid{current_};} +\end{itemdescr} + +\indexlibrarymember{operator++}{basic_const_iterator}% +\begin{itemdecl} +constexpr basic_const_iterator operator++(int) requires @\libconcept{forward_iterator}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto tmp = *this; +++*this; +return tmp; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator--}{basic_const_iterator}% +\begin{itemdecl} +constexpr basic_const_iterator& operator--() requires @\libconcept{bidirectional_iterator}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +--@\exposid{current_}@; +return *this; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator--}{basic_const_iterator}% +\begin{itemdecl} +constexpr basic_const_iterator operator--(int) requires @\libconcept{bidirectional_iterator}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto tmp = *this; +--*this; +return tmp; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator+=}{basic_const_iterator}% +\indexlibrarymember{operator-=}{basic_const_iterator}% +\begin{itemdecl} +constexpr basic_const_iterator& operator+=(difference_type n) + requires @\libconcept{random_access_iterator}@; +constexpr basic_const_iterator& operator-=(difference_type n) + requires @\libconcept{random_access_iterator}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{\placeholder{op}} be the operator. + +\pnum +\effects +Equivalent to: +\begin{codeblock} +@\exposid{current_}@ @\placeholder{op}@ n; +return *this; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator[]}{basic_const_iterator}% +\begin{itemdecl} +constexpr @\exposid{reference}@ operator[](difference_type n) const requires @\libconcept{random_access_iterator}@ +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return static_cast<\exposid{reference}>(\exposid{current_}[n]);} +\end{itemdescr} + +\indexlibrarymember{operator==}{basic_const_iterator}% +\begin{itemdecl} +template<@\libconcept{sentinel_for}@ S> + friend constexpr bool operator==(const basic_const_iterator& x, const S& s); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return x.\exposid{current_} == s;} +\end{itemdescr} + +\indexlibrarymember{operator<}{basic_const_iterator}% +\indexlibrarymember{operator>}{basic_const_iterator}% +\indexlibrarymember{operator<=}{basic_const_iterator}% +\indexlibrarymember{operator>=}{basic_const_iterator}% +\indexlibrarymember{operator<=>}{basic_const_iterator}% +\begin{itemdecl} +friend constexpr bool operator<(const basic_const_iterator& x, const basic_const_iterator& y) + requires @\libconcept{random_access_iterator}@; +friend constexpr bool operator>(const basic_const_iterator& x, const basic_const_iterator& y) + requires @\libconcept{random_access_iterator}@; +friend constexpr bool operator<=(const basic_const_iterator& x, const basic_const_iterator& y) + requires @\libconcept{random_access_iterator}@; +friend constexpr bool operator>=(const basic_const_iterator& x, const basic_const_iterator& y) + requires @\libconcept{random_access_iterator}@; +friend constexpr auto operator<=>(const basic_const_iterator& x, const basic_const_iterator& y) + requires @\libconcept{random_access_iterator}@ && @\libconcept{three_way_comparable}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{\placeholder{op}} be the operator. + +\pnum +\effects +Equivalent to: +\tcode{return x.\exposid{current_} \placeholder{op} \exposid{y.current_};} +\end{itemdescr} + +\indexlibrarymember{operator<}{basic_const_iterator}% +\indexlibrarymember{operator>}{basic_const_iterator}% +\indexlibrarymember{operator<=}{basic_const_iterator}% +\indexlibrarymember{operator>=}{basic_const_iterator}% +\indexlibrarymember{operator<=>}{basic_const_iterator}% +\begin{itemdecl} +template<@\exposconcept{different-from}@ I> + friend constexpr bool operator<(const basic_const_iterator& x, const I& y) + requires @\libconcept{random_access_iterator}@ && @\libconcept{totally_ordered_with}@; +template<@\exposconcept{different-from}@ I> + friend constexpr bool operator>(const basic_const_iterator& x, const I& y) + requires @\libconcept{random_access_iterator}@ && @\libconcept{totally_ordered_with}@; +template<@\exposconcept{different-from}@ I> + friend constexpr bool operator<=(const basic_const_iterator& x, const I& y) + requires @\libconcept{random_access_iterator}@ && @\libconcept{totally_ordered_with}@; +template<@\exposconcept{different-from}@ I> + friend constexpr bool operator>=(const basic_const_iterator& x, const I& y) + requires @\libconcept{random_access_iterator}@ && @\libconcept{totally_ordered_with}@; +template<@\exposconcept{different-from}@ I> + friend constexpr auto operator<=>(const basic_const_iterator& x, const I& y) + requires @\libconcept{random_access_iterator}@ && @\libconcept{totally_ordered_with}@ && + @\libconcept{three_way_comparable_with}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{\placeholder{op}} be the operator. + +\pnum +\returns +Equivalent to: \tcode{return x.\exposid{current_} \placeholder{op} y;} +\end{itemdescr} + +\indexlibrarymember{operator<}{basic_const_iterator}% +\indexlibrarymember{operator>}{basic_const_iterator}% +\indexlibrarymember{operator<=}{basic_const_iterator}% +\indexlibrarymember{operator>=}{basic_const_iterator}% +\begin{itemdecl} +template<@\exposconcept{not-a-const-iterator}@ I> + friend constexpr bool operator<(const I& x, const basic_const_iterator& y) + requires @\libconcept{random_access_iterator}@ && @\libconcept{totally_ordered_with}@; +template<@\exposconcept{not-a-const-iterator}@ I> + friend constexpr bool operator>(const I& x, const basic_const_iterator& y) + requires @\libconcept{random_access_iterator}@ && @\libconcept{totally_ordered_with}@; +template<@\exposconcept{not-a-const-iterator}@ I> + friend constexpr bool operator<=(const I& x, const basic_const_iterator& y) + requires @\libconcept{random_access_iterator}@ && @\libconcept{totally_ordered_with}@; +template<@\exposconcept{not-a-const-iterator}@ I> + friend constexpr bool operator>=(const I& x, const basic_const_iterator& y) + requires @\libconcept{random_access_iterator}@ && @\libconcept{totally_ordered_with}@; +\end{itemdecl} + +\begin{itemdescr} +Let \tcode{\placeholder{op}} be the operator. + +\pnum +\returns +Equivalent to: \tcode{return x \placeholder{op} y.\exposid{current_};} +\end{itemdescr} + +\indexlibrarymember{operator+}{basic_const_iterator}% +\begin{itemdecl} +friend constexpr basic_const_iterator operator+(const basic_const_iterator& i, difference_type n) + requires @\libconcept{random_access_iterator}@; +friend constexpr basic_const_iterator operator+(difference_type n, const basic_const_iterator& i) + requires @\libconcept{random_access_iterator}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return basic_const_iterator(i.\exposid{current_} + n);} +\end{itemdescr} + +\indexlibrarymember{operator-}{basic_const_iterator}% +\begin{itemdecl} +friend constexpr basic_const_iterator operator-(const basic_const_iterator& i, difference_type n) + requires @\libconcept{random_access_iterator}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return basic_const_iterator(i.\exposid{current_} - n);} +\end{itemdescr} + +\indexlibrarymember{operator-}{basic_const_iterator}% +\begin{itemdecl} +template<@\libconcept{sized_sentinel_for}@ S> + friend constexpr difference_type operator-(const basic_const_iterator& x, const S& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return x.\exposid{current_} - y;} +\end{itemdescr} + +\indexlibrarymember{operator-}{basic_const_iterator}% +\begin{itemdecl} +template<@\libconcept{sized_sentinel_for}@ S> + requires @\exposconcept{different-from}@ + friend constexpr difference_type operator-(const S& x, const basic_const_iterator& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return x - y.\exposid{current_};} +\end{itemdescr} + \rSec2[move.iterators]{Move iterators and sentinels} \rSec3[move.iterators.general]{General} diff --git a/source/ranges.tex b/source/ranges.tex index f04619dbf1..e4185da3d2 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -63,6 +63,8 @@ using iterator_t = decltype(ranges::begin(declval())); // freestanding template<@\libconcept{range}@ R> using sentinel_t = decltype(ranges::end(declval())); // freestanding + template<@\libconcept{range}@ R> + using const_iterator_t = const_iterator>; template<@\libconcept{range}@ R> using range_difference_t = iter_difference_t>; // freestanding template<@\libconcept{sized_range}@ R> @@ -71,6 +73,8 @@ using range_value_t = iter_value_t>; // freestanding template<@\libconcept{range}@ R> using range_reference_t = iter_reference_t>; // freestanding + template<@\libconcept{range}@ R> + using range_const_reference_t = iter_const_reference_t>; template<@\libconcept{range}@ R> using range_rvalue_reference_t = iter_rvalue_reference_t>; // freestanding @@ -115,6 +119,9 @@ template concept viewable_range = @\seebelow@; // freestanding + template + concept constant_range = @\seebelow@; + // \ref{view.interface}, class template \tcode{view_interface} template requires is_class_v && @\libconcept{same_as}@> @@ -343,6 +350,25 @@ namespace views { inline constexpr @\unspecnc@ reverse = @\unspecnc@; } // freestanding + // \ref{range.as.const}, as const view + template<@\libconcept{input_range}@ R> + constexpr auto& @\exposid{possibly-const-range}@(R& r) { // \expos + if constexpr (@\libconcept{constant_range}@ && !@\libconcept{constant_range}@) { + return const_cast(r); + } else { + return r; + } + } + + template<@\libconcept{view}@ V> + requires @\libconcept{input_range}@ + class as_const_view; + + template + inline constexpr bool enable_borrowed_range> = enable_borrowed_range; + + namespace views { inline constexpr @\unspec@ as_const = @\unspec@; } + // \ref{range.elements}, elements view template<@\libconcept{input_range}@ V, size_t N> requires @\seebelow@ @@ -670,18 +696,26 @@ \pnum The name \tcode{ranges::cbegin} denotes a customization point -object\iref{customization.point.object}. The expression -\tcode{ranges::\brk{}cbegin(E)} for a subexpression \tcode{E} of type \tcode{T} -is expression-equivalent to: +object\iref{customization.point.object}. +Given a subexpression \tcode{E} with type \tcode{T}, +let \tcode{t} be an lvalue that denotes the reified object for \tcode{E}. +Then: \begin{itemize} -\item \tcode{ranges::begin(static_cast(E))} if \tcode{E} is an lvalue. -\item Otherwise, \tcode{ranges::begin(static_cast(E))}. +\item +If \tcode{E} is an rvalue and +\tcode{enable_borrowed_range>} is \tcode{false}, +\tcode{ranges::cbegin(E)} is ill-formed. +\item +Otherwise, +let \tcode{U} be \tcode{ranges::begin(\exposid{possibly-const-range}(t))}. +\tcode{ranges::cbegin(E)} is expression-equivalent to +\tcode{const_iterator(U)}. \end{itemize} \pnum \begin{note} Whenever \tcode{ranges::cbegin(E)} is a valid expression, its type models -\libconcept{input_or_output_iterator}. +\libconcept{input_or_output_iterator} and \exposconcept{constant-iterator}. \end{note} \rSec2[range.access.cend]{\tcode{ranges::cend}} @@ -689,12 +723,20 @@ \pnum The name \tcode{ranges::cend} denotes a customization point -object\iref{customization.point.object}. The expression -\tcode{ranges::cend(E)} for a subexpression \tcode{E} of type \tcode{T} -is expression-equivalent to: +object\iref{customization.point.object}. +Given a subexpression \tcode{E} with type \tcode{T}, +let \tcode{t} be an lvalue that denotes the reified object for \tcode{E}. +Then: \begin{itemize} -\item \tcode{ranges::end(static_cast(E))} if \tcode{E} is an lvalue. -\item Otherwise, \tcode{ranges::end(static_cast(E))}. +\item +If \tcode{E} is an rvalue and +\tcode{enable_borrowed_range>} is \tcode{false}, +\tcode{ranges::cend(E)} is ill-formed. +\item +Otherwise, +let \tcode{U} be \tcode{ranges::end(\exposid{possibly-const-range}(t))}. +\tcode{ranges::cend(E)} is expression-equivalent to +\tcode{const_sentinel(U)}. \end{itemize} \pnum @@ -703,6 +745,8 @@ the types \tcode{S} and \tcode{I} of the expressions \tcode{ranges::cend(E)} and \tcode{ranges::cbegin(E)} model \tcode{\libconcept{sentinel_for}}. +If \tcode{S} models \libconcept{input_iterator}, +then \tcode{S} also models \exposconceptx{constant-itera\-tor}{constant-iterator}. \end{note} \rSec2[range.access.rbegin]{\tcode{ranges::rbegin}} @@ -850,19 +894,27 @@ \pnum The name \tcode{ranges::crbegin} denotes a customization point -object\iref{customization.point.object}. The expression -\tcode{ranges::\brk{}crbegin(E)} for a subexpression \tcode{E} of type -\tcode{T} is expression-equivalent to: +object\iref{customization.point.object}. +Given a subexpression \tcode{E} with type \tcode{T}, +let \tcode{t} be an lvalue that denotes the reified object for \tcode{E}. +Then: \begin{itemize} -\item \tcode{ranges::\brk{}rbegin(static_cast(E))} if \tcode{E} is - an lvalue. -\item Otherwise, \tcode{ranges::rbegin(static_cast(E))}. +\item +If \tcode{E} is an rvalue and +\tcode{enable_borrowed_range>} is \tcode{false}, +\tcode{ranges::crbegin(E)} is ill-formed. +\item +Otherwise, +let \tcode{U} be \tcode{ranges::rbegin(\exposid{possibly-const-range}(t))}. +\tcode{ranges::crbegin(E)} is expres\-sion-equivalent to +\tcode{const_iterator(U)}. \end{itemize} \pnum \begin{note} Whenever \tcode{ranges::crbegin(E)} is a valid expression, its -type models \libconcept{input_or_output_iterator}. +type models \libconcept{input_or_output_iterator} and +\exposconcept{constant-iterator}. \end{note} \rSec2[range.access.crend]{\tcode{ranges::crend}} @@ -870,13 +922,20 @@ \pnum The name \tcode{ranges::crend} denotes a customization point -object\iref{customization.point.object}. The expression -\tcode{ranges::\brk{}crend(E)} for a subexpression \tcode{E} of type \tcode{T} -is expression-equivalent to: +object\iref{customization.point.object}. +Given a subexpression \tcode{E} with type \tcode{T}, +let \tcode{t} be an lvalue that denotes the reified object for \tcode{E}. +Then: \begin{itemize} -\item \tcode{ranges::rend(static_cast(E))} if \tcode{E} is an lvalue. - -\item Otherwise, \tcode{ranges::rend(static_cast(E))}. +\item +If \tcode{E} is an rvalue and +\tcode{enable_borrowed_range>} is \tcode{false}, +\tcode{ranges::crend(E)} is ill-formed. +\item +Otherwise, +let \tcode{U} be \tcode{ranges::rend(\exposid{possibly-const-range}(t))}. +\tcode{ranges::crend(E)} is expression-equivalent to +\tcode{const_sentinel(U)}. \end{itemize} \pnum @@ -885,6 +944,8 @@ the types \tcode{S} and \tcode{I} of the expressions \tcode{ranges::crend(E)} and \tcode{ranges::crbegin(E)} model \tcode{\libconcept{sentinel_for}}. +If \tcode{S} models \libconcept{input_iterator}, +then \tcode{S} also models \exposconceptx{constant-itera\-tor}{constant-iterator}. \end{note} \rSec2[range.prim.size]{\tcode{ranges::size}} @@ -1085,21 +1146,32 @@ \rSec2[range.prim.cdata]{\tcode{ranges::cdata}} \indexlibraryglobal{cdata}% +\begin{codeblock} +template +constexpr auto @\exposid{as-const-pointer}@(const T* p) { return p; } // \expos +\end{codeblock} + \pnum The name \tcode{ranges::cdata} denotes a customization point -object\iref{customization.point.object}. The expression -\tcode{ranges::\brk{}cdata(E)} for a subexpression \tcode{E} of type \tcode{T} -is expression-equivalent to: +object\iref{customization.point.object}. +Given a subexpression \tcode{E} with type \tcode{T}, +let \tcode{t} be an lvalue that denotes the reified object for \tcode{E}. +Then: \begin{itemize} -\item \tcode{ranges::data(static_cast(E))} if \tcode{E} is an lvalue. - -\item Otherwise, \tcode{ranges::data(static_cast(E))}. +\item +If \tcode{E} is an rvalue and +\tcode{enable_borrowed_range>} is \tcode{false}, +\tcode{ranges::cdata(E)} is ill-formed. +\item +Otherwise, +\tcode{ranges::cdata(E)} is expression-equivalent to +\tcode{\exposid{as-const-pointer}(ranges::data(\exposid{possi\-bly-const-range}(t)))}. \end{itemize} \pnum \begin{note} Whenever \tcode{ranges::cdata(E)} is a valid expression, it -has pointer to object type. +has pointer to constant object type. \end{note} \rSec1[range.req]{Range requirements} @@ -1499,6 +1571,16 @@ (is_lvalue_reference_v || (@\libconcept{movable}@> && !@\exposid{is-initializer-list}@)))); \end{itemdecl} +\pnum +The \libconcept{constant_range} concept specifies the requirements of a +\libconcept{range} type whose elements are not modifiable. + +\begin{itemdecl} +template + concept @\deflibconcept{constant_range}@ = + @\libconcept{input_range}@ && @\exposconcept{constant-iterator}@>; +\end{itemdecl} + \rSec1[range.utility]{Range utilities} \rSec2[range.utility.general]{General} @@ -1566,6 +1648,19 @@ return ranges::begin(@\exposid{derived}@()) == ranges::end(@\exposid{derived}@()); } + constexpr auto cbegin() { + return ranges::cbegin(@\exposid{derived}@()); + } + constexpr auto cbegin() const requires @\libconcept{range}@ { + return ranges::cbegin(@\exposid{derived}@()); + } + constexpr auto cend() { + return ranges::cend(@\exposid{derived}@()); + } + constexpr auto cend() const requires @\libconcept{range}@ { + return ranges::cend(@\exposid{derived}@()); + } + constexpr explicit operator bool() requires requires { ranges::empty(@\exposid{derived}@()); } { return !ranges::empty(@\exposid{derived}@()); @@ -7874,6 +7969,93 @@ Equivalent to: \tcode{return make_reverse_iterator(ranges::begin(\exposid{base_}));} \end{itemdescr} +\rSec2[range.as.const]{As const view} + +\rSec3[range.as.const.overview]{Overview} + +\pnum +\tcode{as_const_view} presents a \libconcept{view} of an underlying sequence as constant. +That is, the elements of an \tcode{as_const_view} cannot be modified. + +\pnum +The name \tcode{views::as_const} denotes +a range adaptor object\iref{range.adaptor.object}. +Let \tcode{E} be an expression, +let \tcode{T} be \tcode{decltype((E))}, and +let \tcode{U} be \tcode{remove_cvref_t}. +The expression \tcode{views::as_const(E)} is expression-equivalent to: +\begin{itemize} +\item +If \tcode{views::all_t} models \libconcept{constant_range}, +then \tcode{views::all(E)}. +\item +Otherwise, +if \tcode{U} denotes \tcode{span} +for some type \tcode{X} and some extent \tcode{Extent}, +then \tcode{span(E)}. +\item +Otherwise, +if \tcode{E} is an lvalue, +\tcode{const U} models \libconcept{constant_range}, and +\tcode{U} does not model \libconcept{view}, +then \tcode{ref_view(static_cast(E))}. +\item +Otherwise, \tcode{as_const_view(E)}. +\end{itemize} + +\pnum +\begin{example} +\begin{codeblock} +template +void cant_touch_this(R&&); + +vector hammer = {'m', 'c'}; +span beat = hammer; +cant_touch_this(views::as_const(beat)); // will not modify the elements of \tcode{hammer} +\end{codeblock} +\end{example} + +\rSec3[range.as.const.view]{Class template \tcode{as_const_view}} + +\begin{codeblock} +namespace std::ranges { + template<@\libconcept{input_range}@ V> + requires @\libconcept{view}@V> + class as_const_view : public view_interface> { + V @\exposid{base_}@ = V(); // \expos + + public: + as_const_view() requires @\libconcept{default_initializable}@ = default; + constexpr explicit as_const_view(V base); + + constexpr V base() const & requires @\libconcept{copy_constructible}@ { return @\exposid{base_}@; } + constexpr V base() && { return std::move(@\exposid{base_}@); } + + constexpr auto begin() requires (!@\exposconcept{simple-view}@) { return ranges::cbegin(@\exposid{base_}@); } + constexpr auto begin() const requires @\libconcept{range}@ { return ranges::cbegin(@\exposid{base_}@); } + + constexpr auto end() requires (!@\exposconcept{simple-view}@) { return ranges::cend(@\exposid{base_}@); } + constexpr auto end() const requires @\libconcept{range}@ { return ranges::cend(@\exposid{base_}@); } + + constexpr auto size() requires @\libconcept{sized_range}@ { return ranges::size(@\exposid{base_}@); } + constexpr auto size() const requires @\libconcept{sized_range}@ { return ranges::size(@\exposid{base_}@); } + }; + + template + as_const_view(R&&) -> as_const_view>; +} +\end{codeblock} + +\begin{itemdecl} +constexpr explicit as_const_view(V base); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \exposid{base_} with \tcode{std::move(base)}. +\end{itemdescr} + \rSec2[range.elements]{Elements view} \rSec3[range.elements.overview]{Overview} diff --git a/source/support.tex b/source/support.tex index 2c297c2c59..44eb0a6c5d 100644 --- a/source/support.tex +++ b/source/support.tex @@ -676,6 +676,7 @@ #define @\defnlibxname{cpp_lib_quoted_string_io}@ 201304L // also in \libheader{iomanip} #define @\defnlibxname{cpp_lib_ranges}@ 202202L // also in \libheader{algorithm}, \libheader{functional}, \libheader{iterator}, \libheader{memory}, \libheader{ranges} +#define @\defnlibxname{cpp_lib_ranges_as_const}@ 202207L // also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_chunk}@ 202202L // also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_chunk_by}@ 202202L // also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_iota}@ 202202L // also in \libheader{numeric} From 0efe0f517aa945901fa90740b0c954a96a88df38 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 12 Aug 2022 08:33:39 +0200 Subject: [PATCH 200/430] [iterator.synopsis,ranges.syn] Add 'freestanding' markers per P1642R11 --- source/iterators.tex | 18 +++++++++--------- source/ranges.tex | 13 +++++++------ 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/source/iterators.tex b/source/iterators.tex index b08afe69ad..4bf3d907d4 100644 --- a/source/iterators.tex +++ b/source/iterators.tex @@ -336,37 +336,37 @@ // \ref{const.iterators}, constant iterators and sentinels template<@\libconcept{indirectly_readable}@ I> - using iter_const_reference_t = @\seebelow@; + using iter_const_reference_t = @\seebelow@; // freestanding template concept @\exposconcept{constant-iterator}@ = @\seebelow@; // \expos template - class basic_const_iterator; + class basic_const_iterator; // freestanding template U> - struct common_type, U> { + struct common_type, U> { // freestanding using type = basic_const_iterator>; }; template U> - struct common_type> { + struct common_type> { // freestanding using type = basic_const_iterator>; }; template U> - struct common_type, basic_const_iterator> { + struct common_type, basic_const_iterator> { // freestanding using type = basic_const_iterator>; }; template<@\libconcept{input_iterator}@ I> - using const_iterator = @\seebelow@; + using const_iterator = @\seebelow@; // freestanding template - using const_sentinel = @\seebelow@; + using const_sentinel = @\seebelow@; // freestanding template<@\libconcept{input_iterator}@ I> - constexpr const_iterator make_const_iterator(I it) { return it; } + constexpr const_iterator make_const_iterator(I it) { return it; } // freestanding template - constexpr const_sentinel make_const_sentinel(S s) { return s; } + constexpr const_sentinel make_const_sentinel(S s) { return s; } // freestanding // \ref{move.iterators}, move iterators and sentinels template class move_iterator; // freestanding diff --git a/source/ranges.tex b/source/ranges.tex index e4185da3d2..e856c35bb2 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -64,7 +64,7 @@ template<@\libconcept{range}@ R> using sentinel_t = decltype(ranges::end(declval())); // freestanding template<@\libconcept{range}@ R> - using const_iterator_t = const_iterator>; + using const_iterator_t = const_iterator>; // freestanding template<@\libconcept{range}@ R> using range_difference_t = iter_difference_t>; // freestanding template<@\libconcept{sized_range}@ R> @@ -74,7 +74,7 @@ template<@\libconcept{range}@ R> using range_reference_t = iter_reference_t>; // freestanding template<@\libconcept{range}@ R> - using range_const_reference_t = iter_const_reference_t>; + using range_const_reference_t = iter_const_reference_t>; // freestanding template<@\libconcept{range}@ R> using range_rvalue_reference_t = iter_rvalue_reference_t>; // freestanding @@ -120,7 +120,7 @@ concept viewable_range = @\seebelow@; // freestanding template - concept constant_range = @\seebelow@; + concept constant_range = @\seebelow@; // freestanding // \ref{view.interface}, class template \tcode{view_interface} template @@ -362,12 +362,13 @@ template<@\libconcept{view}@ V> requires @\libconcept{input_range}@ - class as_const_view; + class as_const_view; // freestanding template - inline constexpr bool enable_borrowed_range> = enable_borrowed_range; + inline constexpr bool enable_borrowed_range> = // freestanding + enable_borrowed_range; - namespace views { inline constexpr @\unspec@ as_const = @\unspec@; } + namespace views { inline constexpr @\unspec@ as_const = @\unspec@; } // freestanding // \ref{range.elements}, elements view template<@\libconcept{input_range}@ V, size_t N> From 75b82999486a337797f549d444b8523d59456051 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Tue, 16 Aug 2022 12:52:15 +0100 Subject: [PATCH 201/430] [const.iterators] Add subclause structure. --- source/iterators.tex | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/source/iterators.tex b/source/iterators.tex index 4bf3d907d4..1d26bbe0b0 100644 --- a/source/iterators.tex +++ b/source/iterators.tex @@ -335,11 +335,17 @@ inserter(Container& x, ranges::iterator_t i); // freestanding // \ref{const.iterators}, constant iterators and sentinels + // \ref{const.iterators.alias}, alias templates template<@\libconcept{indirectly_readable}@ I> using iter_const_reference_t = @\seebelow@; // freestanding template concept @\exposconcept{constant-iterator}@ = @\seebelow@; // \expos + template<@\libconcept{input_iterator}@ I> + using const_iterator = @\seebelow@; // freestanding + template + using const_sentinel = @\seebelow@; // freestanding + // \ref{const.iterators.iterator}, class template \tcode{basic_const_iterator} template class basic_const_iterator; // freestanding @@ -356,12 +362,6 @@ using type = basic_const_iterator>; }; - template<@\libconcept{input_iterator}@ I> - using const_iterator = @\seebelow@; // freestanding - - template - using const_sentinel = @\seebelow@; // freestanding - template<@\libconcept{input_iterator}@ I> constexpr const_iterator make_const_iterator(I it) { return it; } // freestanding @@ -4157,6 +4157,8 @@ \rSec2[const.iterators]{Constant iterators and sentinels} +\rSec3[const.iterators.general]{General} + \pnum Class template \tcode{basic_const_iterator} is an iterator adaptor with the same behavior as the underlying iterator @@ -4169,6 +4171,8 @@ \pnum Specializations of \tcode{basic_const_iterator} are constant iterators. +\rSec3[const.iterators.alias]{Alias templates} + \begin{itemdecl} template<@\libconcept{indirectly_readable}@ It> using iter_const_reference_t = common_reference_t&&, @@ -4201,11 +4205,13 @@ Otherwise, \tcode{S}. \end{itemdescr} -\begin{codeblock} -template - concept @\exposconcept{not-a-const-iterator}@ = @\seebelow@; +\rSec3[const.iterators.iterator]{Class template \tcode{basic_const_iterator}} +\begin{codeblock} namespace std { + template + concept @\exposconcept{not-a-const-iterator}@ = @\seebelow@; + template<@\libconcept{input_iterator}@ Iterator> class @\libglobal{basic_const_iterator}@ { Iterator @\exposid{current_}@ = Iterator(); @@ -4318,6 +4324,8 @@ if \tcode{I} is a specialization of \tcode{basic_const_iterator} and \tcode{true} otherwise. +\rSec3[const.iterators.types]{Member types} + \pnum \tcode{basic_const_iterator::iterator_concept} is defined as follows: \begin{itemize} @@ -4344,6 +4352,8 @@ \tcode{basic_const_iterator::iterator_category} denotes the type \tcode{iterator_traits<\brk{}Iterator>::iterator_category}. +\rSec3[const.iterators.ops]{Operations} + \indexlibraryctor{basic_const_iterator}% \begin{itemdecl} constexpr basic_const_iterator(Iterator current); From 66c784012346818dfbb667fca225cbc0528f00fd Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Tue, 2 Aug 2022 21:39:43 -0700 Subject: [PATCH 202/430] P2286R8 Formatting Ranges Two examples are omitted because we cannot currently render them in-place. --- source/containers.tex | 273 ++++++++++++++++ source/support.tex | 2 +- source/utilities.tex | 733 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 1004 insertions(+), 4 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index 5b125d5e12..089dd9a0d6 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -6098,6 +6098,12 @@ // \ref{vector.bool}, class \tcode{vector} template class vector; + template + inline constexpr bool @\exposid{is-vector-bool-reference}@ = @\seebelow@; // \expos + + template requires @\exposid{is-vector-bool-reference}@ + struct formatter; + // hash support template struct hash; template struct hash>; @@ -9291,6 +9297,66 @@ The specialization is enabled\iref{unord.hash}. \end{itemdescr} +\indexlibraryglobal{\exposid{is-vector-bool-reference}}% +\begin{itemdecl} +template + inline constexpr bool @\exposid{is-vector-bool-reference}@ = @\seebelow@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +The variable template +\tcode{\exposid{is-vector-bool-reference}} is \tcode{true} +if \tcode{T} denotes the type \tcode{vector::reference} +for some type \tcode{Alloc} and +\tcode{vector} is not a program-defined specialization. +\end{itemdescr} + +\indexlibraryglobal{formatter}% +\begin{codeblock} +namespace std { + template + requires @\exposid{is-vector-bool-reference}@ + struct formatter { + private: + formatter @\exposid{underlying_}@; // \expos + + public: + template + constexpr typename ParseContext::iterator + parse(ParseContext& ctx); + + template + typename FormatContext::iterator + format(const T& ref, FormatContext& ctx) const; + }; +} +\end{codeblock} + +\indexlibrarymember{parse}{formatter}% +\begin{itemdecl} +template + constexpr typename ParseContext::iterator + parse(ParseContext& ctx); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Equivalent to: \tcode{return \exposid{underlying_}.parse(ctx);} +\end{itemdescr} + +\indexlibrarymember{format}{formatter}% +\begin{itemdecl} +template + typename FormatContext::iterator + format(const T& ref, FormatContext& ctx) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Equivalent to: \tcode{return \exposid{underlying_}.format(ref, ctx);} +\end{itemdescr} + \rSec1[associative]{Associative containers} \rSec2[associative.general]{In general} @@ -12969,6 +13035,155 @@ \end{codeblock} \end{itemdescr} +\rSec1[assoc.format]{Associative formatting} + +\pnum +For each of +\tcode{map}, +\tcode{multimap}, +\tcode{unordered_map}, and +\tcode{unordered_multimap}, +the library provides the following formatter specialization +where \tcode{\placeholder{map-type}} is the name of the template: + +\indexlibraryglobal{formatter}% +\begin{codeblock} +namespace std { + template T, class... U> + requires @\libconcept{formattable}@ + struct formatter<@\placeholder{map-type}@, charT> { + private: + using @\exposid{maybe-const-map}@ = // \expos + @\exposid{fmt-maybe-const}@<@\placeholder{map-type}@, charT>; + range_formatter>, + charT> @\exposid{underlying_}@; // \expos + public: + constexpr formatter(); + + template + constexpr typename ParseContext::iterator + parse(ParseContext& ctx); + + template + typename FormatContext::iterator + format(@\exposid{maybe-const-map}@& r, FormatContext& ctx) const; + }; +} +\end{codeblock} + +\indexlibraryctor{formatter}% +\begin{itemdecl} +constexpr formatter(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +@\exposid{underlying_}@.set_brackets(@\exposid{STATICALLY-WIDEN}@("{"), @\exposid{STATICALLY-WIDEN}@("}")); +@\exposid{underlying_}@.underlying().set_brackets({}, {}); +@\exposid{underlying_}@.underlying().set_separator(@\exposid{STATICALLY-WIDEN}@(": ")); +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{parse}{formatter}% +\begin{itemdecl} +template + constexpr typename ParseContext::iterator + parse(ParseContext& ctx); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return \exposid{underlying_}.parse(ctx);} +\end{itemdescr} + +\indexlibrarymember{format}{formatter}% +\begin{itemdecl} +template + typename FormatContext::iterator + format(@\exposid{maybe-const-map}@& r, FormatContext& ctx) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return \exposid{underlying_}.format(r, ctx);} +\end{itemdescr} + +\pnum +For each of +\tcode{set}, +\tcode{multiset}, +\tcode{unordered_set}, and +\tcode{unordered_multiset}, +the library provides the following formatter specialization +where \tcode{\placeholder{set-type}} is the name of the template: + +\indexlibraryglobal{formatter}% +\begin{codeblock} +namespace std { +template + requires @\libconcept{formattable}@ + struct formatter<@\placeholder{set-type}@, charT> { + private: + range_formatter @\exposid{underlying_}@; // \expos + public: + constexpr formatter(); + + template + constexpr typename ParseContext::iterator + parse(ParseContext& ctx); + + template + typename FormatContext::iterator + format(const @\placeholder{set-type}@& r, FormatContext& ctx) const; + }; +} +\end{codeblock} + +\indexlibraryctor{formatter}% +\begin{itemdecl} +constexpr formatter(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +@\exposid{underlying_}@.set_brackets(@\exposid{STATICALLY-WIDEN}@("{"), @\exposid{STATICALLY-WIDEN}@("}")); +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{parse}{formatter}% +\begin{itemdecl} +template + constexpr typename ParseContext::iterator + parse(ParseContext& ctx); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return \exposid{underlying_}.parse(ctx);} +\end{itemdescr} + +\indexlibrarymember{format}{formatter}% +\begin{itemdecl} +template + typename FormatContext::iterator + format(const @\placeholder{set-type}@& r, FormatContext& ctx) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return \exposid{underlying_}.format(r, ctx);} +\end{itemdescr} + \rSec1[container.adaptors]{Container adaptors} \rSec2[container.adaptors.general]{In general} @@ -17308,6 +17523,64 @@ \end{codeblock} \end{itemdescr} +\rSec2[container.adaptors.format]{Container adaptors formatting} + +\pnum +For each of +\tcode{queue}, +\tcode{priority_queue}, and +\tcode{stack}, +the library provides the following formatter specialization +where \tcode{\placeholder{adaptor-type}} is the name of the template: + +\indexlibraryglobal{formatter}% +\begin{codeblock} +namespace std { + template Container, class... U> + struct formatter<@\placeholder{adaptor-type}@, charT> { + private: + using @\exposid{maybe-const-adaptor}@ = // \expos + @\exposid{fmt-maybe-const}@<@\placeholder{adaptor-type}@, charT>; + formatter @\exposid{underlying_}@; // \expos + + public: + template + constexpr typename ParseContext::iterator + parse(ParseContext& ctx); + + template + typename FormatContext::iterator + format(@\exposid{maybe-const-adaptor}@& r, FormatContext& ctx) const; + }; +} +\end{codeblock} + +\indexlibrarymember{parse}{formatter}% +\begin{itemdecl} +template + constexpr typename ParseContext::iterator + parse(ParseContext& ctx); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return \exposid{underlying_}.parse(ctx);} +\end{itemdescr} + +\indexlibrarymember{format}{formatter}% +\begin{itemdecl} +template + typename FormatContext::iterator + format(@\exposid{maybe-const-adaptor}@& r, FormatContext& ctx) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return \exposid{underlying_}.format(r.c, ctx);} +\end{itemdescr} + \rSec1[views]{Views} \rSec2[views.general]{General} diff --git a/source/support.tex b/source/support.tex index 44eb0a6c5d..c3b63e53ec 100644 --- a/source/support.tex +++ b/source/support.tex @@ -620,7 +620,7 @@ #define @\defnlibxname{cpp_lib_filesystem}@ 201703L // also in \libheader{filesystem} #define @\defnlibxname{cpp_lib_find_last}@ 202207L // also in \libheader{algorithm} #define @\defnlibxname{cpp_lib_flat_map}@ 202207L // also in \libheader{flat_map} -#define @\defnlibxname{cpp_lib_format}@ 202110L // also in \libheader{format} +#define @\defnlibxname{cpp_lib_format}@ 202207L // also in \libheader{format} #define @\defnlibxname{cpp_lib_gcd_lcm}@ 201606L // also in \libheader{numeric} #define @\defnlibxname{cpp_lib_generic_associative_lookup}@ 201304L // also in \libheader{map}, \libheader{set} #define @\defnlibxname{cpp_lib_generic_unordered_lookup}@ 201811L diff --git a/source/utilities.tex b/source/utilities.tex index 0acc625c6a..b55737e40f 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -13797,13 +13797,37 @@ size_t formatted_size(const locale& loc, @\exposid{wformat-string}@ fmt, Args&&... args); // \ref{format.formatter}, formatter + // \ref{format.formatter.spec}, formatter specializations template struct formatter; + // \ref{format.range}, class template \tcode{range_formatter} + template + requires @\libconcept{same_as}@, T> && @\libconcept{formattable}@ + class range_formatter; + + template + requires (!@\libconcept{same_as}@>, R>) && + @\libconcept{formattable}@, charT> + struct formatter; + // \ref{format.parse.ctx}, class template \tcode{basic_format_parse_context} template class basic_format_parse_context; using format_parse_context = basic_format_parse_context; using wformat_parse_context = basic_format_parse_context; + // \ref{format.formattable}, concept \libconcept{formattable} + template + concept formattable = @\seebelow@; + + template + concept @\defexposconcept{const-formattable-range}@ = // \expos + ranges::@\libconcept{input_range}@ && + @\libconcept{formattable}@, charT>; + + template + using @\exposid{fmt-maybe-const}@ = // \expos + conditional_t<@\exposconcept{const-formattable-range}@, const R, R>; + // \ref{format.arguments}, arguments // \ref{format.arg}, class template \tcode{basic_format_arg} template class basic_format_arg; @@ -14024,7 +14048,7 @@ \begin{ncbnf} \fmtnontermdef{type} \textnormal{one of}\br - \terminal{a A b B c d e E f F g G o p s x X} + \terminal{a A b B c d e E f F g G o p s x X ?} \end{ncbnf} \pnum @@ -14300,6 +14324,10 @@ \lhdr{Type} & \rhdr{Meaning} \\ \rowsep none, \tcode{s} & Copies the string to the output. +\\ \rowsep +% +\tcode{?} & +Copies the escaped string\iref{format.string.escaped} to the output. \\ \end{floattable} @@ -14397,6 +14425,10 @@ % \tcode{b}, \tcode{B}, \tcode{d}, \tcode{o}, \tcode{x}, \tcode{X} & As specified in \tref{format.type.int}. +\\ \rowsep +% +\tcode{?} & +Copies the escaped character\iref{format.string.escaped} to the output. \\ \end{floattable} @@ -14954,6 +14986,35 @@ \\ \end{concepttable} +\rSec3[format.formattable]{Concept \cname{formattable}} + +\pnum +Let \tcode{\placeholder{fmt-iter-for}} be an unspecified type +that models +\tcode{\libconcept{output_iterator}}\iref{iterator.concept.output}. + +\begin{codeblock} +template + concept @\deflibconcept{formattable}@ = + @\libconcept{semiregular}@, charT>> && + requires (formatter, charT> f, + const formatter, charT> cf, + T t, + basic_format_context<@\placeholder{fmt-iter-for}@, charT> fc, + basic_format_parse_context pc) { + { f.parse(pc) } -> @\libconcept{same_as}@::iterator>; + { cf.format(t, fc) } -> @\libconcept{same_as}@<@\placeholder{fmt-iter-for}@>; + }; +\end{codeblock} + +\pnum +A type \tcode{T} and a character type \tcode{charT} +model \libconcept{formattable} +if \tcode{formatter, charT>} meets +the \newoldconcept{BasicFormatter} requirements\iref{formatter.requirements} +and, if \tcode{remove_reference_t} is const-qualified, +the \newoldconcept{Formatter} requirements. + \rSec3[format.formatter.spec]{Formatter specializations} \indexlibraryglobal{formatter}% @@ -14967,12 +15028,19 @@ Let \tcode{charT} be either \tcode{char} or \keyword{wchar_t}. Each specialization of \tcode{formatter} is either enabled or disabled, as described below. +\indextext{\idxcode{formatter}!debug-enabled specialization of}% +A \defn{debug-enabled} specialization of \tcode{formatter} +additionally provides +a public, constexpr, non-static member function \tcode{set_debug_format()} +which modifies the state of the \tcode{formatter} to be as if +the type of the \fmtgrammarterm{std-format-spec} +parsed by the last call to \tcode{parse} were \tcode{?}. Each header that declares the template \tcode{formatter} provides the following enabled specializations: \begin{itemize} \item \indexlibrary{\idxcode{formatter}!specializations!character types}% -The specializations +The debug-enabled specializations \begin{codeblock} template<> struct formatter; template<> struct formatter; @@ -14982,7 +15050,7 @@ \item \indexlibrary{\idxcode{formatter}!specializations!string types}% For each \tcode{charT}, -the string type specializations +the debug-enabled string type specializations \begin{codeblock} template<> struct formatter; template<> struct formatter; @@ -15080,6 +15148,151 @@ \end{codeblock} \end{example} +\rSec3[format.string.escaped]{Formatting escaped characters and strings} + +\pnum +\indextext{string!formatted as escaped}% +\indextext{character!formatted as escaped}% +A character or string can be formatted as \defn{escaped} +to make it more suitable for debugging or for logging. + +\pnum +The escaped string \placeholder{E} representation of a string \placeholder{S} +is constructed by encoding a sequence of characters as follows. +The associated character encoding \placeholder{CE} +for \tcode{charT}~(\tref{lex.string.literal}) +is used to both interpret \placeholder{S} and construct \placeholder{E}. + +\begin{itemize} +\item +\unicode{0022}{quotation mark} (\tcode{"}) is appended to \placeholder{E}. + +\item +For each code unit sequence \placeholder{X} in \placeholder{S} that either +encodes a single character, +is a shift sequence, or +is a sequence of ill-formed code units, +processing is in order as follows: + +\begin{itemize} +\item +If \placeholder{X} encodes a single character \placeholder{C}, then: + +\begin{itemize} +\item +If \placeholder{C} is one of the characters in \tref{format.escape.sequences}, +then the two characters shown as the corresponding escape sequence +are appended to \placeholder{E}. + +\item +Otherwise, if \placeholder{C} is not \unicode{0020}{space} and + +\begin{itemize} +\item +\placeholder{CE} is a Unicode encoding and +\placeholder{C} corresponds to either +a UCS scalar value whose Unicode property \tcode{General_Category} +has a value in the groups \tcode{Separator} (\tcode{Z}) or \tcode{Other} (\tcode{C}) or to +a UCS scalar value which has the Unicode property \tcode{Grapheme_Extend=Yes}, +as described by table 12 of UAX \#44, or + +\item +\placeholder{CE} is not a Unicode encoding and +\placeholder{C} is one of an implementation-defined set +of separator or non-printable characters +\end{itemize} + +then the sequence \tcode{\textbackslash u\{\placeholder{hex-digit-sequence}\}} +is appended to \placeholder{E}, +where \tcode{\placeholder{hex-digit-sequence}} +is the shortest hexadecimal representation +of \placeholder{C} using lower-case hexadecimal digits. + +\item +Otherwise, \placeholder{C} is appended to \placeholder{E}. +\end{itemize} + +\item +Otherwise, if \placeholder{X} is a shift sequence, +the effect on \placeholder{E} and further decoding of \placeholder{S} +is unspecified. + +\recommended +A shift sequence should be represented in \placeholder{E} +such that the original code unit sequence of \placeholder{S} +can be reconstructed. + +\item +Otherwise (\placeholder{X} is a sequence of ill-formed code units), +each code unit \placeholder{U} is appended to \placeholder{E} in order +as the sequence \tcode{\textbackslash x\{\placeholder{hex-digit-sequence}\}}, +where \tcode{\placeholder{hex-digit-sequence}} +is the shortest hexadecimal representation of \placeholder{U} +using lower-case hexadecimal digits. +\end{itemize} + +\item +Finally, \unicode{0022}{quotation mark} (\tcode{"}) +is appended to \placeholder{E}. +\end{itemize} +% +\begin{floattable}{Mapping of characters to escape sequences}{format.escape.sequences}{ll} +\topline +\lhdr{Character} & \rhdr{Escape sequence} \\ \rowsep +\unicode{0009}{character tabulation} & +\tcode{\textbackslash t} +\\ \rowsep +% +\unicode{000a}{line feed} & +\tcode{\textbackslash n} +\\ \rowsep +% +\unicode{000d}{carriage return} & +\tcode{\textbackslash r} +\\ \rowsep +% +\unicode{0022}{quotation mark} & +\tcode{\textbackslash "} +\\ \rowsep +% +\unicode{005c}{reverse solidus} & +\tcode{\textbackslash\textbackslash} +\\ +\end{floattable} + +\pnum +The escaped string representation of a character \placeholder{C} +is equivalent to the escaped string representation +of a string of \placeholder{C}, except that: + +\begin{itemize} +\item +the result starts and ends with \unicode{0027}{apostrope} (\tcode{'}) +instead of \unicode{0022}{quotation mark} (\tcode{"}), and +\item +if \placeholder{C} is \unicode{0027}{apostrope}, +the two characters \tcode{\textbackslash '} are appended to \placeholder{E}, and +\item +if \placeholder{C} is \unicode{0022}{quotation mark}, +then \placeholder{C} is appended unchanged. +\end{itemize} + +%% FIXME: Example is incomplete; s2 and s6 are missing below; +%% FIXME: their Unicode characters are not available in our font (Latin Modern). +\begin{example} +\begin{codeblock} +string s0 = format("[{}]", "h\tllo"); // \tcode{s0} has value: \tcode{[h llo]} +string s1 = format("[{:?}]", "h\tllo"); // \tcode{s1} has value: \tcode{["h\textbackslash tllo"]} +string s3 = format("[{:?}] [{:?}]", '\'', '"'); // \tcode{s3} has value: \tcode{['\textbackslash '', '"']} + +// The following examples assume use of the UTF-8 encoding +string s4 = format("[{:?}]", string("\0 \n \t \x02 \x1b", 9)); + // \tcode{s4} has value: \tcode{[\textbackslash u\{0\} \textbackslash n \textbackslash t \textbackslash u\{2\} \textbackslash u\{1b\}]} +string s5 = format("[{:?}]", "\xc3\x28"); // invalid UTF-8 + // \tcode{s5} has value: \tcode{["\textbackslash x\{c3\}\textbackslash x\{28\}"]} +\end{codeblock} +\end{example} + \rSec3[format.parse.ctx]{Class template \tcode{basic_format_parse_context}} \indexlibraryglobal{basic_format_parse_context}% @@ -15372,6 +15585,326 @@ \end{codeblock} \end{example} +\rSec2[format.range]{Class template \tcode{range_formatter}} + +\pnum +The class template \tcode{range_formatter} is a convenient utility +for implementing \tcode{formatter} specializations for range types. + +\pnum +\tcode{range_formatter} interprets \fmtgrammarterm{format-spec} +as a \fmtgrammarterm{range-format-spec}. +The syntax of format specifications is as follows: + +\begin{ncbnf} +\fmtnontermdef{range-format-spec}\br + \opt{range-fill-and-align} \opt{width} \opt{\terminal{n}} \opt{range-type} \opt{range-underlying-spec} +\end{ncbnf} + +\begin{ncbnf} +\fmtnontermdef{range-fill-and-align}\br + \opt{range-fill} align +\end{ncbnf} + +\begin{ncbnf} +\fmtnontermdef{range-fill}\br + \textnormal{any character other than} \terminal{\{} \textnormal{or} \terminal{\}} \textnormal{or} \terminal{:} +\end{ncbnf} + +\begin{ncbnf} +\fmtnontermdef{range-type}\br + \terminal{m}\br + \terminal{s}\br + \terminal{?s} +\end{ncbnf} + +\begin{ncbnf} +\fmtnontermdef{range-underlying-spec}\br + \terminal{:} format-spec +\end{ncbnf} + +\pnum +For \tcode{range_formatter}, +the \fmtgrammarterm{format-spec} +in a \fmtgrammarterm{range-underlying-spec}, if any, +is interpreted by \tcode{formatter}. + +\pnum +The \fmtgrammarterm{range-fill-and-align} is interpreted +the same way as a \fmtgrammarterm{fill-and-align}\iref{format.string.std}. +The productions \fmtgrammarterm{align} and \fmtgrammarterm{width} +are described in \ref{format.string}. + +\pnum +The \tcode{n} option causes the range to be formatted +without the opening and closing brackets. +\begin{note} +This is equivalent to invoking \tcode{set_brackets(\{\}, \{\})}. +\end{note} + +\pnum +The \fmtgrammarterm{range-type} specifier changes the way a range is formatted, +with certain options only valid with certain argument types. +The meaning of the various type options +is as specified in \tref{formatter.range.type}. + +\begin{concepttable}{Meaning of \fmtgrammarterm{range-type} options}{formatter.range.type} +{p{1in}p{1.4in}p{2.7in}} +\topline +\hdstyle{Option} & \hdstyle{Requirements} & \hdstyle{Meaning} \\ \capsep +% +\tcode{m} & +\tcode{T} shall be +either a specialization of \tcode{pair} or a specialization of \tcode{tuple} +such that \tcode{tuple_size_v} is \tcode{2}. & +Indicates that +the opening bracket should be \tcode{"\{"}, +the closing bracket should be \tcode{"\}"}, +the separator should be \tcode{", "}, and +each range element should be formatted as if +\tcode{m} were specified for its \fmtgrammarterm{tuple-type}. +\begin{tailnote} +If the \tcode{n} option is provided in addition to the \tcode{m} option, +both the opening and closing brackets are still empty. +\end{tailnote} +\\ \rowsep +% +\tcode{s} & +\tcode{T} shall be \tcode{charT}. & +Indicates that the range should be formatted as a \tcode{string}. +\\ \rowsep +% +\tcode{?s} & +\tcode{T} shall be \tcode{charT}. & +Indicates that the range should be formatted as +an escaped string\iref{format.string.escaped}. +\\ +\end{concepttable} + +If the \fmtgrammarterm{range-type} is \tcode{s} or \tcode{?s}, +then there shall be +no \tcode{n} option and no \fmtgrammarterm{range-underlying-spec}. + +\indexlibraryglobal{range_formatter}% +\begin{codeblock} +namespace std { + template + requires @\libconcept{same_as}@, T> && @\libconcept{formattable}@ + class range_formatter { + formatter @\exposid{underlying_}@; // \expos + basic_string_view @\exposid{separator_}@ = @\exposid{STATICALLY-WIDEN}@(", "); // \expos + basic_string_view @\exposid{opening-bracket_}@ = @\exposid{STATICALLY-WIDEN}@("["); // \expos + basic_string_view @\exposid{closing-bracket_}@ = @\exposid{STATICALLY-WIDEN}@("]"); // \expos + + public: + constexpr void set_separator(basic_string_view sep); + constexpr void set_brackets(basic_string_view opening, + basic_string_view closing); + constexpr formatter& underlying() { return @\exposid{underlying_}@; } + constexpr const formatter& underlying() const { return @\exposid{underlying_}@; } + + template + constexpr typename ParseContext::iterator + parse(ParseContext& ctx); + + template + requires @\libconcept{formattable}@, charT> && + @\libconcept{same_as}@>, T> + typename FormatContext::iterator + format(R&& r, FormatContext& ctx) const; + }; +} +\end{codeblock} + +\indexlibrarymember{set_separator}{range_formatter}% +\begin{itemdecl} +constexpr void set_separator(basic_string_view sep); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{\exposid{separator_} = sep;} +\end{itemdescr} + +\indexlibrarymember{set_brackets}{range_formatter}% +\begin{itemdecl} +constexpr void set_brackets(basic_string_view opening, basic_string_view closing); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +@\exposid{opening-bracket_}@ = opening; +@\exposid{closing-bracket_}@ = closing; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{parse}{range_formatter}% +\begin{itemdecl} +template + constexpr typename ParseContext::iterator + parse(ParseContext& ctx); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Parses the format specifier as a \fmtgrammarterm{range-format-spec} and +stores the parsed specifiers in \tcode{*this}. +The values of +\exposid{opening-bracket_}, \exposid{closing-bracket_}, and \exposid{separator_} +are modified if and only if required by +the \fmtgrammarterm{range-type} or the \tcode{n} option, if present. +If: +\begin{itemize} +\item +the \fmtgrammarterm{range-type} is neither \tcode{s} nor \tcode{?s}, +\item +\tcode{\exposid{underlying_}.set_debug_format()} is a valid expression, and +\item +there is no \fmtgrammarterm{range-underlying-spec}, +\end{itemize} +then calls \tcode{\exposid{underlying_}.set_debug_format()}. + +\pnum +\returns +An iterator past the end of the \fmtgrammarterm{range-format-spec}. +\end{itemdescr} + +\indexlibrarymember{format}{range_formatter}% +\begin{itemdecl} +template + requires @\libconcept{formattable}@, charT> && + @\libconcept{same_as}@>, T> + typename FormatContext::iterator + format(R&& r, FormatContext& ctx) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Writes the following into \tcode{ctx.out()}, +adjusted according to the \fmtgrammarterm{range-format-spec}: + +\begin{itemize} +\item +If the \fmtgrammarterm{range-type} was \tcode{s}, +then as if by formatting \tcode{basic_string(from_range, r)}. +\item +Otherwise, if the \fmtgrammarterm{range-type} was \tcode{?s}, +then as if by formatting \tcode{basic_string(from_range, r)} +as an escaped string\iref{format.string.escaped}. +\item +Otherwise, +\begin{itemize} +\item +\exposid{opening-bracket_}, +\item +for each element \tcode{e} of the range \tcode{r}: +\begin{itemize} +\item +the result of writing \tcode{e} via \exposid{underlying_} and +\item +\exposid{separator_}, unless \tcode{e} is the last element of \tcode{r}, and +\end{itemize} +\item +\exposid{closing-bracket_}. +\end{itemize} +\end{itemize} + +\pnum +\returns +An iterator past the end of the output range. +\end{itemdescr} + +\indexlibraryglobal{formatter}% +\begin{codeblock} +namespace std { + template + requires (!@\libconcept{same_as}@>, R>) && + @\libconcept{formattable}@, charT> + struct formatter { + private: + using @\exposid{maybe-const-r}@ = @\exposid{fmt-maybe-const}@; + range_formatter>, + charT> @\exposid{underlying_}@; // \expos + + public: + constexpr void set_separator(basic_string_view sep); + constexpr void set_brackets(basic_string_view opening, + basic_string_view closing); + + template + constexpr typename ParseContext::iterator + parse(ParseContext& ctx); + + template + typename FormatContext::iterator + format(@\exposid{maybe-const-r}@& elems, FormatContext& ctx) const; + }; +} +\end{codeblock} + +\pnum +\begin{note} +The \tcode{(!\libconcept{same_as}>, R>)} +constraint prevents constraint recursion +for ranges whose reference type is the same range type. +For example, \tcode{std::filesystem::path} +is a range of \tcode{std::filesystem::path}. +\end{note} + +\indexlibrarymember{set_separator}{formatter}% +\begin{itemdecl} +constexpr void set_separator(basic_string_view sep); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{\exposid{underlying_}.set_separator(sep);} +\end{itemdescr} + +\indexlibrarymember{set_brackets}{formatter}% +\begin{itemdecl} +constexpr void set_brackets(basic_string_view opening, basic_string_view closing); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{\exposid{underlying_}.set_brackets(opening, closing);} +\end{itemdescr} + +\indexlibrarymember{parse}{formatter}% +\begin{itemdecl} +template + constexpr typename ParseContext::iterator + parse(ParseContext& ctx); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return \exposid{underlying_}.parse(ctx);} +\end{itemdescr} + +\indexlibrarymember{format}{formatter}% +\begin{itemdecl} +template + typename FormatContext::iterator + format(@\exposid{maybe-const-r}@& elems, FormatContext& ctx) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return \exposid{underlying_}.format(elems, ctx);} +\end{itemdescr} + \rSec2[format.arguments]{Arguments} \rSec3[format.arg]{Class template \tcode{basic_format_arg}} @@ -15790,6 +16323,200 @@ \tcode{i < size_ ?\ data_[i] :\ basic_format_arg()}. \end{itemdescr} +\rSec2[format.tuple]{Tuple formatter} + +\pnum +For each of \tcode{pair} and \tcode{tuple}, +the library provides the following formatter specialization +where \tcode{\placeholder{tuple-type}} is the name of the template: + +\indexlibraryglobal{formatter}% +\begin{codeblock} +namespace std { + template... Ts> + struct formatter<@\placeholder{tuple-type}@, charT> { + private: + tuple, charT>...> @\exposid{underlying_}@; // \expos + basic_string_view @\exposid{separator_}@ = @\exposid{STATICALLY-WIDEN}@(", "); // \expos + basic_string_view @\exposid{opening-bracket_}@ = @\exposid{STATICALLY-WIDEN}@("("); // \expos + basic_string_view @\exposid{closing-bracket_}@ = @\exposid{STATICALLY-WIDEN}@(")"); // \expos + + public: + constexpr void set_separator(basic_string_view sep); + constexpr void set_brackets(basic_string_view opening, + basic_string_view closing); + + template + constexpr typename ParseContext::iterator + parse(ParseContext& ctx); + + template + typename FormatContext::iterator + format(@\seebelow@& elems, FormatContext& ctx) const; + }; +} +\end{codeblock} + +\pnum +The \tcode{parse} member functions of these formatters +interpret the format specification as +a \fmtgrammarterm{tuple-format-spec} according to the following syntax: + +\begin{ncbnf} +\fmtnontermdef{tuple-format-spec}\br + \opt{tuple-fill-and-align} \opt{width} \opt{tuple-type} +\end{ncbnf} + +\begin{ncbnf} +\fmtnontermdef{tuple-fill-and-align}\br + \opt{tuple-fill} align +\end{ncbnf} + +\begin{ncbnf} +\fmtnontermdef{tuple-fill}\br + \textnormal{any character other than} \terminal{\{} \textnormal{or} \terminal{\}} \textnormal{or} \terminal{:} +\end{ncbnf} + +\begin{ncbnf} +\fmtnontermdef{tuple-type}\br + \terminal{m}\br + \terminal{n} +\end{ncbnf} + +\pnum +The \fmtgrammarterm{tuple-fill-and-align} is interpreted the same way as +a \fmtgrammarterm{fill-and-align}\iref{format.string.std}. +The productions \fmtgrammarterm{align} and \fmtgrammarterm{width} +are described in \ref{format.string}. + +\pnum +The \fmtgrammarterm{tuple-type} specifier +changes the way a \tcode{pair} or \tcode{tuple} is formatted, +with certain options only valid with certain argument types. +The meaning of the various type options +is as specified in \tref{formatter.tuple.type}. + +\begin{concepttable}{Meaning of \fmtgrammarterm{tuple-type} options}{formatter.tuple.type} +{p{0.5in}p{1.4in}p{3.2in}} +\topline +\hdstyle{Option} & \hdstyle{Requirements} & \hdstyle{Meaning} \\ \capsep +% +\tcode{m} & +\tcode{sizeof...(Ts) == 2} & +Equivalent to: +\begin{codeblock} +set_separator(@\exposid{STATICALLY-WIDEN}@(": ")); +set_brackets({}, {}); +\end{codeblock}% +\\ \rowsep +% +\tcode{n} & +none & +Equivalent to: \tcode{set_brackets(\{\}, \{\});} +\\ \rowsep +% +none & +none & +No effects +\\ +\end{concepttable} + +\indexlibrarymember{set_separator}{formatter}% +\begin{itemdecl} +constexpr void set_separator(basic_string_view sep); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{\exposid{separator_} = sep;} +\end{itemdescr} + +\indexlibrarymember{set_brackets}{formatter}% +\begin{itemdecl} +constexpr void set_brackets(basic_string_view opening, basic_string_view closing); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +@\exposid{opening-bracket_}@ = opening; +@\exposid{closing-bracket_}@ = closing; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{parse}{formatter}% +\begin{itemdecl} +template + constexpr typename ParseContext::iterator + parse(ParseContext& ctx); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Parses the format specifier as a \fmtgrammarterm{tuple-format-spec} and +stores the parsed specifiers in \tcode{*this}. +The values of +\exposid{opening-bracket_}, +\exposid{closing-bracket_}, and +\exposid{separator_} +are modified if and only if +required by the \fmtgrammarterm{tuple-type}, if present. +For each element \tcode{\placeholder{e}} in \exposid{underlying_}, +if \tcode{\placeholder{e}.set_debug_format()} is a valid expression, +calls \tcode{\placeholder{e}.set_debug_format()}. + +\pnum +\returns +An iterator past the end of the \fmtgrammarterm{tuple-format-spec}. +\end{itemdescr} + +\indexlibrarymember{format}{formatter}% +\begin{itemdecl} +template + typename FormatContext::iterator + format(@\seebelow@& elems, FormatContext& ctx) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +The type of \tcode{elems} is: +\begin{itemize} +\item +If \tcode{(\libconcept{formattable} \&\& ...)} is \tcode{true}, +\tcode{const \placeholder{tuple-type}\&}. +\item +Otherwise \tcode{\placeholder{tuple-type}\&}. +\end{itemize} + +\pnum +\effects +Writes the following into \tcode{ctx.out()}, +adjusted according to the \fmtgrammarterm{tuple-format-spec}: +\begin{itemize} +\item +\exposid{opening-bracket_}, +\item +for each index \tcode{I} in the \range{0}{sizeof...(Ts)}: +\begin{itemize} +\item +if \tcode{I != 0}, \exposid{separator_}, +\item +the result of writing \tcode{get(elems)} +via \tcode{get(\exposid{underlying_})}, and +\end{itemize} +\item +\exposid{closing-bracket_}. +\end{itemize} + +\pnum +\returns +An iterator past the end of the output range. +\end{itemdescr} + \rSec2[format.error]{Class \tcode{format_error}} \indexlibraryglobal{format_error}% From 658ec649ec2b824f49e441f64de1682901c2c92a Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 3 Aug 2022 14:01:53 -0700 Subject: [PATCH 203/430] [format.range] Drop the superfluous "convenient" utility descriptor --- source/utilities.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/utilities.tex b/source/utilities.tex index b55737e40f..0976b8cab5 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -15588,7 +15588,7 @@ \rSec2[format.range]{Class template \tcode{range_formatter}} \pnum -The class template \tcode{range_formatter} is a convenient utility +The class template \tcode{range_formatter} is a utility for implementing \tcode{formatter} specializations for range types. \pnum From dad87aa3b0db331e6213b3ada8bf3fe20f91a34e Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 3 Aug 2022 14:44:37 -0700 Subject: [PATCH 204/430] [format.range] Rename section to [format.range.formatter] --- source/utilities.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/utilities.tex b/source/utilities.tex index 0976b8cab5..da521382a4 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -13800,7 +13800,7 @@ // \ref{format.formatter.spec}, formatter specializations template struct formatter; - // \ref{format.range}, class template \tcode{range_formatter} + // \ref{format.range.formatter}, class template \tcode{range_formatter} template requires @\libconcept{same_as}@, T> && @\libconcept{formattable}@ class range_formatter; @@ -15585,7 +15585,7 @@ \end{codeblock} \end{example} -\rSec2[format.range]{Class template \tcode{range_formatter}} +\rSec2[format.range.formatter]{Class template \tcode{range_formatter}} \pnum The class template \tcode{range_formatter} is a utility From c66bdce380146ec212aa8d8088980960808954f9 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Thu, 4 Aug 2022 12:51:15 -0700 Subject: [PATCH 205/430] [format.range.formatter][format.tuple] Rename tuple-type to pair-or-tuple to avoid confusion with the grammarterm of the same name --- source/utilities.tex | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/utilities.tex b/source/utilities.tex index da521382a4..a186770a56 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -16328,13 +16328,13 @@ \pnum For each of \tcode{pair} and \tcode{tuple}, the library provides the following formatter specialization -where \tcode{\placeholder{tuple-type}} is the name of the template: +where \tcode{\placeholder{pair-or-tuple}} is the name of the template: \indexlibraryglobal{formatter}% \begin{codeblock} namespace std { template... Ts> - struct formatter<@\placeholder{tuple-type}@, charT> { + struct formatter<@\placeholder{pair-or-tuple}@, charT> { private: tuple, charT>...> @\exposid{underlying_}@; // \expos basic_string_view @\exposid{separator_}@ = @\exposid{STATICALLY-WIDEN}@(", "); // \expos @@ -16487,9 +16487,9 @@ \begin{itemize} \item If \tcode{(\libconcept{formattable} \&\& ...)} is \tcode{true}, -\tcode{const \placeholder{tuple-type}\&}. +\tcode{const \placeholder{pair-or-tuple}\&}. \item -Otherwise \tcode{\placeholder{tuple-type}\&}. +Otherwise \tcode{\placeholder{pair-or-tuple}\&}. \end{itemize} \pnum From b6e978de8e12e83353da349b65b130a86315c73d Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Thu, 4 Aug 2022 14:52:16 -0700 Subject: [PATCH 206/430] [vector.bool] Fix wording - change "variable template" to "expression" --- source/containers.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index 089dd9a0d6..bae72ea7db 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -9305,9 +9305,9 @@ \begin{itemdescr} \pnum -The variable template +The expression \tcode{\exposid{is-vector-bool-reference}} is \tcode{true} -if \tcode{T} denotes the type \tcode{vector::reference} +if \tcode{T} denotes the type \tcode{vector::\linebreak{}reference} for some type \tcode{Alloc} and \tcode{vector} is not a program-defined specialization. \end{itemdescr} From 3346632bda9a76c1e838431ce31914312c887ae4 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Fri, 5 Aug 2022 12:47:12 -0700 Subject: [PATCH 207/430] [format.syn] Move the specialization of formatter up in the synopsis --- source/utilities.tex | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/utilities.tex b/source/utilities.tex index a186770a56..173b93a931 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -13797,19 +13797,19 @@ size_t formatted_size(const locale& loc, @\exposid{wformat-string}@ fmt, Args&&... args); // \ref{format.formatter}, formatter - // \ref{format.formatter.spec}, formatter specializations template struct formatter; - // \ref{format.range.formatter}, class template \tcode{range_formatter} - template - requires @\libconcept{same_as}@, T> && @\libconcept{formattable}@ - class range_formatter; - + // \ref{format.formatter.spec}, formatter specializations template requires (!@\libconcept{same_as}@>, R>) && @\libconcept{formattable}@, charT> struct formatter; + // \ref{format.range.formatter}, class template \tcode{range_formatter} + template + requires @\libconcept{same_as}@, T> && @\libconcept{formattable}@ + class range_formatter; + // \ref{format.parse.ctx}, class template \tcode{basic_format_parse_context} template class basic_format_parse_context; using format_parse_context = basic_format_parse_context; From 2141dab25c7f6d186d662e0ebe916efcd56843ae Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Fri, 5 Aug 2022 12:51:21 -0700 Subject: [PATCH 208/430] [vector.syn] Drop the superfluous "inline" from is-vector-bool-reference --- source/containers.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/containers.tex b/source/containers.tex index bae72ea7db..eacdcf194b 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -6099,7 +6099,7 @@ template class vector; template - inline constexpr bool @\exposid{is-vector-bool-reference}@ = @\seebelow@; // \expos + constexpr bool @\exposid{is-vector-bool-reference}@ = @\seebelow@; // \expos template requires @\exposid{is-vector-bool-reference}@ struct formatter; From 42a690442a4d2a32e79b0e7c12d98bbd35ed9449 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Tue, 16 Aug 2022 14:14:09 +0100 Subject: [PATCH 209/430] [assoc.format] Add formatting support for flat_{,multi}{map,set}. These additions are part of LWG-Motions 6 and 7 (P0429R9 "flat_map" and P1222R4 "flat_set"). --- source/containers.tex | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index eacdcf194b..dae29df486 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -13041,8 +13041,10 @@ For each of \tcode{map}, \tcode{multimap}, -\tcode{unordered_map}, and +\tcode{unordered_map}, \tcode{unordered_multimap}, +\tcode{flat_map}, and +\tcode{flat_multimap}, the library provides the following formatter specialization where \tcode{\placeholder{map-type}} is the name of the template: @@ -13117,8 +13119,10 @@ For each of \tcode{set}, \tcode{multiset}, -\tcode{unordered_set}, and +\tcode{unordered_set}, \tcode{unordered_multiset}, +\tcode{flat_set}, and +\tcode{flat_multiset}, the library provides the following formatter specialization where \tcode{\placeholder{set-type}} is the name of the template: From 240dba4ed9e0645a7e41cddb02e7244d0db46903 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sun, 31 Jul 2022 21:41:40 +0200 Subject: [PATCH 210/430] P2291R3 Add Constexpr Modifiers to Functions to_chars and from_chars for Integral Types in Header --- source/support.tex | 1 + source/utilities.tex | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/source/support.tex b/source/support.tex index c3b63e53ec..ff2804004b 100644 --- a/source/support.tex +++ b/source/support.tex @@ -591,6 +591,7 @@ #define @\defnlibxname{cpp_lib_complex_udls}@ 201309L // also in \libheader{complex} #define @\defnlibxname{cpp_lib_concepts}@ 202002L // also in \libheader{concepts} #define @\defnlibxname{cpp_lib_constexpr_algorithms}@ 201806L // also in \libheader{algorithm} +#define @\defnlibxname{cpp_lib_constexpr_charconv}@ 202207L // also in \libheader{charconv} #define @\defnlibxname{cpp_lib_constexpr_cmath}@ 202202L // also in \libheader{cmath}, \libheader{cstdlib} #define @\defnlibxname{cpp_lib_constexpr_complex}@ 201711L // also in \libheader{complex} #define @\defnlibxname{cpp_lib_constexpr_dynamic_alloc}@ 201907L // also in \libheader{memory} diff --git a/source/utilities.tex b/source/utilities.tex index 173b93a931..72aeb18ed3 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -13401,7 +13401,7 @@ friend bool operator==(const to_chars_result&, const to_chars_result&) = default; }; - to_chars_result to_chars(char* first, char* last, @\placeholder{integer-type}@ value, int base = 10); + constexpr to_chars_result to_chars(char* first, char* last, @\placeholder{integer-type}@ value, int base = 10); to_chars_result to_chars(char* first, char* last, bool value, int base = 10) = delete; to_chars_result to_chars(char* first, char* last, @\placeholder{floating-point-type}@ value); @@ -13420,8 +13420,8 @@ friend bool operator==(const from_chars_result&, const from_chars_result&) = default; }; - from_chars_result from_chars(const char* first, const char* last, - @\placeholder{integer-type}@& value, int base = 10); + constexpr from_chars_result from_chars(const char* first, const char* last, + @\placeholder{integer-type}@& value, int base = 10); from_chars_result from_chars(const char* first, const char* last, @\placeholder{floating-point-type}@& value, chars_format fmt = chars_format::general); @@ -13490,7 +13490,7 @@ \indexlibraryglobal{to_chars}% \begin{itemdecl} -to_chars_result to_chars(char* first, char* last, @\placeholder{integer-type}@ value, int base = 10); +constexpr to_chars_result to_chars(char* first, char* last, @\placeholder{integer-type}@ value, int base = 10); \end{itemdecl} \begin{itemdescr} @@ -13621,8 +13621,8 @@ \indexlibraryglobal{from_chars}% \begin{itemdecl} -from_chars_result from_chars(const char* first, const char* last, - @\placeholder{integer-type}@&@\itcorr[-1]@ value, int base = 10); +constexpr from_chars_result from_chars(const char* first, const char* last, + @\placeholder{integer-type}@&@\itcorr[-1]@ value, int base = 10); \end{itemdecl} \begin{itemdescr} From 231ba175a6484d5da1ba391d7dc61a3d118f57a9 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sun, 24 Jul 2022 14:25:02 +0200 Subject: [PATCH 211/430] P2302R4 std::ranges::contains --- source/algorithms.tex | 62 +++++++++++++++++++++++++++++++++++++++++++ source/support.tex | 1 + 2 files changed, 63 insertions(+) diff --git a/source/algorithms.tex b/source/algorithms.tex index 04273a3283..ab0b1c63ab 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -695,6 +695,29 @@ constexpr bool none_of(R&& r, Pred pred, Proj proj = {}); } + // \ref{alg.contains}, contains + namespace ranges { + template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class T, class Proj = identity> + requires @\libconcept{indirect_binary_predicate}@, const T*> + constexpr bool contains(I first, S last, const T& value, Proj proj = {}); + template<@\libconcept{input_range}@ R, class T, class Proj = identity> + requires + @\libconcept{indirect_binary_predicate}@, Proj>, const T*> + constexpr bool contains(R&& r, const T& value, Proj proj = {}); + + template<@\libconcept{forward_iterator}@ I1, @\libconcept{sentinel_for}@ S1, + @\libconcept{forward_iterator}@ I2, @\libconcept{sentinel_for}@ S2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@ + constexpr bool contains_subrange(I1 first1, S1 last1, I2 first2, S2 last2, + Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); + template<@\libconcept{forward_range}@ R1, @\libconcept{forward_range}@ R2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@, iterator_t, Pred, Proj1, Proj2> + constexpr bool contains_subrange(R1&& r1, R2&& r2, + Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); + } + // \ref{alg.foreach}, for each template constexpr Function for_each(InputIterator first, InputIterator last, Function f); @@ -3223,6 +3246,45 @@ At most \tcode{last - first} applications of the predicate and any projection. \end{itemdescr} +\rSec2[alg.contains]{Contains} + +\indexlibraryglobal{contains}% +\begin{itemdecl} +template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class T, class Proj = identity> + requires @\libconcept{indirect_binary_predicate}@, const T*> + constexpr bool ranges::contains(I first, S last, const T& value, Proj proj = {}); +template<@\libconcept{input_range}@ R, class T, class Proj = identity> + requires @\libconcept{indirect_binary_predicate}@, Proj>, const T*> + constexpr bool ranges::contains(R&& r, const T& value, Proj proj = {}); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{ranges::find(std::move(first), last, value, proj) != last}. +\end{itemdescr} + +\indexlibraryglobal{contains_subrange}% +\begin{itemdecl} +template<@\libconcept{forward_iterator}@ I1, @\libconcept{sentinel_for}@ S1, + @\libconcept{forward_iterator}@ I2, @\libconcept{sentinel_for}@ S2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@ + constexpr bool ranges::contains_subrange(I1 first1, S1 last1, I2 first2, S2 last2, + Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); +template<@\libconcept{forward_range}@ R1, @\libconcept{forward_range}@ R2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@, iterator_t, Pred, Proj1, Proj2> + constexpr bool ranges::contains_subrange(R1&& r1, R2&& r2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{first2 == last2 || !ranges::search(first1, last1, first2, last2, pred, proj1, proj2).empty()}. +\end{itemdescr} + \rSec2[alg.foreach]{For each} \indexlibraryglobal{for_each}% diff --git a/source/support.tex b/source/support.tex index ff2804004b..ccc0ba2309 100644 --- a/source/support.tex +++ b/source/support.tex @@ -680,6 +680,7 @@ #define @\defnlibxname{cpp_lib_ranges_as_const}@ 202207L // also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_chunk}@ 202202L // also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_chunk_by}@ 202202L // also in \libheader{ranges} +#define @\defnlibxname{cpp_lib_ranges_contains}@ 202207L // also in \libheader{algorithm} #define @\defnlibxname{cpp_lib_ranges_iota}@ 202202L // also in \libheader{numeric} #define @\defnlibxname{cpp_lib_ranges_join_with}@ 202202L // also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_slide}@ 202202L // also in \libheader{ranges} From 58e39f23ab247d56e8a2dc4a6764d1e95d3ca50c Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sun, 24 Jul 2022 20:09:43 +0200 Subject: [PATCH 212/430] P2322R6 ranges::fold --- source/algorithms.tex | 270 ++++++++++++++++++++++++++++++++++++++++++ source/support.tex | 1 + 2 files changed, 271 insertions(+) diff --git a/source/algorithms.tex b/source/algorithms.tex index ab0b1c63ab..1d3f89cbc7 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -642,6 +642,9 @@ template struct in_found_result; + template + struct in_value_result; + template struct out_value_result; } @@ -1215,6 +1218,91 @@ @\libconcept{indirectly_comparable}@, iterator_t, Pred, Proj1, Proj2> constexpr bool ends_with(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); + + // \ref{alg.fold}, fold + template + class @\exposid{flipped}@ { // \expos + F @\exposid{f}@; // \expos + + public: + template requires @\libconcept{invocable}@ + invoke_result_t operator()(T&&, U&&); + }; + + template + concept @\defexposconcept{indirectly-binary-left-foldable-impl}@ = // \expos + @\libconcept{movable}@ && @\libconcept{movable}@ && + @\libconcept{convertible_to}@ && @\libconcept{invocable}@> && + @\libconcept{assignable_from}@>>; + + template + concept @\defexposconcept{indirectly-binary-left-foldable}@ = // \expos + @\libconcept{copy_constructible}@ && @\libconcept{indirectly_readable}@ && + @\libconcept{invocable}@> && + @\libconcept{convertible_to}@>, + decay_t>>> && + @\exposconcept{indirectly-binary-left-foldable-impl}@>>>; + + template + concept @\defexposconcept{indirectly-binary-right-foldable}@ = // \expos + @\exposconcept{indirectly-binary-left-foldable}@<@\exposid{flipped}@, T, I>; + + template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class T, + @\exposconcept{indirectly-binary-left-foldable}@ F> + constexpr auto fold_left(I first, S last, T init, F f); + + template<@\libconcept{input_range}@ R, class T, @\exposconcept{indirectly-binary-left-foldable}@> F> + constexpr auto fold_left(R&& r, T init, F f); + + template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, + @\exposconcept{indirectly-binary-left-foldable}@, I> F> + requires @\libconcept{constructible_from}@, iter_reference_t> + constexpr auto fold_left_first(I first, S last, F f); + + template<@\libconcept{input_range}@ R, @\exposconcept{indirectly-binary-left-foldable}@, iterator_t> F> + requires @\libconcept{constructible_from}@, range_reference_t> + constexpr auto fold_left_first(R&& r, F f); + + template<@\libconcept{bidirectional_iterator}@ I, @\libconcept{sentinel_for}@ S, class T, + @\exposconcept{indirectly-binary-right-foldable}@ F> + constexpr auto fold_right(I first, S last, T init, F f); + + template<@\libconcept{bidirectional_range}@ R, class T, + @\exposconcept{indirectly-binary-right-foldable}@> F> + constexpr auto fold_right(R&& r, T init, F f); + + template <@\libconcept{bidirectional_iterator}@ I, @\libconcept{sentinel_for}@ S, + @\exposconcept{indirectly-binary-right-foldable}@, I> F> + requires @\libconcept{constructible_from}@, iter_reference_t> + constexpr auto fold_right_last(I first, S last, F f); + + template<@\libconcept{bidirectional_range}@ R, + @\exposconcept{indirectly-binary-right-foldable}@, iterator_t> F> + requires @\libconcept{constructible_from}@, range_reference_t> + constexpr auto fold_right_last(R&& r, F f); + + template + using fold_left_with_iter_result = in_value_result; + template + using fold_left_first_with_iter_result = in_value_result; + + template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class T, + @\exposconcept{indirectly-binary-left-foldable}@ F> + constexpr @\seebelow@ fold_left_with_iter(I first, S last, T init, F f); + + template<@\libconcept{input_range}@ R, class T, @\exposconcept{indirectly-binary-left-foldable}@> F> + constexpr @\seebelow@ fold_left_with_iter(R&& r, T init, F f); + + template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, + @\exposconcept{indirectly-binary-left-foldable}@, I> F> + requires @\libconcept{constructible_from}@, iter_reference_t> + constexpr @\seebelow@ fold_left_first_with_iter(I first, S last, F f); + + template<@\libconcept{input_range}@ R, + @\exposconcept{indirectly-binary-left-foldable}@, iterator_t> F> + requires @\libconcept{constructible_from}@, range_reference_t> + constexpr @\seebelow@ fold_left_first_with_iter(R&& r, F f); } // \ref{alg.modifying.operations}, mutating sequence operations @@ -3104,6 +3192,24 @@ } }; + template + struct in_value_result { + [[no_unique_address]] I in; + [[no_unique_address]] T value; + + template + requires @\libconcept{convertible_to}@ && @\libconcept{convertible_to}@ + constexpr operator in_value_result() const & { + return {in, value}; + } + + template + requires @\libconcept{convertible_to}@ && @\libconcept{convertible_to}@ + constexpr operator in_value_result() && { + return {std::move(in), std::move(value)}; + } + }; + template struct out_value_result { [[no_unique_address]] O out; @@ -4518,6 +4624,170 @@ \end{codeblock} \end{itemdescr} +\rSec2[alg.fold]{Fold} + +\indexlibraryglobal{fold_left}% +\begin{itemdecl} +template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class T, @\exposconcept{indirectly-binary-left-foldable}@ F> + constexpr auto ranges::fold_left(I first, S last, T init, F f); +template<@\libconcept{input_range}@ R, class T, @\exposconcept{indirectly-binary-left-foldable}@> F> + constexpr auto ranges::fold_left(R&& r, T init, F f); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\begin{codeblock} +ranges::fold_left_with_iter(std::move(first), last, std::move(init), f).value +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{fold_left_first}% +\begin{itemdecl} +template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, + @\exposconcept{indirectly-binary-left-foldable}@, I> F> + requires @\libconcept{constructible_from}@, iter_reference_t> + constexpr auto ranges::fold_left_first(I first, S last, F f); +template<@\libconcept{input_range}@ R, @\exposconcept{indirectly-binary-left-foldable}@, iterator_t> F> + requires @\libconcept{constructible_from}@, range_reference_t> + constexpr auto ranges::fold_left_first(R&& r, F f); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\begin{codeblock} +ranges::fold_left_first_with_iter(std::move(first), last, f).value +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{fold_right}% +\begin{itemdecl} +template<@\libconcept{bidirectional_iterator}@ I, @\libconcept{sentinel_for}@ S, class T, + @\exposconcept{indirectly-binary-right-foldable}@ F> + constexpr auto ranges::fold_right(I first, S last, T init, F f); +template<@\libconcept{bidirectional_range}@ R, class T, + @\exposconcept{indirectly-binary-right-foldable}@> F> + constexpr auto ranges::fold_right(R&& r, T init, F f); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +using U = decay_t, T>>; +if (first == last) + return U(std::move(init)); +I tail = ranges::next(first, last); +U accum = invoke(f, *--tail, std::move(init)); +while (first != tail) + accum = invoke(f, *--tail, std::move(accum)); +return accum; +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{fold_right_last}% +\begin{itemdecl} +template<@\libconcept{bidirectional_iterator}@ I, @\libconcept{sentinel_for}@ S, + @\exposconcept{indirectly-binary-right-foldable}@, I> F> + requires @\libconcept{constructible_from}@, iter_reference_t> + constexpr auto ranges::fold_right_last(I first, S last, F f); +template<@\libconcept{bidirectional_range}@ R, + @\exposconcept{indirectly-binary-right-foldable}@, iterator_t> F> + requires @\libconcept{constructible_from}@, range_reference_t> + constexpr auto ranges::fold_right_last(R&& r, F f); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{U} be +\tcode{decltype(ranges::fold_right(first, last, iter_value_t(*first), f))}. + +\pnum +\effects +Equivalent to: +\begin{codeblock} +if (first == last) + return optional(); +I tail = ranges::prev(ranges::next(first, std::move(last))); +return optional(in_place, + ranges::fold_right(std::move(first), tail, iter_value_t(*tail), std::move(f))); +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{fold_left_with_iter}% +\begin{itemdecl} +template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class T, + @\exposconcept{indirectly-binary-left-foldable}@ F> + constexpr @\seebelow@ ranges::fold_left_with_iter(I first, S last, T init, F f); +template<@\libconcept{input_range}@ R, class T, @\exposconcept{indirectly-binary-left-foldable}@> F> + constexpr @\seebelow@ ranges::fold_left_with_iter(R&& r, T init, F f); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{U} be \tcode{decay_t>>}. + +\pnum +\effects +Equivalent to: +\begin{codeblock} +if (first == last) + return {std::move(first), U(std::move(init))}; +U accum = invoke(f, std::move(init), *first); +for (++first; first != last; ++first) + accum = invoke(f, std::move(accum), *first); +return {std::move(first), std::move(accum)}; +\end{codeblock} + +\pnum +\remarks +The return type is +\tcode{fold_left_with_iter_result} for the first overload and +\tcode{fold_left_with_iter_result, U>} +for the second overload. +\end{itemdescr} + +\indexlibraryglobal{fold_left_first_with_iter}% +\begin{itemdecl} +template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, + @\exposconcept{indirectly-binary-left-foldable}@, I> F> + requires @\libconcept{constructible_from}@, iter_reference_t> + constexpr @\seebelow@ ranges::fold_left_first_with_iter(I first, S last, F f); +template<@\libconcept{input_range}@ R, @\exposconcept{indirectly-binary-left-foldable}@, iterator_t> F> + requires @\libconcept{constructible_from}@, range_reference_t> + constexpr @\seebelow@ ranges::fold_left_first_with_iter(R&& r, F f); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{U} be +\begin{codeblock} +decltype(ranges::fold_left(std::move(first), last, iter_value_t(*first), f)) +\end{codeblock} + +\pnum +\effects +Equivalent to: +\begin{codeblock} +if (first == last) + return {std::move(first), optional()}; +optional init(in_place, *first); +for (++first; first != last; ++first) + *init = invoke(f, std::move(*init), *first); +return {std::move(first), std::move(init)}; +\end{codeblock} + +\pnum +\remarks +The return type is +\tcode{fold_left_first_with_iter_result>} +for the first overload and +\tcode{fold_left_first_with_iter_result, optional>} +for the second overload. +\end{itemdescr} + \rSec1[alg.modifying.operations]{Mutating sequence operations} \rSec2[alg.copy]{Copy} diff --git a/source/support.tex b/source/support.tex index ccc0ba2309..d0c1397c32 100644 --- a/source/support.tex +++ b/source/support.tex @@ -681,6 +681,7 @@ #define @\defnlibxname{cpp_lib_ranges_chunk}@ 202202L // also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_chunk_by}@ 202202L // also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_contains}@ 202207L // also in \libheader{algorithm} +#define @\defnlibxname{cpp_lib_ranges_fold}@ 202207L // also in \libheader{algorithm} #define @\defnlibxname{cpp_lib_ranges_iota}@ 202202L // also in \libheader{numeric} #define @\defnlibxname{cpp_lib_ranges_join_with}@ 202202L // also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_slide}@ 202202L // also in \libheader{ranges} From b77c526dda683307f1c0048efa0d922eb5dd02e0 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sun, 24 Jul 2022 20:40:31 +0200 Subject: [PATCH 213/430] P2374R4 views::cartesian_product --- source/macros.tex | 3 + source/ranges.tex | 819 ++++++++++++++++++++++++++++++++++++++++++++- source/support.tex | 1 + 3 files changed, 806 insertions(+), 17 deletions(-) diff --git a/source/macros.tex b/source/macros.tex index 84f6ecbf71..9f29cdd9ea 100644 --- a/source/macros.tex +++ b/source/macros.tex @@ -147,6 +147,8 @@ \let\textup\nocode% \let\otcode\tcode% \let\tcode\nocode% +\let\oexposid\exposid% +\let\exposid\nocode% \let\ogrammarterm\grammarterm% \let\grammarterm\nocode% \let\omname\mname% @@ -157,6 +159,7 @@ \let\BreakableUnderscore\textunderscore% \edef\x{#1}% \let\tcode\otcode% +\let\exposid\oexposid% \let\grammarterm\gterm% \let\mname\omname% \let\Cpp\oCpp% diff --git a/source/ranges.tex b/source/ranges.tex index e856c35bb2..e5791ca17f 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -478,7 +478,14 @@ template inline constexpr bool enable_borrowed_range> = enable_borrowed_range; - namespace views { inline constexpr @\unspecnc@ stride = @\unspecnc@; } // freestanding + namespace views { inline constexpr @\unspecnc@ stride = @\unspecnc@; } + + // \ref{range.cartesian}, cartesian product view + template<@\libconcept{input_range}@ First, @\libconcept{forward_range}@... Vs> + requires (@\libconcept{view}@ && ... && @\libconcept{view}@) + class cartesian_product_view; + + namespace views { inline constexpr @\unspecnc@ cartesian_product = @\unspecnc@; } } namespace std { @@ -3764,6 +3771,41 @@ to temporarily cache values as it is iterated over. \end{note} +\rSec2[range.adaptor.tuple]{Range adaptor helpers} + +\begin{codeblock} +namespace std::ranges { + template + using @\exposid{tuple-or-pair}@ = @\seebelow@; // \expos + + template + constexpr auto @\exposid{tuple-transform}@(F&& f, Tuple&& tuple) { // \expos + return apply([&](Ts&&... elements) { + return @\exposid{tuple-or-pair}@...>( + invoke(f, std::forward(elements))... + ); + }, std::forward(tuple)); + } + + template + constexpr void @\exposid{tuple-for-each}@(F&& f, Tuple&& tuple) { // \expos + apply([&](Ts&&... elements) { + (invoke(f, std::forward(elements)), ...); + }, std::forward(tuple)); + } +\end{codeblock} + +\pnum +Given some pack of types \tcode{Ts}, +the alias template \exposid{tuple-or-pair} is defined as follows: +\begin{itemize} +\item +If \tcode{sizeof...(Ts)} is 2, +\tcode{\exposid{tuple-or-pair}} denotes \tcode{pair}. +\item +Otherwise, \tcode{\exposid{tuple-or-pair}} denotes \tcode{tuple}. +\end{itemize} + \rSec2[range.all]{All view} \rSec3[range.all.general]{General} @@ -8761,22 +8803,6 @@ (!(@\libconcept{bidirectional_range}@ && ...) && (@\libconcept{common_range}@ && ...)) || ((@\libconcept{random_access_range}@ && ...) && (@\libconcept{sized_range}@ && ...)); - template - constexpr auto @\exposid{tuple-transform}@(F&& f, Tuple&& tuple) { // \expos - return apply([&](Ts&&... elements) { - return tuple...>( - invoke(f, std::forward(elements))... - ); - }, std::forward(tuple)); - } - - template - constexpr void @\exposid{tuple-for-each}@(F&& f, Tuple&& tuple) { // \expos - apply([&](Ts&&... elements) { - (invoke(f, std::forward(elements)), ...); - }, std::forward(tuple)); - } - template<@\libconcept{input_range}@... Views> requires (@\libconcept{view}@ && ...) && (sizeof...(Views) > 0) class zip_view : public view_interface> { @@ -13603,3 +13629,762 @@ Equivalent to: \tcode{ranges::iter_swap(x.\exposid{current_}, y.\exposid{current_});} \end{itemdescr} + +\rSec2[range.cartesian]{Cartesian product view} + +\rSec3[range.cartesian.overview]{Overview} + +\indexlibraryglobal{cartesian_product_view}% +\pnum +\tcode{cartesian_product_view} takes any non-zero number of ranges $n$ and +produces a view of tuples calculated by +the $n$-ary cartesian product of the provided ranges. + +\pnum +The name \tcode{views::cartesian_product} denotes a customization point object\iref{customization.point.object}. +Given a pack of subexpressions \tcode{Es}, +the expression \tcode{views::cartesian_product(Es...)} +is expression-equivalent to +\begin{itemize} +\item +\tcode{\exposid{decay-copy}(views::empty>)} +if \tcode{Es} is an empty pack, +\item +otherwise, +\tcode{cartesian_product_view...>(Es...)}. +\end{itemize} + +\pnum +\begin{example} +\begin{codeblock} +std::vector v { 0, 1, 2 }; +for (auto&& [a,b,c] : std::views::cartesian_product(v, v, v)) { + std::cout << a << ' ' << b << ' ' << c << '\n'; + // 0 0 0 + // 0 0 1 + // 0 0 2 + // 0 1 0 + // 0 1 1 + // ... +} +\end{codeblock} +\end{example} + +\rSec3[range.cartesian.view]{Class template \tcode{cartesian_product_view}} + +\begin{codeblock} +namespace std::ranges { + template + concept @\defexposconcept{cartesian-product-is-random-access}@ = // \expos + (@\libconcept{random_access_range}@<@\exposid{maybe-const}@> && ... && + (@\libconcept{random_access_range}@<@\exposid{maybe-const}@> + && @\libconcept{sized_range}@<@\exposid{maybe-const}@>)); + + template + concept @\defexposconcept{cartesian-product-common-arg}@ = // \expos + @\libconcept{common_range}@ || (@\libconcept{sized_range}@ && @\libconcept{random_access_range}@); + + template + concept @\defexposconcept{cartesian-product-is-bidirectional}@ = // \expos + (@\libconcept{bidirectional_range}@<@\exposid{maybe-const}@> && ... && + (@\libconcept{bidirectional_range}@<@\exposid{maybe-const}@> + && @\exposconcept{cartesian-product-common-arg}@<@\exposid{maybe-const}@>)); + + template + concept @\defexposconcept{cartesian-product-is-common}@ = // \expos + @\exposconcept{cartesian-product-common-arg}@>; + + template + concept @\defexposconcept{cartesian-product-is-sized}@ = // \expos + (@\libconcept{sized_range}@ && ...); + + template class FirstSent, class First, class... Vs> + concept @\defexposconcept{cartesian-is-sized-sentinel}@ = // \expos + (@\libconcept{sized_sentinel_for}@, + iterator_t<@\exposid{maybe-const}@> && ... + && (@\libconcept{sized_range}@<@\exposid{maybe-const}@> + && @\libconcept{sized_sentinel_for}@>, + iterator_t<@\exposid{maybe-const}@>>)); + + template<@\exposconcept{cartesian-product-common-arg}@ R> + constexpr auto @\exposid{cartesian-common-arg-end}@(R& r) { // \expos + if constexpr (@\libconcept{common_range}@) { + return ranges::end(r); + } else { + return ranges::begin(r) + ranges::distance(r); + } + } + + template<@\libconcept{input_range}@ First, @\libconcept{forward_range}@... Vs> + requires (@\libconcept{view}@ && ... && @\libconcept{view}@) + class cartesian_product_view : public view_interface> { + private: + tuple @\exposid{bases_}@; // \expos + // \ref{ranges.cartesian.iterator}, class template \tcode{cartesian_product_view::\exposid{iterator}} + template class @\exposid{iterator}@; // \expos + public: + constexpr cartesian_product_view() = default; + constexpr explicit cartesian_product_view(First first_base, Vs... bases); + + constexpr @\exposid{iterator}@ begin() + requires (!@\exposconcept{simple-view}@ || ... || !@\exposconcept{simple-view}@); + constexpr @\exposid{iterator}@ begin() const + requires (@\libconcept{range}@ && ... && @\libconcept{range}@); + + constexpr @\exposid{iterator}@ end() + requires ((!@\exposconcept{simple-view}@ || ... || !@\exposconcept{simple-view}@) && + @\exposconcept{cartesian-product-is-common}@); + constexpr @\exposid{iterator}@ end() const + requires @\exposconcept{cartesian-product-is-common}@; + constexpr default_sentinel_t end() const noexcept; + + constexpr @\seebelow@ size() + requires @\exposconcept{cartesian-product-is-sized}@; + constexpr @\seebelow@ size() const + requires @\exposconcept{cartesian-product-is-sized}@; + }; + + template + cartesian_product_view(Vs&&...) -> cartesian_product_view...>; +} +\end{codeblock} + +\begin{itemdecl} +constexpr explicit cartesian_product_view(First first_base, Vs... bases); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \exposid{bases_} +with \tcode{std::move(first_base), std::move(bases)...}. +\end{itemdescr} + +\begin{itemdecl} +constexpr @\exposid{iterator}@ begin() + requires (!@\exposconcept{simple-view}@ || ... || !@\exposconcept{simple-view}@); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\tcode{return \exposid{iterator}(\exposid{tuple-transform}(ranges::begin, \exposid{bases_}));} +\end{itemdescr} + +\begin{itemdecl} +constexpr @\exposid{iterator}@ begin() const + requires (@\libconcept{range}@ && ... && @\libconcept{range}@); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\tcode{return \exposid{iterator}(\exposid{tuple-transform}(ranges::begin, \exposid{bases_}));} +\end{itemdescr} + +\begin{itemdecl} +constexpr @\exposid{iterator}@ end() + requires ((!@\exposconcept{simple-view}@ || ... || !@\exposconcept{simple-view}@) + && @\exposconcept{cartesian-product-is-common}@); +constexpr @\exposid{iterator}@ end() const + requires @\exposconcept{cartesian-product-is-common}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let: +\begin{itemize} +\item +\exposid{is-const} be \tcode{true} for the const-qualified overload, and +\tcode{false} otherwise; +\item +\exposid{is-empty} be \tcode{true} +if the expression \tcode{ranges::empty(rng)} is \tcode{true} +for any \tcode{rng} among the underlying ranges except the first one and +\tcode{false} otherwise; and +\item +\tcode{\exposid{begin-or-first-end}(rng)} be expression-equivalent to +\tcode{\exposid{is-empty} ? ranges::begin(rng) : \exposid{cartesian-common-arg-end}(rng)} +if \tcode{rng} is the first underlying range and +\tcode{ranges::begin(rng)} otherwise. +\end{itemize} + +\pnum +\effects +Equivalent to: +\begin{codeblock} +@\exposid{iterator}@ it(@\exposid{tuple-transform}@( + [](auto& rng){ return @\exposid{begin-or-first-end}@(rng); }, @\exposid{bases_}@)); +return it; +\end{codeblock} +\end{itemdescr} + +\begin{itemdecl} +constexpr default_sentinel_t end() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{default_sentinel}. +\end{itemdescr} + +\begin{itemdecl} +constexpr @\seebelow@ size() + requires @\exposconcept{cartesian-product-is-sized}@; +constexpr @\seebelow@ size() const + requires @\exposconcept{cartesian-product-is-sized}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +The return type is an \impldef{return type of \tcode{cartesian_product_view::size}} unsigned-integer-like type. + +\pnum +\recommended +The return type should be the smallest unsigned-integer-like type +that is sufficiently wide to store the product of the maximum sizes of +all the underlying ranges, if such a type exists. + +\pnum +Let $p$ be the product of the sizes of all the ranges in \tcode{bases_}. + +\pnum +\expects +$p$ can be represented by the return type. + +\pnum +\returns +$p$. +\end{itemdescr} + +\rSec3[ranges.cartesian.iterator]{Class template \tcode{cartesian_product_view::\exposid{iterator}}} + +\begin{codeblock} +namespace std::ranges { + template<@\libconcept{input_range}@ First, @\libconcept{forward_range}@... Vs> + requires (@\libconcept{view}@ && ... && @\libconcept{view}@) + template + class cartesian_product_view::@\exposid{iterator}@ { + public: + using iterator_category = input_iterator_tag; + using iterator_concept = @\seebelow@; + using value_type = @\exposid{tuple-or-pair}@>, + range_value_t<@\exposid{maybe-const}@>...>; + using reference = @\exposid{tuple-or-pair}@>, + reference_t<@\exposid{maybe-const}@>...>; + using difference_type = @\seebelow@; + + @\exposid{iterator}@() requires @\libconcept{forward_range}@<@\exposid{maybe-const}@> = default; + + constexpr @\exposid{iterator}@(@\exposid{iterator}@ i) requires Const && + (@\libconcept{convertible_to}@, iterator_t<@\exposid{maybe-const}@>> && + ... && @\libconcept{convertible_to}@, iterator_t<@\exposid{maybe-const}@>>); + + constexpr auto operator*() const; + constexpr @\exposid{iterator}@& operator++(); + constexpr void operator++(int); + constexpr @\exposid{iterator}@ operator++(int) requires @\libconcept{forward_range}@<@\exposid{maybe-const}@>; + + constexpr @\exposid{iterator}@& operator--() + requires @\exposconcept{cartesian-product-is-bidirectional}@; + constexpr @\exposid{iterator}@ operator--(int) + requires @\exposconcept{cartesian-product-is-bidirectional}@; + + constexpr @\exposid{iterator}@& operator+=(difference_type x) + requires @\exposconcept{cartesian-product-is-random-access}@; + constexpr @\exposid{iterator}@& operator-=(difference_type x) + requires @\exposconcept{cartesian-product-is-random-access}@; + + constexpr reference operator[](difference_type n) const + requires @\exposconcept{cartesian-product-is-random-access}@; + + friend constexpr bool operator==(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) + requires @\libconcept{equality_comparable}@>>; + + friend constexpr bool operator==(const @\exposid{iterator}@& x, default_sentinel_t); + + friend constexpr auto operator<=>(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) + requires @\exposconcept{all-random-access}@; + + friend constexpr @\exposid{iterator}@ operator+(const @\exposid{iterator}@& x, difference_type y) + requires @\exposconcept{cartesian-product-is-random-access}@; + friend constexpr @\exposid{iterator}@ operator+(difference_type x, const @\exposid{iterator}@& y) + requires @\exposconcept{cartesian-product-is-random-access}@; + friend constexpr @\exposid{iterator}@ operator-(const @\exposid{iterator}@& x, difference_type y) + requires @\exposconcept{cartesian-product-is-random-access}@; + friend constexpr difference_type operator-(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) + requires @\exposconcept{cartesian-is-sized-sentinel}@; + + friend constexpr difference_type operator-(@\exposid{iterator}@ i, default_sentinel_t) + requires @\exposconcept{cartesian-is-sized-sentinel}@; + friend constexpr difference_type operator-(default_sentinel_t, @\exposid{iterator}@ i) + requires @\exposconcept{cartesian-is-sized-sentinel}@; + + friend constexpr auto iter_move(const @\exposid{iterator}@& i) noexcept(@\seebelow@); + + friend constexpr void iter_swap(const @\exposid{iterator}@& l, const @\exposid{iterator}@& r) noexcept(@\seebelow@) + requires (@\libconcept{indirectly_swappable}@>> && ... && + @\libconcept{indirectly_swappable}@>>); + + private: + @\exposid{maybe-const}@* @\exposid{parent_}@ = nullptr; // \expos + @\exposid{tuple-or-pair}@>, + iterator_t<@\exposid{maybe-const}@>...> @\exposid{current_}@; // \expos + + template + constexpr void @\exposid{next}@(); // \expos + + template + constexpr void @\exposid{prev}@(); // \expos + + template + constexpr difference_type @\exposid{distance-from}@(Tuple t); // \expos + + constexpr explicit @\exposid{iterator}@(@\exposid{tuple-or-pair}@>, + iterator_t<@\exposid{maybe-const}@>...> current); // \expos + }; +} +\end{codeblock} + +\pnum +\tcode{\exposid{iterator}::iterator_concept} is defined as follows: +\begin{itemize} +\item +If \tcode{\exposconcept{cartesian-product-is-random-access}} +is modeled, +then \tcode{iterator_con\-cept} denotes \tcode{random_access_iterator_tag}. +\item +Otherwise, +if \tcode{\exposconcept{cartesian-product-is-bidirectional}} +is modeled, +then \tcode{it\-erator_concept} denotes \tcode{bidirectional_iterator_tag}. +\item +Otherwise, +if \tcode{\exposid{maybe-const}} models \libconcept{forward_range}, +then \tcode{iterator_concept} denotes \tcode{forward_iterator_tag}. +\item +Otherwise, \tcode{iterator_concept} denotes \tcode{input_iterator_tag}. +\end{itemize} + +\pnum +\tcode{\exposid{iterator}::difference_type} is +an \impldef{type of \tcode{ranges::cartesian_product_view::\exposid{iterator}::difference_type}} +signed-integer-like type. + +\pnum +\recommended +\tcode{\exposid{iterator}::difference_type} should be +the smallest signed-integer-like type +that is sufficiently wide to store +the product of the maximum sizes of all underlying ranges +if such a type exists. + +\pnum +\begin{itemdecl} +template + constexpr void @\exposid{next}@(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto& it = std::get(@\exposid{current_}@); +++it; +if constexpr (N > 0) { + if (it == ranges::end(std::get(@\exposid{parent_}@->@\exposid{bases_}@))) { + it = ranges::begin(std::get(@\exposid{parent_}@->@\exposid{bases_}@)); + @\exposid{next}@(); + } +} +\end{codeblock} +\end{itemdescr} + +\begin{itemdecl} +template + constexpr void @\exposid{prev}@(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto& it = std::get(@\exposid{current_}@); +if (it == ranges::begin(std::get(@\exposid{parent_}@->@\exposid{bases_}@))) { + it = @\exposid{cartesian-common-arg-end}@(std::get(@\exposid{parent_}@->@\exposid{bases_}@)); + if constexpr (N > 0) { + @\exposid{prev}@(); + } +} +--it; +\end{codeblock} +\end{itemdescr} + +\begin{itemdecl} +template + constexpr difference_type @\exposid{distance-from}@(Tuple t); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let: +\begin{itemize} +\item +$\exposid{scaled-size}(N)$ be the product of +\tcode{static_cast(ranges::size(std::get<\brk{}$N$>(\exposid{parent_}->\exposid{bases_})))} and +$\exposid{scaled-size}(N+1)$ +if $N < \tcode{sizeof...(Vs)}$, otherwise \tcode{static_cast(1)}; +\item +$\exposid{scaled-distance}(N)$ be the product of +\tcode{static_cast(std::get<$N$>(\exposid{cur\-rent_}) - std::get<$N$>(t))} and $\exposid{scaled-size}(N+1)$; and +\item +\exposid{scaled-sum} be the sum of $\exposid{scaled-distance}(N)$ +for every integer $0 \le N \le \tcode{sizeof...(Vs)}$. +\end{itemize} + +\pnum +\expects +\exposid{scaled-sum} can be represented by \tcode{difference_type}. + +\pnum +\returns +\exposid{scaled-sum}. +\end{itemdescr} + +\begin{itemdecl} +constexpr explicit @\exposid{iterator}@(@\exposid{tuple-or-pair}@>, + iterator_t>...> current); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \exposid{current_} with \tcode{std::move(current)}. +\end{itemdescr} + +\begin{itemdecl} +constexpr @\exposid{iterator}@(@\exposid{iterator}@ i) requires Const && + (@\libconcept{convertible_to}@, iterator_t<@\exposid{maybe-const}@>> && + ... && @\libconcept{convertible_to}@, iterator_t<@\exposid{maybe-const}@>>); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \exposid{current_} with \tcode{std::move(i.\exposid{current_})}. +\end{itemdescr} + +\begin{itemdecl} +constexpr auto operator*() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return @\exposid{tuple-transform}@([](auto& i) -> decltype(auto) { return *i; }, @\exposid{current_}@); +\end{codeblock} +\end{itemdescr} + +\begin{itemdecl} +constexpr @\exposid{iterator}@& operator++(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +@\exposid{next}@(); +return *this; +\end{codeblock} +\end{itemdescr} + +\begin{itemdecl} +constexpr void operator++(int); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{++*this}. +\end{itemdescr} + +\begin{itemdecl} +constexpr @\exposid{iterator}@ operator++(int) requires @\libconcept{forward_range}@<@\exposid{maybe-const}@>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto tmp = *this; +++*this; +return tmp; +\end{codeblock} +\end{itemdescr} + +\begin{itemdecl} +constexpr @\exposid{iterator}@& operator--() + requires @\exposconcept{cartesian-product-is-bidirectional}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +@\exposid{prev}@(); +return *this; +\end{codeblock} +\end{itemdescr} + +\begin{itemdecl} +constexpr @\exposid{iterator}@ operator--(int) + requires @\exposconcept{cartesian-product-is-bidirectional}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto tmp = *this; +--*this; +return tmp; +\end{codeblock} +\end{itemdescr} + +\begin{itemdecl} +constexpr @\exposid{iterator}@& operator+=(difference_type x) + requires @\exposconcept{cartesian-product-is-random-access}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{orig} be the value of \tcode{*this} before the call. + +Let \tcode{ret} be: +\begin{itemize} +\item +If \tcode{x > 0}, +the value of \tcode{*this} had \exposid{next} been called \tcode{x} times. +\item +Otherwise, if \tcode{x < 0}, +the value of \tcode{*this} had \exposid{prev} been called \tcode{-x} times. +\item +Otherwise, \tcode{orig}. +\end{itemize} + +\pnum +\expects +\tcode{x} is in the range +$[\tcode{ranges::distance(*this, ranges::begin(*\exposid{parent_}))},$\newline +$\tcode{ranges::distance(*this, ranges::end(*\exposid{parent_}))}]$. + +\pnum +\effects +Sets the value of \tcode{*this} to \tcode{ret}. + +\pnum +\returns +\tcode{*this}. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\begin{itemdecl} +constexpr @\exposid{iterator}@& operator-=(difference_type x) + requires @\exposconcept{cartesian-product-is-random-access}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +*this += -x; +return *this; +\end{codeblock} +\end{itemdescr} + +\begin{itemdecl} +constexpr reference operator[](difference_type n) const + requires @\exposconcept{cartesian-product-is-random-access}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return *((*this) + n);} +\end{itemdescr} + +\begin{itemdecl} +friend constexpr bool operator==(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) + requires \libconcept{equality_comparable}>>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return x.\exposid{current_} == y.\exposid{current_};} +\end{itemdescr} + +\begin{itemdecl} +friend constexpr bool operator==(const @\exposid{iterator}@& x, default_sentinel_t); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{std::get<$i$>(x.\exposid{current_}) == ranges::end(std::get<$i$>(x.\exposid{parent_}->\exposid{bases_}))} +is \tcode{true} +for any integer $0 \le i \le \tcode{sizeof...(Vs)}$; +otherwise, \tcode{false}. +\end{itemdescr} + +\begin{itemdecl} +friend constexpr auto operator<=>(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) + requires @\exposconcept{all-random-access}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return x.\exposid{current_} <=> y.\exposid{current_};} +\end{itemdescr} + +\begin{itemdecl} +friend constexpr @\exposid{iterator}@ operator+(const @\exposid{iterator}@& x, difference_type y) + requires @\exposconcept{cartesian-product-is-random-access}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return \exposid{iterator}(x) += y;} +\end{itemdescr} + +\begin{itemdecl} +friend constexpr @\exposid{iterator}@ operator+(difference_type x, const @\exposid{iterator}@& y) + requires @\exposconcept{cartesian-product-is-random-access}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return y + x;} +\end{itemdescr} + +\begin{itemdecl} +friend constexpr @\exposid{iterator}@ operator-(const @\exposid{iterator}@& x, difference_type y) + requires @\exposconcept{cartesian-product-is-random-access}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return \exposid{iterator}(x) -= y;} +\end{itemdescr} + +\begin{itemdecl} +friend constexpr difference_type operator-(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) + requires @\exposconcept{cartesian-is-sized-sentinel}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return x.\exposid{distance-from}(y.\exposid{current_});} +\end{itemdescr} + +\begin{itemdecl} +friend constexpr difference_type operator-(@\exposid{iterator}@ i, default_sentinel_t) + requires @\exposconcept{cartesian-is-sized-sentinel}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \exposid{end-tuple} be an object of a type +that is a specialization of \tcode{tuple}, such that: +\begin{itemize} +\item +\tcode{std::get<0>(\exposid{end-tuple})} has the same value as +\tcode{ranges::end(std::get<0>(i.\exposid{parent_}->\exposid{ba\-ses_}))}; +\item +\tcode{std::get<$N$>(\exposid{end-tuple})} has the same value as +\tcode{ranges::begin(std::get<$N$>(i.\exposid{parent_}->\exposid{bases_}))} +for every integer $1 \le N \le \tcode{sizeof...(Vs)}$. +\end{itemize} + +\pnum +\effects +Equivalent to: \tcode{return i.\exposid{distance-from}(\exposid{end-tuple});} +\end{itemdescr} + +\begin{itemdecl} +friend constexpr difference_type operator-(default_sentinel_t s, @\exposid{iterator}@ i) + requires @\exposconcept{cartesian-is-sized-sentinel}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return -(i - s);} +\end{itemdescr} + +\begin{itemdecl} +friend constexpr auto iter_move(const @\exposid{iterator}@& i) noexcept(@\seebelow@); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return \exposid{tuple-transform}(ranges::iter_move, i.\exposid{current_});} + +\pnum +\remarks +The exception specification is equivalent to +the logical AND of the following expressions: +\begin{itemize} +\item +\tcode{noexcept(ranges::iter_move(std::get<$N$>(i.\exposid{current_}))} +for every integer\newline $0 \le N \le \tcode{sizeof...(Vs)}$, +\item +\tcode{is_nothrow_move_constructible_v>>}\newline +for every type \tcode{T} in \tcode{F, Vs...}. +\end{itemize} +\end{itemdescr} + +\begin{itemdecl} +friend constexpr void iter_swap(const @\exposid{iterator}@& l, const @\exposid{iterator}@& r) noexcept(@\seebelow@) + requires (@\libconcept{indirectly_swappable}@>> && ... && + @\libconcept{indirectly_swappable}@>>); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +For every integer $0 \le i \le \tcode{sizeof...(Vs)}$, performs: +\begin{codeblock} +ranges::iter_swap(std::get<@$i$@>(l.@\exposid{current_}@), std::get<@$i$@>(r.@\exposid{current_}@)) +\end{codeblock} + +\pnum +\remarks +The exception specification is equivalent to the logical AND of the following expressions: +\begin{itemize} +\item +\tcode{noexcept(ranges::iter_swap(std::get<$i$>(l.\exposid{current_}), std::get<$i$>(r.\exposid{current_})))} +for\newline every integer $0 \le i \le \tcode{sizeof...(Vs)}$. +\end{itemize} +\end{itemdescr} diff --git a/source/support.tex b/source/support.tex index d0c1397c32..0cd26e7b0b 100644 --- a/source/support.tex +++ b/source/support.tex @@ -678,6 +678,7 @@ #define @\defnlibxname{cpp_lib_ranges}@ 202202L // also in \libheader{algorithm}, \libheader{functional}, \libheader{iterator}, \libheader{memory}, \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_as_const}@ 202207L // also in \libheader{ranges} +#define @\defnlibxname{cpp_lib_ranges_cartesian_product}@ 202207L // also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_chunk}@ 202202L // also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_chunk_by}@ 202202L // also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_contains}@ 202207L // also in \libheader{algorithm} From d899065cc9cb44e87919803657f55fe7a57110e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Wed, 17 Aug 2022 00:34:49 +0100 Subject: [PATCH 214/430] [range.cartesian] Replace "tuple-or-pair" with "tuple". These changes are part of LWG-Motion 12 (P2165R4, "Compatibility between tuple and tuple-like objects"). --- source/ranges.tex | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index e5791ca17f..3731b8a042 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -13871,9 +13871,9 @@ public: using iterator_category = input_iterator_tag; using iterator_concept = @\seebelow@; - using value_type = @\exposid{tuple-or-pair}@>, + using value_type = tuple>, range_value_t<@\exposid{maybe-const}@>...>; - using reference = @\exposid{tuple-or-pair}@>, + using reference = tuple>, reference_t<@\exposid{maybe-const}@>...>; using difference_type = @\seebelow@; @@ -13931,7 +13931,7 @@ private: @\exposid{maybe-const}@* @\exposid{parent_}@ = nullptr; // \expos - @\exposid{tuple-or-pair}@>, + tuple>, iterator_t<@\exposid{maybe-const}@>...> @\exposid{current_}@; // \expos template @@ -13943,7 +13943,7 @@ template constexpr difference_type @\exposid{distance-from}@(Tuple t); // \expos - constexpr explicit @\exposid{iterator}@(@\exposid{tuple-or-pair}@>, + constexpr explicit @\exposid{iterator}@(tuple>, iterator_t<@\exposid{maybe-const}@>...> current); // \expos }; } @@ -14057,7 +14057,7 @@ \end{itemdescr} \begin{itemdecl} -constexpr explicit @\exposid{iterator}@(@\exposid{tuple-or-pair}@>, +constexpr explicit @\exposid{iterator}@(tuple>, iterator_t>...> current); \end{itemdecl} From e64feeaedf3324bc1f56cf7cf860408e8b34a696 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Tue, 2 Aug 2022 23:17:31 +0200 Subject: [PATCH 215/430] P2540R1 Empty Product for certain Views --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index 3731b8a042..a400deae14 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -13647,7 +13647,7 @@ is expression-equivalent to \begin{itemize} \item -\tcode{\exposid{decay-copy}(views::empty>)} +\tcode{views::single(tuple())} if \tcode{Es} is an empty pack, \item otherwise, From f2cd12dbef5e0d52fa92cf89ac31d9ed0efa8924 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Wed, 3 Aug 2022 09:49:19 +0200 Subject: [PATCH 216/430] P2404R3 Move-only types for equality_comparable_with, totally_ordered_with, and three_way_comparable_with --- source/compatibility.tex | 27 ++++++++++++ source/concepts.tex | 89 ++++++++++++++++++++++++++++++++-------- source/support.tex | 17 +++++--- 3 files changed, 111 insertions(+), 22 deletions(-) diff --git a/source/compatibility.tex b/source/compatibility.tex index ab1ca5cd5d..3f1bcd7c11 100644 --- a/source/compatibility.tex +++ b/source/compatibility.tex @@ -133,6 +133,33 @@ Valid \CppXX{} code that \tcode{\#include}{s} headers with these names may be invalid in this revision of \Cpp{}. +\rSec2[diff.cpp20.concepts]{\ref{concepts}: concepts library} + +\diffref{cmp.concept,concept.equalitycomparable,concept.totallyordered} +\change +Replace \tcode{common_reference_with} in \tcode{three_way_comparable_with}, +\tcode{equality_comparable_with}, and \tcode{totally_ordered_with} +with an exposition-only concept. +\rationale +Allow uncopyable, but movable, types to model these concepts. +\effect +Valid \CppXX{} code relying on subsumption +with \tcode{common_reference_with} +may fail to compile in this revision of \Cpp{}. For example: +\begin{codeblock} +template + requires @\libconcept{equality_comparable_with}@ +bool attempted_equals(const T&, const U& u); // previously selected overload + +template + requires @\libconcept{common_reference_with}@&, const remove_reference_t&> +bool attempted_equals(const T& t, const U& u); // ambiguous overload; previously + // rejected by partial ordering +bool test(shared_ptr p) { + return attempted_equals(p, nullptr); // ill-formed; previously well-formed +} +\end{codeblock} + \rSec2[diff.cpp20.utilities]{\ref{utilities}: general utilities library} \diffref{format} diff --git a/source/concepts.tex b/source/concepts.tex index 0cf400e29e..801cb8ec57 100644 --- a/source/concepts.tex +++ b/source/concepts.tex @@ -849,6 +849,16 @@ Subclause \ref{concepts.compare} describes concepts that establish relationships and orderings on values of possibly differing object types. +\pnum +Given an expression \tcode{E} and a type \tcode{C}, +let \tcode{\exposid{CONVERT_TO_LVALUE}(E)} be: +\begin{itemize} +\item +\tcode{static_cast(as_const(E))} if that is a valid expression, and +\item +\tcode{static_cast(std::move(E))} otherwise. +\end{itemize} + \rSec2[concept.booleantestable]{Boolean testability} \pnum @@ -985,6 +995,42 @@ model \exposconcept{boolean-testable}. \end{example} +\rSec2[concept.comparisoncommontype]{Comparison common types} + +\begin{itemdecl} +template> + concept @\defexposconcept{comparison-common-type-with-impl}@ = // \expos + @\libconcept{same_as}@, + common_reference_t> && + requires { + requires @\libconcept{convertible_to}@ || @\libconcept{convertible_to}@; + requires @\libconcept{convertible_to}@ || @\libconcept{convertible_to}@; + }; + +template + concept @\defexposconcept{comparison-common-type-with}@ = // \expos + @\exposconcept{comparison-common-type-with-impl}@, remove_cvref_t>; +\end{itemdecl} + +\pnum +Let \tcode{C} be \tcode{common_reference_t}. +Let \tcode{t1} and \tcode{t2} be equality-preserving expressions +that are lvalues of type \tcode{remove_cvref_t}, and +let \tcode{u1} and \tcode{u2} be equality-preserving expressions +that are lvalues of type \tcode{remove_cvref_t}. +\tcode{T} and \tcode{U} model +\tcode{\exposconcept{comparison-common-type-with}} only if: +\begin{itemize} +\item +\tcode{\exposid{CONVERT_TO_LVALUE}(t1)} equals +\tcode{\exposid{CONVERT_TO_LVALUE}(t2)} +if and only if \tcode{t1} equals \tcode{t2}, and +\item +\tcode{\exposid{CONVERT_TO_LVALUE}(u1)} equals +\tcode{\exposid{CONVERT_TO_LVALUE}(u2)} +if and only if \tcode{u1} equals \tcode{u2} +\end{itemize} + \rSec2[concept.equalitycomparable]{Concept \cname{equality_comparable}} \begin{itemdecl} @@ -1039,7 +1085,7 @@ template concept @\deflibconcept{equality_comparable_with}@ = @\libconcept{equality_comparable}@ && @\libconcept{equality_comparable}@ && - @\libconcept{common_reference_with}@&, const remove_reference_t&> && + @\exposconcept{comparison-common-type-with}@ && @\libconcept{equality_comparable}@< common_reference_t< const remove_reference_t&, @@ -1050,15 +1096,21 @@ \begin{itemdescr} \pnum Given types \tcode{T} and \tcode{U}, -let \tcode{t} be an lvalue of type \tcode{const remove_reference_t}, -\tcode{u} be an lvalue of type \tcode{const remove_reference_t}, -and \tcode{C} be: +let \tcode{t} and \tcode{t2} be lvalues +denoting distinct equal objects of types \tcode{const remove_reference_t} and +\tcode{remove_cvref_t}, respectively, +let \tcode{u} and \tcode{u2} be lvalues +denoting distinct equal objects of types \tcode{const remove_reference_t} and +\tcode{remove_cvref_t}, respectively, and +let \tcode{C} be: \begin{codeblock} common_reference_t&, const remove_reference_t&> \end{codeblock} \tcode{T} and \tcode{U} model \tcode{\libconcept{equality_comparable_with}} only if -\tcode{bool(t == u) == bool(C(t) == C(u))}. +\begin{codeblock} +bool(t == u) == bool(@\exposid{CONVERT_TO_LVALUE}@(t2) == @\exposid{CONVERT_TO_LVALUE}@(u2)) +\end{codeblock} \end{itemdescr} \rSec2[concept.totallyordered]{Concept \cname{totally_ordered}} @@ -1101,24 +1153,27 @@ \begin{itemdescr} \pnum Given types \tcode{T} and \tcode{U}, -let \tcode{t} be an lvalue of type \tcode{const remove_reference_t}, -\tcode{u} be an lvalue of type \tcode{const remove_reference_t}, -and \tcode{C} be: +let \tcode{t} and \tcode{t2} be lvalues +denoting distinct equal objects of types \tcode{const remove_reference_t} and +\tcode{remove_cvref_t}, respectively, +let \tcode{u} and \tcode{u2} be lvalues +denoting distinct equal objects of types \tcode{const remove_reference_t} and +\tcode{remove_cvref_t}, respectively, and +let \tcode{C} be: \begin{codeblock} common_reference_t&, const remove_reference_t&> \end{codeblock} \tcode{T} and \tcode{U} model \tcode{\libconcept{totally_ordered_with}} only if - \begin{itemize} -\item \tcode{bool(t < u) == bool(C(t) < C(u)).} -\item \tcode{bool(t > u) == bool(C(t) > C(u)).} -\item \tcode{bool(t <= u) == bool(C(t) <= C(u)).} -\item \tcode{bool(t >= u) == bool(C(t) >= C(u)).} -\item \tcode{bool(u < t) == bool(C(u) < C(t)).} -\item \tcode{bool(u > t) == bool(C(u) > C(t)).} -\item \tcode{bool(u <= t) == bool(C(u) <= C(t)).} -\item \tcode{bool(u >= t) == bool(C(u) >= C(t)).} +\item \tcode{bool(t < u) == bool(\exposid{CONVERT_TO_LVALUE}(t2) < \exposid{CONVERT_TO_LVALUE}(u2))}. +\item \tcode{bool(t > u) == bool(\exposid{CONVERT_TO_LVALUE}(t2) > \exposid{CONVERT_TO_LVALUE}(u2))}. +\item \tcode{bool(t <= u) == bool(\exposid{CONVERT_TO_LVALUE}(t2) <= \exposid{CONVERT_TO_LVALUE}(u2))}. +\item \tcode{bool(t >= u) == bool(\exposid{CONVERT_TO_LVALUE}(t2) >= \exposid{CONVERT_TO_LVALUE}(u2))}. +\item \tcode{bool(u < t) == bool(\exposid{CONVERT_TO_LVALUE}(u2) < \exposid{CONVERT_TO_LVALUE}(t2))}. +\item \tcode{bool(u > t) == bool(\exposid{CONVERT_TO_LVALUE}(u2) > \exposid{CONVERT_TO_LVALUE}(t2))}. +\item \tcode{bool(u <= t) == bool(\exposid{CONVERT_TO_LVALUE}(u2) <= \exposid{CONVERT_TO_LVALUE}(t2))}. +\item \tcode{bool(u >= t) == bool(\exposid{CONVERT_TO_LVALUE}(u2) >= \exposid{CONVERT_TO_LVALUE}(t2))}. \end{itemize} \end{itemdescr} diff --git a/source/support.tex b/source/support.tex index 0cd26e7b0b..06063893b1 100644 --- a/source/support.tex +++ b/source/support.tex @@ -589,7 +589,7 @@ #define @\defnlibxname{cpp_lib_chrono_udls}@ 201304L // also in \libheader{chrono} #define @\defnlibxname{cpp_lib_clamp}@ 201603L // also in \libheader{algorithm} #define @\defnlibxname{cpp_lib_complex_udls}@ 201309L // also in \libheader{complex} -#define @\defnlibxname{cpp_lib_concepts}@ 202002L // also in \libheader{concepts} +#define @\defnlibxname{cpp_lib_concepts}@ 202207L // also in \libheader{concepts}, \libheader{compare} #define @\defnlibxname{cpp_lib_constexpr_algorithms}@ 201806L // also in \libheader{algorithm} #define @\defnlibxname{cpp_lib_constexpr_charconv}@ 202207L // also in \libheader{charconv} #define @\defnlibxname{cpp_lib_constexpr_cmath}@ 202202L // also in \libheader{cmath}, \libheader{cstdlib} @@ -4830,7 +4830,7 @@ concept @\deflibconcept{three_way_comparable_with}@ = @\libconcept{three_way_comparable}@ && @\libconcept{three_way_comparable}@ && - @\libconcept{common_reference_with}@&, const remove_reference_t&> && + @\exposconcept{comparison-common-type-with}@ && @\libconcept{three_way_comparable}@< common_reference_t&, const remove_reference_t&>, Cat> && @\exposconcept{weakly-equality-comparable-with}@ && @@ -4842,11 +4842,17 @@ \end{codeblock} \pnum -Let \tcode{t} and \tcode{u} be lvalues +Let \tcode{t} and \tcode{t2} be lvalues +denoting distinct equal objects of types \tcode{const remove_reference_t} and -\tcode{const remove_reference_t}, respectively. +\tcode{remove_cvref_t}, respectively, and +let \tcode{u} and \tcode{u2} be lvalues denoting distinct equal objects +of types \tcode{const remove_reference_t} and +\tcode{remove_cvref_t}, respectively. Let \tcode{C} be \tcode{common_reference_t\&, const remove_reference_t\&>}. +Let \tcode{\exposid{CONVERT_TO_LVALUE}(E)} be defined +as in \ref{concepts.compare.general}. \tcode{T}, \tcode{U}, and \tcode{Cat} model \tcode{\libconcept{three_way_comparable_with}} only if: \begin{itemize} @@ -4859,7 +4865,8 @@ \item \tcode{(t <=> u != 0) == bool(t != u)} is \tcode{true}, \item - \tcode{Cat(t <=> u) == Cat(C(t) <=> C(u))} is \tcode{true}, + \tcode{Cat(t <=> u) == Cat(\exposid{CONVERT_TO_LVALUE}(t2) <=> +\exposid{CONVERT_TO_LVALUE}(u2))} is \tcode{true}, \item \tcode{(t <=> u < 0) == bool(t < u)} is \tcode{true}, \item From 758b012be431613db5ea59eb596ac097fadc8bb4 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 4 Aug 2022 21:05:50 +0200 Subject: [PATCH 217/430] P2408R5 Ranges iterators as inputs to non-Ranges algorithms --- source/algorithms.tex | 54 ++++++++++++++++++++++--------------------- source/regex.tex | 8 +++---- source/support.tex | 2 ++ 3 files changed, 34 insertions(+), 30 deletions(-) diff --git a/source/algorithms.tex b/source/algorithms.tex index 1d3f89cbc7..43327ae0fe 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -69,6 +69,11 @@ Throughout this Clause, where the template parameters are not constrained, the names of template parameters are used to express type requirements. \begin{itemize} +\item + If an algorithm's \Fundescx{Effects} element specifies + that a value pointed to by any iterator passed as an argument is modified, + then the type of that argument shall meet + the requirements of a mutable iterator\iref{iterator.requirements}. \item If an algorithm's template parameter is named \tcode{InputIterator}, @@ -86,16 +91,18 @@ \item If an algorithm's template parameter is named \tcode{ForwardIterator}, - \tcode{ForwardIterator1}, or - \tcode{Forward\-Iterator2}, + \tcode{ForwardIterator1}, + \tcode{ForwardItera\-tor2}, or + \tcode{NoThrowForwardIterator}, the template argument shall meet the - \oldconcept{ForwardIterator} requirements\iref{forward.iterators}. + \oldconcept{ForwardIterator} requirements\iref{forward.iterators} + if it is required to be a mutable iterator, or + model \libconcept{forward_iterator}\iref{iterator.concept.forward} otherwise. \item If an algorithm's template parameter is named \tcode{NoThrowForwardIterator}, - the template argument shall meet the - \oldconcept{ForwardIterator} requirements\iref{forward.iterators}, and - is required to have the property that no exceptions are thrown + the template argument + is also required to have the property that no exceptions are thrown from increment, assignment, or comparison of, or indirection through, valid iterators. \item @@ -104,28 +111,23 @@ \tcode{Bidirectional\-Iterator1}, or \tcode{BidirectionalIterator2}, the template argument shall meet the - \oldconcept{BidirectionalIterator} requirements\iref{bidirectional.iterators}. + \oldconcept{BidirectionalIterator} requirements\iref{bidirectional.iterators} + if it is required to be a mutable iterator, or model + \libconcept{bidirectional_iterator}\iref{iterator.concept.bidir} otherwise. \item If an algorithm's template parameter is named \tcode{RandomAccessIterator}, \tcode{Random\-AccessIterator1}, or \tcode{RandomAccessIterator2}, the template argument shall meet the - \oldconcept{RandomAccessIterator} requirements\iref{random.access.iterators}. + \oldconcept{RandomAccessIterator} requirements\iref{random.access.iterators} + if it is required to be a mutable iterator, or model + \libconcept{random_access_iterator}\iref{iterator.concept.random.access} otherwise. \end{itemize} - -\pnum -If an algorithm's \effects element specifies -that a value pointed to by any iterator passed as an argument is modified, -then that algorithm has an additional type requirement: -The type of that argument shall meet -the requirements of a mutable iterator\iref{iterator.requirements}. \begin{note} -This requirement does not affect arguments that are named -\tcode{OutputIterator}, \tcode{OutputIterator1}, or \tcode{OutputIterator2}, -because output iterators must always be mutable, nor -does it affect arguments that are constrained, -for which mutability requirements are expressed explicitly. +These requirements do not affect iterator arguments that are constrained, +for which iterator category and mutability requirements +are expressed explicitly. \end{note} \pnum @@ -6033,8 +6035,8 @@ \item For the overloads with no \tcode{ExecutionPolicy}, let \tcode{T} be the value type of \tcode{InputIterator}. - If \tcode{InputIterator} meets - the \oldconcept{ForwardIterator} requirements, + If \tcode{InputIterator} models + \libconcept{forward_iterator}\iref{iterator.concept.forward}, then there are no additional requirements for \tcode{T}. Otherwise, if \tcode{OutputIterator} meets the \oldconcept{ForwardIterator} requirements and @@ -6339,8 +6341,8 @@ \item \tcode{SampleIterator} meets the \oldconcept{RandomAccessIterator} requirements\iref{random.access.iterators} - unless \tcode{Pop\-ulat\-ion\-Iter\-ator} meets - the \oldconcept{ForwardIterator} requirements\iref{forward.iterators}. + unless \tcode{Pop\-ulat\-ion\-Iter\-ator} + models \libconcept{forward_iterator}\iref{iterator.concept.forward}. \item \tcode{remove_reference_t} meets the requirements of a uniform random bit generator type\iref{rand.req.urng}. @@ -6369,8 +6371,8 @@ \begin{itemize} \item For the overload in namespace \tcode{std}, - stable if and only if \tcode{PopulationIterator} meets - the \oldconcept{For\-wardIterator} requirements. + stable if and only if \tcode{PopulationIterator} + models \libconcept{forward_iterator}. For the first overload in namespace \tcode{ranges}, stable if and only if \tcode{I} models \libconcept{forward_iterator}. \item diff --git a/source/regex.tex b/source/regex.tex index 963a3d0630..6aec80405f 100644 --- a/source/regex.tex +++ b/source/regex.tex @@ -2691,8 +2691,8 @@ \begin{itemdescr} \pnum \expects -\tcode{BidirectionalIterator} meets the -\oldconcept{BidirectionalIterator} requirements\iref{bidirectional.iterators}. +\tcode{BidirectionalIterator} models +\libconcept{bidirectional_iterator}\iref{iterator.concept.bidir}. \pnum \effects @@ -2881,8 +2881,8 @@ \begin{itemdescr} \pnum \expects -\tcode{BidirectionalIterator} meets the -\oldconcept{BidirectionalIterator} requirements\iref{bidirectional.iterators}. +\tcode{BidirectionalIterator} models +\libconcept{bidirectional_iterator}\iref{iterator.concept.bidir}. \pnum \effects diff --git a/source/support.tex b/source/support.tex index 06063893b1..d08a76acc5 100644 --- a/source/support.tex +++ b/source/support.tex @@ -553,6 +553,8 @@ \begin{codeblock} // all freestanding #define @\defnlibxname{cpp_lib_addressof_constexpr}@ 201603L // also in \libheader{memory} +#define @\defnlibxname{cpp_lib_algorithm_iterator_requirements}@ 202207L + // also in \libheader{algorithm}, \libheader{numeric}, \libheader{memory} #define @\defnlibxname{cpp_lib_allocate_at_least}@ 202106L // also in \libheader{memory} #define @\defnlibxname{cpp_lib_allocator_traits_is_always_equal}@ 201411L // also in \libheader{memory}, \libheader{scoped_allocator}, \libheader{string}, \libheader{deque}, \libheader{forward_list}, \libheader{list}, \libheader{vector}, From 75518ffdc476cbc239918466588d963fc97a8013 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 28 Jul 2022 23:43:07 +0200 Subject: [PATCH 218/430] P2417R2 A more constexpr bitset --- source/support.tex | 1 + source/utilities.tex | 132 +++++++++++++++++++++---------------------- 2 files changed, 67 insertions(+), 66 deletions(-) diff --git a/source/support.tex b/source/support.tex index d08a76acc5..9e23951169 100644 --- a/source/support.tex +++ b/source/support.tex @@ -593,6 +593,7 @@ #define @\defnlibxname{cpp_lib_complex_udls}@ 201309L // also in \libheader{complex} #define @\defnlibxname{cpp_lib_concepts}@ 202207L // also in \libheader{concepts}, \libheader{compare} #define @\defnlibxname{cpp_lib_constexpr_algorithms}@ 201806L // also in \libheader{algorithm} +#define @\defnlibxname{cpp_lib_constexpr_bitset}@ 202202L // also in \libheader{bitset} #define @\defnlibxname{cpp_lib_constexpr_charconv}@ 202207L // also in \libheader{charconv} #define @\defnlibxname{cpp_lib_constexpr_cmath}@ 202202L // also in \libheader{cmath}, \libheader{cstdlib} #define @\defnlibxname{cpp_lib_constexpr_complex}@ 201711L // also in \libheader{complex} diff --git a/source/utilities.tex b/source/utilities.tex index 72aeb18ed3..46ec5ed5a0 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -8862,11 +8862,11 @@ // \ref{bitset.operators}, bitset operators template - bitset operator&(const bitset&, const bitset&) noexcept; + constexpr bitset operator&(const bitset&, const bitset&) noexcept; template - bitset operator|(const bitset&, const bitset&) noexcept; + constexpr bitset operator|(const bitset&, const bitset&) noexcept; template - bitset operator^(const bitset&, const bitset&) noexcept; + constexpr bitset operator^(const bitset&, const bitset&) noexcept; template basic_istream& operator>>(basic_istream& is, bitset& x); @@ -8887,23 +8887,23 @@ // bit reference class reference { friend class bitset; - reference() noexcept; + constexpr reference() noexcept; public: - reference(const reference&) = default; - ~reference(); - reference& operator=(bool x) noexcept; // for \tcode{b[i] = x;} - reference& operator=(const reference&) noexcept; // for \tcode{b[i] = b[j];} - bool operator~() const noexcept; // flips the bit - operator bool() const noexcept; // for \tcode{x = b[i];} - reference& flip() noexcept; // for \tcode{b[i].flip();} + constexpr reference(const reference&) = default; + constexpr ~reference(); + constexpr reference& operator=(bool x) noexcept; // for \tcode{b[i] = x;} + constexpr reference& operator=(const reference&) noexcept; // for \tcode{b[i] = b[j];} + constexpr bool operator~() const noexcept; // flips the bit + constexpr operator bool() const noexcept; // for \tcode{x = b[i];} + constexpr reference& flip() noexcept; // for \tcode{b[i].flip();} }; // \ref{bitset.cons}, constructors constexpr bitset() noexcept; constexpr bitset(unsigned long long val) noexcept; template - explicit bitset( + constexpr explicit bitset( const basic_string& str, typename basic_string::size_type pos = 0, typename basic_string::size_type n @@ -8911,47 +8911,47 @@ charT zero = charT('0'), charT one = charT('1')); template - explicit bitset( + constexpr explicit bitset( const charT* str, typename basic_string::size_type n = basic_string::npos, charT zero = charT('0'), charT one = charT('1')); // \ref{bitset.members}, bitset operations - bitset& operator&=(const bitset& rhs) noexcept; - bitset& operator|=(const bitset& rhs) noexcept; - bitset& operator^=(const bitset& rhs) noexcept; - bitset& operator<<=(size_t pos) noexcept; - bitset& operator>>=(size_t pos) noexcept; - bitset& set() noexcept; - bitset& set(size_t pos, bool val = true); - bitset& reset() noexcept; - bitset& reset(size_t pos); - bitset operator~() const noexcept; - bitset& flip() noexcept; - bitset& flip(size_t pos); + constexpr bitset& operator&=(const bitset& rhs) noexcept; + constexpr bitset& operator|=(const bitset& rhs) noexcept; + constexpr bitset& operator^=(const bitset& rhs) noexcept; + constexpr bitset& operator<<=(size_t pos) noexcept; + constexpr bitset& operator>>=(size_t pos) noexcept; + constexpr bitset& set() noexcept; + constexpr bitset& set(size_t pos, bool val = true); + constexpr bitset& reset() noexcept; + constexpr bitset& reset(size_t pos); + constexpr bitset operator~() const noexcept; + constexpr bitset& flip() noexcept; + constexpr bitset& flip(size_t pos); // element access constexpr bool operator[](size_t pos) const; // for \tcode{b[i];} - reference operator[](size_t pos); // for \tcode{b[i];} + constexpr reference operator[](size_t pos); // for \tcode{b[i];} - unsigned long to_ulong() const; - unsigned long long to_ullong() const; + constexpr unsigned long to_ulong() const; + constexpr unsigned long long to_ullong() const; template, class Allocator = allocator> - basic_string + constexpr basic_string to_string(charT zero = charT('0'), charT one = charT('1')) const; - size_t count() const noexcept; + constexpr size_t count() const noexcept; constexpr size_t size() const noexcept; - bool operator==(const bitset& rhs) const noexcept; - bool test(size_t pos) const; - bool all() const noexcept; - bool any() const noexcept; - bool none() const noexcept; - bitset operator<<(size_t pos) const noexcept; - bitset operator>>(size_t pos) const noexcept; + constexpr bool operator==(const bitset& rhs) const noexcept; + constexpr bool test(size_t pos) const; + constexpr bool all() const noexcept; + constexpr bool any() const noexcept; + constexpr bool none() const noexcept; + constexpr bitset operator<<(size_t pos) const noexcept; + constexpr bitset operator>>(size_t pos) const noexcept; }; // \ref{bitset.hash}, hash support @@ -9038,7 +9038,7 @@ \indexlibraryctor{bitset}% \begin{itemdecl} template - explicit bitset( + constexpr explicit bitset( const basic_string& str, typename basic_string::size_type pos = 0, typename basic_string::size_type n @@ -9089,7 +9089,7 @@ \indexlibraryctor{bitset}% \begin{itemdecl} template - explicit bitset( + constexpr explicit bitset( const charT* str, typename basic_string::size_type n = basic_string::npos, charT zero = charT('0'), @@ -9113,7 +9113,7 @@ \indexlibrarymember{operator\&=}{bitset}% \begin{itemdecl} -bitset& operator&=(const bitset& rhs) noexcept; +constexpr bitset& operator&=(const bitset& rhs) noexcept; \end{itemdecl} \begin{itemdescr} @@ -9130,7 +9130,7 @@ \indexlibrarymember{operator"|=}{bitset}% \begin{itemdecl} -bitset& operator|=(const bitset& rhs) noexcept; +constexpr bitset& operator|=(const bitset& rhs) noexcept; \end{itemdecl} \begin{itemdescr} @@ -9147,7 +9147,7 @@ \indexlibrarymember{operator\caret=}{bitset}% \begin{itemdecl} -bitset& operator^=(const bitset& rhs) noexcept; +constexpr bitset& operator^=(const bitset& rhs) noexcept; \end{itemdecl} \begin{itemdescr} @@ -9164,7 +9164,7 @@ \indexlibrarymember{operator<<=}{bitset}% \begin{itemdecl} -bitset& operator<<=(size_t pos) noexcept; +constexpr bitset& operator<<=(size_t pos) noexcept; \end{itemdecl} \begin{itemdescr} @@ -9189,7 +9189,7 @@ \indexlibrarymember{operator>>=}{bitset}% \begin{itemdecl} -bitset& operator>>=(size_t pos) noexcept; +constexpr bitset& operator>>=(size_t pos) noexcept; \end{itemdecl} \begin{itemdescr} @@ -9215,7 +9215,7 @@ \indexlibrary{\idxcode{set} (member)!\idxcode{bitset}}% \indexlibrary{\idxcode{bitset}!\idxcode{set}}% \begin{itemdecl} -bitset& set() noexcept; +constexpr bitset& set() noexcept; \end{itemdecl} \begin{itemdescr} @@ -9233,7 +9233,7 @@ \indexlibrary{\idxcode{set} (member)!\idxcode{bitset}}% \indexlibrary{\idxcode{bitset}!\idxcode{set}}% \begin{itemdecl} -bitset& set(size_t pos, bool val = true); +constexpr bitset& set(size_t pos, bool val = true); \end{itemdecl} \begin{itemdescr} @@ -9255,7 +9255,7 @@ \indexlibrarymember{reset}{bitset}% \begin{itemdecl} -bitset& reset() noexcept; +constexpr bitset& reset() noexcept; \end{itemdecl} \begin{itemdescr} @@ -9271,7 +9271,7 @@ \indexlibrarymember{reset}{bitset}% \begin{itemdecl} -bitset& reset(size_t pos); +constexpr bitset& reset(size_t pos); \end{itemdecl} \begin{itemdescr} @@ -9292,7 +9292,7 @@ \indexlibrarymember{operator\~{}}{bitset}% \begin{itemdecl} -bitset operator~() const noexcept; +constexpr bitset operator~() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -9310,7 +9310,7 @@ \indexlibrarymember{flip}{bitset}% \begin{itemdecl} -bitset& flip() noexcept; +constexpr bitset& flip() noexcept; \end{itemdecl} \begin{itemdescr} @@ -9326,7 +9326,7 @@ \indexlibrarymember{flip}{bitset}% \begin{itemdecl} -bitset& flip(size_t pos); +constexpr bitset& flip(size_t pos); \end{itemdecl} \begin{itemdescr} @@ -9347,7 +9347,7 @@ \indexlibrarymember{to_ulong}{bitset}% \begin{itemdecl} -unsigned long to_ulong() const; +constexpr unsigned long to_ulong() const; \end{itemdecl} \begin{itemdescr} @@ -9365,7 +9365,7 @@ \indexlibrarymember{to_ullong}{bitset}% \begin{itemdecl} -unsigned long long to_ullong() const; +constexpr unsigned long long to_ullong() const; \end{itemdecl} \begin{itemdescr} @@ -9386,7 +9386,7 @@ template, class Allocator = allocator> - basic_string + constexpr basic_string to_string(charT zero = charT('0'), charT one = charT('1')) const; \end{itemdecl} @@ -9411,7 +9411,7 @@ \indexlibrarymember{count}{bitset}% \begin{itemdecl} -size_t count() const noexcept; +constexpr size_t count() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -9434,7 +9434,7 @@ \indexlibrarymember{operator==}{bitset}% \begin{itemdecl} -bool operator==(const bitset& rhs) const noexcept; +constexpr bool operator==(const bitset& rhs) const noexcept; \end{itemdecl} \begin{itemdescr} @@ -9447,7 +9447,7 @@ \indexlibrarymember{test}{bitset}% \begin{itemdecl} -bool test(size_t pos) const; +constexpr bool test(size_t pos) const; \end{itemdecl} \begin{itemdescr} @@ -9467,7 +9467,7 @@ \indexlibrarymember{all}{bitset}% \begin{itemdecl} -bool all() const noexcept; +constexpr bool all() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -9480,7 +9480,7 @@ \indexlibrary{\idxcode{any} (member)!\idxcode{bitset}}% \indexlibrary{\idxcode{bitset}!\idxcode{any}}% \begin{itemdecl} -bool any() const noexcept; +constexpr bool any() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -9491,7 +9491,7 @@ \indexlibrarymember{none}{bitset}% \begin{itemdecl} -bool none() const noexcept; +constexpr bool none() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -9502,7 +9502,7 @@ \indexlibrarymember{operator<<}{bitset}% \begin{itemdecl} -bitset operator<<(size_t pos) const noexcept; +constexpr bitset operator<<(size_t pos) const noexcept; \end{itemdecl} \begin{itemdescr} @@ -9513,7 +9513,7 @@ \indexlibrarymember{operator>>}{bitset}% \begin{itemdecl} -bitset operator>>(size_t pos) const noexcept; +constexpr bitset operator>>(size_t pos) const noexcept; \end{itemdecl} \begin{itemdescr} @@ -9544,7 +9544,7 @@ \indexlibrarymember{operator[]}{bitset}% \begin{itemdecl} -bitset::reference operator[](size_t pos); +constexpr bitset::reference operator[](size_t pos); \end{itemdecl} \begin{itemdescr} @@ -9593,7 +9593,7 @@ \indexlibrarymember{operator\&}{bitset}% \begin{itemdecl} template - bitset operator&(const bitset& lhs, const bitset& rhs) noexcept; + constexpr bitset operator&(const bitset& lhs, const bitset& rhs) noexcept; \end{itemdecl} \begin{itemdescr} @@ -9605,7 +9605,7 @@ \indexlibrarymember{operator"|}{bitset}% \begin{itemdecl} template - bitset operator|(const bitset& lhs, const bitset& rhs) noexcept; + constexpr bitset operator|(const bitset& lhs, const bitset& rhs) noexcept; \end{itemdecl} \begin{itemdescr} @@ -9617,7 +9617,7 @@ \indexlibrarymember{operator\caret}{bitset}% \begin{itemdecl} template - bitset operator^(const bitset& lhs, const bitset& rhs) noexcept; + constexpr bitset operator^(const bitset& lhs, const bitset& rhs) noexcept; \end{itemdecl} \begin{itemdescr} From 55b6fb3f2160235434c53b3a902f2a2cf35a2f52 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 4 Aug 2022 22:22:25 +0200 Subject: [PATCH 219/430] P2419R2 Clarify handling of encodings in localized formatting of chrono types The feature test macros will be revised after all motions have been applied. --- source/time.tex | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/time.tex b/source/time.tex index 667d1fc334..a59096095d 100644 --- a/source/time.tex +++ b/source/time.tex @@ -10509,6 +10509,11 @@ the formats specified in ISO 8601:2004 shall be used where so described. Some of the conversion specifiers depend on the formatting locale. +If the string literal encoding is a Unicode encoding form and +the locale is among +an \impldef{locales with Unicode support for chrono types} set of locales, +each replacement that depends on the locale is performed as if +the replacement character sequence is converted to the string literal encoding. If the formatted object does not contain the information the conversion specifier refers to, an exception of type \tcode{format_error} is thrown. From 00cdc0ef2c595cccbac249f621b467e8c0426050 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 28 Jul 2022 23:05:15 +0200 Subject: [PATCH 220/430] P2438R2 std::string::substr() && --- source/compatibility.tex | 22 ++++++++++++++ source/strings.tex | 63 ++++++++++++++++++++++++++++++---------- 2 files changed, 70 insertions(+), 15 deletions(-) diff --git a/source/compatibility.tex b/source/compatibility.tex index 3f1bcd7c11..991dd1523b 100644 --- a/source/compatibility.tex +++ b/source/compatibility.tex @@ -201,6 +201,28 @@ std::format("{}", t.bit); // ill-formed, previously returned \tcode{"0"} \end{codeblock} +\rSec2[diff.cpp20.strings]{\ref{strings}: strings library} + +\diffref{string.classes} +\change +Additional rvalue overload for the \tcode{substr} member function and +the corresponding constructor. +\rationale +Improve efficiency of operations on rvalues. +\effect +Valid \CppXX{} code that created a substring +by calling \tcode{substr} (or the corresponding constructor) +on an xvalue expression with type \tcode{S} +that is a specialization of \tcode{basic_string} +may change meaning in this revision of \Cpp{}. +\begin{codeblock} +std::string s1 = "some long string that forces allocation", s2 = s1; +std::move(s1).substr(10, 5); +assert(s1 == s2); // unspecified, previously guaranteed to be \tcode{true} +std::string s3(std::move(s2), 10, 5); +assert(s1 == s2); // unspecified, previously guaranteed to be \tcode{true} +\end{codeblock} + \rSec2[diff.cpp20.containers]{\ref{containers}: containers library} \diffref{associative.reqmts,unord.req} diff --git a/source/strings.tex b/source/strings.tex index ad2a4aeee8..b46c8f912f 100644 --- a/source/strings.tex +++ b/source/strings.tex @@ -2066,6 +2066,10 @@ const Allocator& a = Allocator()); constexpr basic_string(const basic_string& str, size_type pos, size_type n, const Allocator& a = Allocator()); + constexpr basic_string(basic_string&& str, size_type pos, + const Allocator& a = Allocator()); + constexpr basic_string(basic_string&& str, size_type pos, size_type n, + const Allocator& a = Allocator()); template constexpr basic_string(const T& t, size_type pos, size_type n, const Allocator& a = Allocator()); @@ -2287,7 +2291,8 @@ constexpr size_type find_last_not_of(const charT* s, size_type pos = npos) const; constexpr size_type find_last_not_of(charT c, size_type pos = npos) const noexcept; - constexpr basic_string substr(size_type pos = 0, size_type n = npos) const; + constexpr basic_string substr(size_type pos = 0, size_type n = npos) const &; + constexpr basic_string substr(size_type pos = 0, size_type n = npos) &&; template constexpr int compare(const T& t) const noexcept(@\seebelow@); @@ -2453,15 +2458,43 @@ const Allocator& a = Allocator()); constexpr basic_string(const basic_string& str, size_type pos, size_type n, const Allocator& a = Allocator()); +constexpr basic_string(basic_string&& str, size_type pos, + const Allocator& a = Allocator()); +constexpr basic_string(basic_string&& str, size_type pos, size_type n, + const Allocator& a = Allocator()); \end{itemdecl} \begin{itemdescr} +\pnum +Let +\begin{itemize} +\item +\tcode{s} be the value of \tcode{str} prior to this call and +\item +\tcode{rlen} be \tcode{pos + min(n, s.size() - pos)} +for the overloads with parameter \tcode{n}, and +\tcode{s.size()} otherwise. +\end{itemize} + \pnum \effects -Let \tcode{n} be \tcode{npos} for the first overload. Equivalent to: -\begin{codeblock} -basic_string(basic_string_view(str).substr(pos, n), a) -\end{codeblock} +Constructs an object +whose initial value is the range \range{s.data() + pos}{s.data() + rlen}. + +\pnum +\throws +\tcode{out_of_range} if \tcode{pos > s.size()}. + +\pnum +\remarks +For the overloads with a \tcode{basic_string\&\&} parameter, +\tcode{str} is left in a valid but unspecified state. + +\pnum +\recommended +For the overloads with a \tcode{basic_string\&\&} parameter, +implementations should avoid allocation +if \tcode{s.get_allocator() == a} is \tcode{true}. \end{itemdescr} \indexlibraryctor{basic_string}% @@ -4422,24 +4455,24 @@ \indexlibrarymember{substr}{basic_string}% \begin{itemdecl} -constexpr basic_string substr(size_type pos = 0, size_type n = npos) const; +constexpr basic_string substr(size_type pos = 0, size_type n = npos) const &; \end{itemdecl} \begin{itemdescr} \pnum \effects -Determines the effective length \tcode{rlen} of the string to copy as the smaller of \tcode{n} and -\tcode{size() - pos}. +Equivalent to: \tcode{return basic_string(*this, pos, n);} +\end{itemdescr} -\pnum -\returns -\tcode{basic_string(data()+pos, rlen)}. +\indexlibrarymember{substr}{basic_string}% +\begin{itemdecl} +constexpr basic_string substr(size_type pos = 0, size_type n = npos) &&; +\end{itemdecl} +\begin{itemdescr} \pnum -\throws -\tcode{out_of_range} -if -\tcode{pos > size()}. +\effects +Equivalent to: \tcode{return basic_string(std::move(*this), pos, n);} \end{itemdescr} \rSec4[string.compare]{\tcode{basic_string::compare}} From 1d1f8ce37d0b8c98f82c27fa414728aaa8216098 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 4 Aug 2022 22:54:09 +0200 Subject: [PATCH 221/430] P2446R2 views::as_rvalue --- source/ranges.tex | 101 +++++++++++++++++++++++++++++++++++++++++++++ source/support.tex | 1 + 2 files changed, 102 insertions(+) diff --git a/source/ranges.tex b/source/ranges.tex index a400deae14..f91a0ee044 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -230,6 +230,16 @@ inline constexpr bool enable_borrowed_range> = // freestanding enable_borrowed_range; + // \ref{range.as.rvalue}, as rvalue view + template<@\libconcept{view}@ V> + requires @\libconcept{input_range}@ + class as_rvalue_view; + + template + inline constexpr bool enable_borrowed_range> = enable_borrowed_range; + + namespace views { inline constexpr @\unspec@ as_rvalue = @\unspec@; } + // \ref{range.filter}, filter view template<@\libconcept{input_range}@ V, @\libconcept{indirect_unary_predicate}@> Pred> requires @\libconcept{view}@ && is_object_v @@ -3953,6 +3963,97 @@ Initializes \exposid{r_} with \tcode{std::move(t)}. \end{itemdescr} +\rSec2[range.as.rvalue]{As rvalue view} + +\rSec3[range.as.rvalue.overview]{Overview} + +\pnum +\tcode{as_rvalue_view} presents a \libconcept{view} of an underlying sequence +with the same behavior as the underlying sequence +except that its elements are rvalues. +Some generic algorithms can be called with a \tcode{as_rvalue_view} +to replace copying with moving. + +\pnum +\indexlibrarymember{as_rvalue}{views}% +The name \tcode{views::as_rvalue} denotes +a range adaptor object\iref{range.adaptor.object}. +Let \tcode{E} be an expression and let \tcode{T} be \tcode{decltype((E))}. +The expression \tcode{views::as_rvalue(E)} is expression-equivalent to: +\begin{itemize} +\item +\tcode{views::all(E)} if \tcode{same_as, range_reference_t>} is \tcode{true}. +\item +Otherwise, \tcode{as_rvalue_view(E)}. +\end{itemize} + +\pnum +\begin{example} +\begin{codeblock} +vector words = {"the", "quick", "brown", "fox", "ate", "a", "pterodactyl"}; +vector new_words; +ranges::copy(words | views::as_rvalue, back_inserter(new_words)); + // moves each string from \tcode{words} into \tcode{new_words} +\end{codeblock} +\end{example} + +\rSec3[range.as.rvalue.view]{Class template \tcode{as_rvalue_view}} + +\begin{codeblock} +namespace std::ranges { + template<@\libconcept{input_range}@ V> + requires @\libconcept{view}@ + class @\libglobal{as_rvalue_view}@ : public view_interface> + { + V @\exposid{base_}@ = V(); // \expos + + public: + as_rvalue_view() requires @\libconcept{default_initializable}@ = default; + constexpr explicit as_rvalue_view(V base); + + constexpr V base() const & requires copy_constructible { return @\exposid{base_}@; } + constexpr V base() && { return std::move(@\exposid{base_}@); } + + constexpr auto begin() requires (!@\exposconcept{simple-view}@) + { return move_iterator(ranges::begin(@\exposid{base_}@)); } + constexpr auto begin() const requires @\libconcept{range}@ + { return move_iterator(ranges::begin(@\exposid{base_}@)); } + + constexpr auto end() requires (!@\exposconcept{simple-view}@) { + if constexpr (@\libconcept{common_range}@) { + return move_iterator(ranges::end(@\exposid{base_}@)); + } else { + return move_sentinel(ranges::end(@\exposid{base_}@)); + } + } + constexpr auto end() const requires @\libconcept{range}@ { + if constexpr (@\libconcept{common_range}@) { + return move_iterator(ranges::end(@\exposid{base_}@)); + } else { + return move_sentinel(ranges::end(@\exposid{base_}@)); + } + } + + constexpr auto size() requires @\libconcept{sized_range}@ { return ranges::size(@\exposid{base_}@); } + constexpr auto size() const requires @\libconcept{sized_range}@ { return ranges::size(@\exposid{base_}@); } + }; + + template + as_rvalue_view(R&&) -> as_rvalue_view>; +} +\end{codeblock} + +\indexlibraryctor{as_rvalue_view}% +\begin{itemdecl} +constexpr explicit as_rvalue_view(V base); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \exposid{base_} with \tcode{std::move(base)}. +\end{itemdescr} + \rSec2[range.filter]{Filter view} \rSec3[range.filter.overview]{Overview} diff --git a/source/support.tex b/source/support.tex index 9e23951169..3ec63fb3c2 100644 --- a/source/support.tex +++ b/source/support.tex @@ -681,6 +681,7 @@ #define @\defnlibxname{cpp_lib_ranges}@ 202202L // also in \libheader{algorithm}, \libheader{functional}, \libheader{iterator}, \libheader{memory}, \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_as_const}@ 202207L // also in \libheader{ranges} +#define @\defnlibxname{cpp_lib_ranges_as_rvalue}@ 202207L // also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_cartesian_product}@ 202207L // also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_chunk}@ 202202L // also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_chunk_by}@ 202202L // also in \libheader{ranges} From 7838d1c53b91aaab2f7b2ac155090c6a5a5a59e0 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 12 Aug 2022 09:31:59 +0200 Subject: [PATCH 222/430] [ranges.syn] Add 'freestanding' markers per P1642R11 --- source/ranges.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index f91a0ee044..e0a61b1102 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -233,12 +233,12 @@ // \ref{range.as.rvalue}, as rvalue view template<@\libconcept{view}@ V> requires @\libconcept{input_range}@ - class as_rvalue_view; + class as_rvalue_view; // freestanding template inline constexpr bool enable_borrowed_range> = enable_borrowed_range; - namespace views { inline constexpr @\unspec@ as_rvalue = @\unspec@; } + namespace views { inline constexpr @\unspecnc@ as_rvalue = @\unspecnc@; } // freestanding // \ref{range.filter}, filter view template<@\libconcept{input_range}@ V, @\libconcept{indirect_unary_predicate}@> Pred> From 7bee8fd801b4495e3b292f0c3ac3440661187173 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 29 Jul 2022 00:19:59 +0200 Subject: [PATCH 223/430] P2465R3 Standard Library Modules std and std.compat --- source/basic.tex | 10 +++++--- source/declarations.tex | 14 ++++++++--- source/expressions.tex | 12 +++++---- source/lib-intro.tex | 56 +++++++++++++++++++++++++++++++++++++++++ source/support.tex | 1 + 5 files changed, 80 insertions(+), 13 deletions(-) diff --git a/source/basic.tex b/source/basic.tex index ad85305be3..ba765a09d4 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -3876,12 +3876,14 @@ or any other names that the library uses to declare these names. Thus, a \grammarterm{new-expression}, \grammarterm{delete-expression}, or function call that refers to one of -these functions without importing or including the header \libheaderref{new} is -well-formed. However, referring to \tcode{std} +these functions without importing or including the header \libheaderref{new} +or importing a \Cpp{} library module\iref{std.modules} +is well-formed. However, referring to \tcode{std} or \tcode{std::size_t} or \tcode{std::align_val_t} -is ill-formed unless the name has been declared -by importing or including the appropriate header. +is ill-formed unless +a standard library declaration\iref{cstddef.syn,new.syn,std.modules} +of that name precedes\iref{basic.lookup.general} the use of that name. \end{note} Allocation and/or deallocation functions may also be declared and defined for any diff --git a/source/declarations.tex b/source/declarations.tex index 8bb280b91c..8df1c2cd06 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -1901,6 +1901,10 @@ the deduced type $\mathtt{T}'$ replacing \tcode{T} is determined using the rules for template argument deduction. +If the initialization is copy-list-initialization, +a declaration of \tcode{std::initializer_list} +shall precede\iref{basic.lookup.general} +the \grammarterm{placeholder-type-specifier}. Obtain \tcode{P} from \tcode{T} by replacing the occurrences of \opt{\grammarterm{type-constraint}} \keyword{auto} either with @@ -5653,10 +5657,12 @@ corresponding parameter to be a non-deduced context\iref{temp.deduct.call}. \end{note} The template -\tcode{std::initializer_list} is not predefined; if the header -\tcode{} is not imported or included prior to a use of -\tcode{std::initializer_list} --- even an implicit use in which the type is not -named\iref{dcl.spec.auto} --- the program is ill-formed. +\tcode{std::initializer_list} is not predefined; +if a standard library declaration\iref{initializer.list.syn,std.modules} +of \tcode{std::initializer_list} is not reachable from\iref{module.reach} +a use of \tcode{std::initializer_list} --- +even an implicit use in which the type is not named\iref{dcl.spec.auto} --- +the program is ill-formed. \pnum List-initialization of an object or reference of type \tcode{T} is defined as follows: diff --git a/source/expressions.tex b/source/expressions.tex index bbae186efd..771923fd34 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -3939,9 +3939,10 @@ \end{example} \pnum -If the header \libheaderref{typeinfo} -is not imported or included prior -to a use of \keyword{typeid}, the program is ill-formed. +The type \tcode{std::type_info}\iref{type.info} is not predefined; +if a standard library declaration\iref{typeinfo.syn,std.modules} of +\tcode{std::type_info} does not precede\iref{basic.lookup.general} +a \tcode{typeid} expression, the program is ill-formed. \pnum \begin{note} @@ -6429,8 +6430,9 @@ \tcode{std::weak_ordering}, and \tcode{std::partial_ordering}) are not predefined; -if the header \libheaderref{compare} -is not imported or included prior to a use of such a class type -- +if a standard library declaration\iref{compare.syn,std.modules} +of such a class type does not precede\iref{basic.lookup.general} +a use of that type -- even an implicit use in which the type is not named (e.g., via the \keyword{auto} specifier\iref{dcl.spec.auto} in a defaulted three-way comparison\iref{class.spaceship} diff --git a/source/lib-intro.tex b/source/lib-intro.tex index 39dd9e1a7d..da95382659 100644 --- a/source/lib-intro.tex +++ b/source/lib-intro.tex @@ -1363,6 +1363,62 @@ \tcode{wscanf_s} \\ \end{multicolfloattable} +\rSec3[std.modules]{Modules} + +\pnum +The \Cpp{} standard library provides +the following \defn{\Cpp{} library modules}. + +\pnum +The named module \tcode{std} exports declarations in namespace \tcode{std} +that are provided by the importable \Cpp{} library headers +(\tref{headers.cpp} or the subset provided by a freestanding implementation) +and the \Cpp{} headers for C library facilities~(\tref{headers.cpp.c}). +It additionally exports declarations in the global namespace +for the storage allocation and deallocation functions +that are provided by \libheaderref{new}. + +\pnum +The named module \tcode{std.compat} exports the same declarations as +the named module \tcode{std}, and +additionally exports declarations in the global namespace +corresponding to the declarations in namespace \tcode{std} +that are provided by +the \Cpp{} headers for C library facilities~(\tref{headers.cpp.c}). + +\pnum +It is unspecified to which module a declaration in the standard library +is attached. +\begin{note} +Implementations are required to ensure that mixing +\tcode{\#include} and \tcode{import} does not result in +conflicting attachments\iref{basic.link}. +\end{note} +\recommended +Implementations should ensure such attachments do not preclude +further evolution or decomposition of the standard library modules. + +\pnum +A declaration in the standard library denotes the same entity regardless of +whether it was made reachable through +including a header, +importing a header unit, or +importing a \Cpp{} library module. + +\pnum +\recommended +Implementations should avoid exporting any other declarations +from the \Cpp{} library modules. + +\begin{note} +Like all named modules, the \Cpp{} library modules +do not make macros visible\iref{module.import}, such as +\tcode{assert}\iref{cassert.syn}, +\tcode{errno}\iref{cerrno.syn}, +\tcode{offsetof}\iref{cstddef.syn}, and +\tcode{va_arg}\iref{cstdarg.syn}. +\end{note} + \rSec3[compliance]{Freestanding implementations} \indextext{implementation!freestanding|(}% diff --git a/source/support.tex b/source/support.tex index 3ec63fb3c2..9495257e24 100644 --- a/source/support.tex +++ b/source/support.tex @@ -664,6 +664,7 @@ #define @\defnlibxname{cpp_lib_math_special_functions}@ 201603L // also in \libheader{cmath} #define @\defnlibxname{cpp_lib_mdspan}@ 202207L // also in \libheader{mdspan} #define @\defnlibxname{cpp_lib_memory_resource}@ 201603L // also in \libheader{memory_resource} +#define @\defnlibxname{cpp_lib_modules}@ 202207L #define @\defnlibxname{cpp_lib_move_only_function}@ 202110L // also in \libheader{functional} #define @\defnlibxname{cpp_lib_node_extract}@ 201606L // also in \libheader{map}, \libheader{set}, \libheader{unordered_map}, \libheader{unordered_set} From 7e85089c14cb115aaf4b1fccdce3e624e0fc7fb4 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 29 Jul 2022 00:44:20 +0200 Subject: [PATCH 224/430] P2445R1 std::forward_like --- source/support.tex | 1 + source/utilities.tex | 53 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/source/support.tex b/source/support.tex index 9495257e24..349c00602e 100644 --- a/source/support.tex +++ b/source/support.tex @@ -625,6 +625,7 @@ #define @\defnlibxname{cpp_lib_find_last}@ 202207L // also in \libheader{algorithm} #define @\defnlibxname{cpp_lib_flat_map}@ 202207L // also in \libheader{flat_map} #define @\defnlibxname{cpp_lib_format}@ 202207L // also in \libheader{format} +#define @\defnlibxname{cpp_lib_forward_like}@ 202207L // also in \libheader{utility} #define @\defnlibxname{cpp_lib_gcd_lcm}@ 201606L // also in \libheader{numeric} #define @\defnlibxname{cpp_lib_generic_associative_lookup}@ 201304L // also in \libheader{map}, \libheader{set} #define @\defnlibxname{cpp_lib_generic_unordered_lookup}@ 201811L diff --git a/source/utilities.tex b/source/utilities.tex index 46ec5ed5a0..e78ed9dc4a 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -55,6 +55,8 @@ constexpr T&& forward(remove_reference_t& t) noexcept; template constexpr T&& forward(remove_reference_t&& t) noexcept; + template + [[nodiscard]] constexpr auto forward_like(U&& x) noexcept -> @\seebelow@; template constexpr remove_reference_t&& move(T&&) noexcept; template @@ -358,6 +360,57 @@ \end{example} \end{itemdescr} +\indexlibraryglobal{forward_like}% +\begin{itemdecl} +template + [[nodiscard]] constexpr auto forward_like(U&& x) noexcept -> @\seebelow@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\begin{itemize} +\item +Let \tcode{\exposid{COPY_CONST}(A, B)} be \tcode{const B} +if \tcode{A} is a const type, otherwise \tcode{B}. +\item +Let \tcode{\exposid{OVERRIDE_REF}(A, B)} be \tcode{remove_reference_t\&\&} +if \tcode{A} is an rvalue reference type, otherwise \tcode{B\&}. +\item +Let \tcode{V} be +\begin{codeblock} +@\exposid{OVERRIDE_REF}@(T&&, @\exposid{COPY_CONST}@(remove_reference_t, remove_reference_t)) +\end{codeblock} +\end{itemize} + +\pnum +\returns +\tcode{static_cast(x)}. + +\pnum +\remarks +The return type is \tcode{V}. + +\pnum +\begin{example} +\begin{codeblock} +struct accessor { + vector* container; + decltype(auto) operator[](this auto&& self, size_t i) { + return std::forward_like((*container)[i]); + } +}; +void g() { + vector v{"a"s, "b"s}; + accessor a{&v}; + string& x = a[0]; // OK, binds to lvalue reference + string&& y = std::move(a)[0]; // OK, is rvalue reference + string const&& z = std::move(as_const(a))[1]; // OK, is \tcode{const\&\&} + string& w = as_const(a)[1]; // error: will not bind to non-const +} +\end{codeblock} +\end{example} +\end{itemdescr} + \indexlibrary{\idxcode{move}!function}% \indextext{\idxcode{move}}% \begin{itemdecl} From b2f596f4aff2b6f37070f986b2541f79ff5a3e1d Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 29 Jul 2022 11:59:00 +0200 Subject: [PATCH 225/430] P2467R1 Support exclusive mode for fstreams --- source/iostreams.tex | 51 ++++++++++++++++++++++++++------------------ source/support.tex | 1 + 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/source/iostreams.tex b/source/iostreams.tex index 7425917019..ee3afe522c 100644 --- a/source/iostreams.tex +++ b/source/iostreams.tex @@ -778,6 +778,7 @@ static constexpr openmode ate = @\unspec@; static constexpr openmode binary = @\unspec@; static constexpr openmode in = @\unspec@; + static constexpr openmode noreplace = @\unspec@; static constexpr openmode out = @\unspec@; static constexpr openmode trunc = @\unspec@; @@ -1070,6 +1071,8 @@ perform input and output in binary mode (as opposed to text mode) \\ \tcode{in} & open for input \\ +\tcode{noreplace} & + open in exclusive mode \\ \tcode{out} & open for output \\ \tcode{trunc} & @@ -10900,28 +10903,34 @@ the open fails. \begin{floattable}{File open modes}{filebuf.open.modes} -{cccccl} +{ccccccl} \topline -\multicolumn{5}{|c}{\tcode{ios_base} flag combination} & \tcode{stdio} equivalent \\ -\tcode{binary} & \tcode{in} & \tcode{out} & \tcode{trunc} & \tcode{app} & \\ \capsep - & & + & & & \tcode{"w"} \\ \rowsep - & & + & + & & \tcode{"w"} \\ \rowsep - & & + & & + & \tcode{"a"} \\ \rowsep - & & & & + & \tcode{"a"} \\ \rowsep - & + & & & & \tcode{"r"} \\ \rowsep - & + & + & & & \tcode{"r+"} \\ \rowsep - & + & + & + & & \tcode{"w+"} \\ \rowsep - & + & + & & + & \tcode{"a+"} \\ \rowsep - & + & & & + & \tcode{"a+"} \\ \rowsep - + & & + & & & \tcode{"wb"} \\ \rowsep - + & & + & + & & \tcode{"wb"} \\ \rowsep - + & & + & & + & \tcode{"ab"} \\ \rowsep - + & & & & + & \tcode{"ab"} \\ \rowsep - + & + & & & & \tcode{"rb"} \\ \rowsep - + & + & + & & & \tcode{"r+b"} \\ \rowsep - + & + & + & + & & \tcode{"w+b"} \\ \rowsep - + & + & + & & + & \tcode{"a+b"} \\ \rowsep - + & + & & & + & \tcode{"a+b"} \\ +\multicolumn{6}{|c}{\tcode{ios_base} flag combination} & \tcode{stdio} equivalent \\ +\tcode{binary} & \tcode{in} & \tcode{out} & \tcode{trunc} & \tcode{app} & \tcode{noreplace} \\ \capsep + & & + & & & & \tcode{"w"} \\ \rowsep + & & + & & & + & \tcode{"wx"} \\ \rowsep + & & + & + & & & \tcode{"w"} \\ \rowsep + & & + & + & & + & \tcode{"wx"} \\ \rowsep + & & + & & + & & \tcode{"a"} \\ \rowsep + & & & & + & & \tcode{"a"} \\ \rowsep + & + & & & & & \tcode{"r"} \\ \rowsep + & + & + & & & & \tcode{"r+"} \\ \rowsep + & + & + & + & & & \tcode{"w+"} \\ \rowsep + & + & + & + & & + & \tcode{"w+x"} \\ \rowsep + & + & + & & + & & \tcode{"a+"} \\ \rowsep + & + & & & + & & \tcode{"a+"} \\ \rowsep + + & & + & & & & \tcode{"wb"} \\ \rowsep + + & & + & & & + & \tcode{"wbx"} \\ \rowsep + + & & + & + & & & \tcode{"wb"} \\ \rowsep + + & & + & + & & + & \tcode{"wbx"} \\ \rowsep + + & & + & & + & & \tcode{"ab"} \\ \rowsep + + & & & & + & & \tcode{"ab"} \\ \rowsep + + & + & & & & & \tcode{"rb"} \\ \rowsep + + & + & + & & & & \tcode{"r+b"} \\ \rowsep + + & + & + & + & & & \tcode{"w+b"} \\ \rowsep + + & + & + & + & & + & \tcode{"w+bx"} \\ \rowsep + + & + & + & & + & & \tcode{"a+b"} \\ \rowsep + + & + & & & + & & \tcode{"a+b"} \\ \end{floattable} \pnum diff --git a/source/support.tex b/source/support.tex index 349c00602e..2560761550 100644 --- a/source/support.tex +++ b/source/support.tex @@ -642,6 +642,7 @@ #define @\defnlibxname{cpp_lib_interpolate}@ 201902L // also in \libheader{cmath}, \libheader{numeric} #define @\defnlibxname{cpp_lib_invoke}@ 201411L // also in \libheader{functional} #define @\defnlibxname{cpp_lib_invoke_r}@ 202106L // also in \libheader{functional} +#define @\defnlibxname{cpp_lib_ios_noreplace}@ 202207L // also in \libheader{ios} #define @\defnlibxname{cpp_lib_is_aggregate}@ 201703L // also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_is_constant_evaluated}@ 201811L // also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_is_final}@ 201402L // also in \libheader{type_traits} From 7786c6b1e3640417fcaee466c87113aa7e0457af Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 5 Aug 2022 20:23:08 +0200 Subject: [PATCH 226/430] P2474R2 views::repeat Editorial changes: * [range.repeat.iterator] Fix incomplete template-head * [range.repeat.iterator] Fix misspelled names: - "is-signed-like" => "is-signed-integer-like" - "bound_" => "current_" * [range.repeat.iterator] Use statement form of "Equivalent to" --- source/ranges.tex | 462 +++++++++++++++++++++++++++++++++++++++++++++ source/support.tex | 1 + 2 files changed, 463 insertions(+) diff --git a/source/ranges.tex b/source/ranges.tex index e0a61b1102..5b93f76c8a 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -189,6 +189,14 @@ namespace views { inline constexpr @\unspecnc@ iota = @\unspecnc@; } // freestanding + // \ref{range.repeat}, repeat view + template<@\libconcept{copy_constructible}@ W, @\libconcept{semiregular}@ Bound = unreachable_sentinel_t> + requires (is_object_v && @\libconcept{same_as}@> + && (@\exposid{is-integer-like}@ || @\libconcept{same_as}@)) + class repeat_view; + + namespace views { inline constexpr @\unspec@ repeat = @\unspec@; } + // \ref{range.istream}, istream view template<@\libconcept{movable}@ Val, class CharT, class Traits = char_traits> requires @\seebelow@ @@ -3327,6 +3335,429 @@ Equivalent to: \tcode{return -(y - x);} \end{itemdescr} +\rSec2[range.repeat]{Repeat view} + +\rSec3[range.repeat.overview]{Overview} + +\pnum +\tcode{repeat_view} generates a sequence of elements +by repeatedly producing the same value. + +\pnum +\indexlibrarymember{repeat}{views}% +The name \tcode{views::repeat} denotes +a customization point object\iref{customization.point.object}. +Given subexpressions \tcode{E} and \tcode{F}, +the expressions \tcode{views::repeat(E)} and \tcode{views::repeat(E, F)} +are expression-equivalent to +\tcode{repeat_view(E)} and \tcode{repeat_view(E, F)}, respectively. + +\pnum +\begin{example} +\begin{codeblock} +for (int i : views::repeat(17, 4)) + cout << i << ' '; +// prints: 17 17 17 17 +\end{codeblock} +\end{example} + +\rSec3[range.repeat.view]{Class template \tcode{repeat_view}} + +\begin{codeblock} +namespace std::ranges { + template<@\libconcept{copy_constructible}@ W, @\libconcept{semiregular}@ Bound = unreachable_sentinel_t> + requires (is_object_v && @\libconcept{same_as}@> && + (@\exposid{is-integer-like}@ || @\libconcept{same_as}@)) + class @\libglobal{repeat_view}@ : public view_interface> { + private: + // \ref{range.repeat.iterator}, class \tcode{range_view::\exposid{iterator}} + struct @\exposid{iterator}@; // \expos + + @\exposid{copyable-box}@ @\exposid{value_}@ = W(); // \expos, see \ref{range.copy.wrap} + Bound @\exposid{bound_}@ = Bound(); // \expos + + public: + repeat_view() requires @\libconcept{default_initializable}@ = default; + + constexpr explicit repeat_view(const W& value, Bound bound = Bound()); + constexpr explicit repeat_view(W&& value, Bound bound = Bound()); + template + requires @\libconcept{constructible_from}@ && + @\libconcept{constructible_from}@ + constexpr explicit repeat_view(piecewise_construct_t, + tuple value_args, tuple bound_args = tuple<>{}); + + constexpr @\exposid{iterator}@ begin() const; + constexpr @\exposid{iterator}@ end() const requires (!@\libconcept{same_as}@); + constexpr unreachable_sentinel_t end() const noexcept; + + constexpr auto size() const requires (!@\libconcept{same_as}@); + }; + + template + repeat_view(W, Bound) -> repeat_view; +} +\end{codeblock} + +\indexlibraryctor{repeat_view}% +\begin{itemdecl} +constexpr explicit repeat_view(const W& value, Bound bound = Bound()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +If \tcode{Bound} is not \tcode{unreachable_sentinel_t}, +$\tcode{bound} \ge 0$. + +\pnum +\effects +Initializes \exposid{value_} with \tcode{value} and +\exposid{bound_} with \tcode{bound}. +\end{itemdescr} + +\indexlibraryctor{repeat_view}% +\begin{itemdecl} +constexpr explicit repeat_view(W&& value, Bound bound = Bound()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +If \tcode{Bound} is not \tcode{unreachable_sentinel_t}, $\tcode{bound} \ge 0$. + +\pnum +\effects +Initializes \exposid{value_} with \tcode{std::move(value)} and +\exposid{bound_} with \tcode{bound}. +\end{itemdescr} + +\indexlibraryctor{repeat_view}% +\begin{itemdecl} +template + requires @\libconcept{constructible_from}@ && + @\libconcept{constructible_from}@ +constexpr explicit repeat_view(piecewise_construct_t, + tuple value_args, tuple bound_args = tuple<>{}); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \exposid{value_} with arguments of types \exposid{WArgs...} +obtained by forwarding the elements of \tcode{value_args} and +initializes \exposid{bound_} with arguments of types \tcode{BoundArgs...} +obtained by forwarding the elements of \tcode{bound_args}. +(Here, forwarding an element \tcode{x} of type \tcode{U} within a tuple object +means calling \tcode{std::forward(x)}.) +\end{itemdescr} + +\indexlibrarymember{begin}{repeat_view}% +\begin{itemdecl} +constexpr @\exposid{iterator}@ begin() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return \exposid{iterator}(addressof(*value_));} +\end{itemdescr} + +\indexlibrarymember{end}{repeat_view}% +\begin{itemdecl} +constexpr @\exposid{iterator}@ end() const requires (!@\libconcept{same_as}@); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return \exposid{iterator}(addressof(*\exposid{value_}), \exposid{bound_});} +\end{itemdescr} + +\indexlibrarymember{end}{repeat_view}% +\begin{itemdecl} +constexpr unreachable_sentinel_t end() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return unreachable_sentinel;} +\end{itemdescr} + +\indexlibrarymember{size}{repeat_view}% +\begin{itemdecl} +constexpr auto size() const requires (!same_as); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return \exposid{to-unsigned-like}(\exposid{bound_});} +\end{itemdescr} + +\rSec3[range.repeat.iterator]{Class template \tcode{repeat_view::\exposid{iterator}}} + +\begin{codeblock} +namespace std::ranges { + template<@\libconcept{copy_constructible}@ W, @\libconcept{semiregular}@ Bound = unreachable_sentinel_t> + requires (is_object_v && @\libconcept{same_as}@> && + (@\exposid{is-integer-like}@ || @\libconcept{same_as}@)) + class repeat_view::@\exposid{iterator}@ { + private: + using @\exposid{index-type}@ = // \expos + conditional_t<@\libconcept{same_as}@, ptrdiff_t, Bound>; + const W* @\exposid{value_}@ = nullptr; // \expos + @\exposid{index-type}@ @\exposid{current_}@ = @\exposid{index-type}@(); // \expos + + constexpr explicit @\exposid{iterator}@(const W* value, @\exposid{index-type}@ b = @\exposid{index-type}@()); // \expos + + public: + using iterator_concept = random_access_iterator_tag; + using iterator_category = random_access_iterator_tag; + using value_type = W; + using difference_type = conditional_t<@\exposid{is-signed-integer-like}@<@\exposid{index-type}@>, + @\exposid{index-type}@, + @\placeholdernc{IOTA-DIFF-T}@(@\exposid{index-type}@)>; + + @\exposid{iterator}@() = default; + + constexpr const W& operator*() const noexcept; + + constexpr @\exposid{iterator}@& operator++(); + constexpr @\exposid{iterator}@ operator++(int); + + constexpr @\exposid{iterator}@& operator--(); + constexpr @\exposid{iterator}@ operator--(int); + + constexpr @\exposid{iterator}@& operator+=(difference_type n); + constexpr @\exposid{iterator}@& operator-=(difference_type n); + constexpr const W& operator[](difference_type n) const noexcept; + + friend constexpr bool operator==(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y); + friend constexpr auto operator<=>(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y); + + friend constexpr @\exposid{iterator}@ operator+(@\exposid{iterator}@ i, difference_type n); + friend constexpr @\exposid{iterator}@ operator+(difference_type n, @\exposid{iterator}@ i); + + friend constexpr @\exposid{iterator}@ operator-(@\exposid{iterator}@ i, difference_type n); + friend constexpr difference_type operator-(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y); + }; +} +\end{codeblock} + +\indexlibraryctor{repeat_view::iterator}% +\begin{itemdecl} +constexpr explicit @\exposid{iterator}@(const W* value, @\exposid{index-type}@ b = @\exposid{index-type}@()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +If \tcode{Bound} is not \tcode{unreachable_sentinel_t}, $\tcode{b} \ge 0$. + +\pnum +\effects +Initializes \exposid{value_} with \tcode{value} and +\exposid{current_} with \tcode{b}. +\end{itemdescr} + +\indexlibrarymember{operator*}{repeat_view::iterator}% +\begin{itemdecl} +constexpr const W& operator*() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return *\exposid{value_};} +\end{itemdescr} + +\indexlibrarymember{operator++}{repeat_view::iterator}% +\begin{itemdecl} +constexpr @\exposid{iterator}@& operator++(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +++@\exposid{current_}@; +return *this; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator++}{repeat_view::iterator}% +\begin{itemdecl} +constexpr @\exposid{iterator}@ operator++(int); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto tmp = *this; +++*this; +return tmp; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator--}{repeat_view::iterator}% +\begin{itemdecl} +constexpr @\exposid{iterator}@& operator--(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +If \tcode{Bound} is not \tcode{unreachable_sentinel_t}, +$\exposid{current_} > 0$. + +\pnum +\effects +Equivalent to: +\begin{codeblock} +--@\exposid{current_}@; +return *this; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator--}{repeat_view::iterator}% +\begin{itemdecl} +constexpr @\exposid{iterator}@ operator--(int); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto tmp = *this; +--*this; +return tmp; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator+=}{repeat_view::iterator}% +\begin{itemdecl} +constexpr @\exposid{iterator}@& operator+=(difference_type n); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +If \tcode{Bound} is not \tcode{unreachable_sentinel_t}, +$\exposid{current_} + \tcode{n} \ge 0$. + +\pnum +\effects +Equivalent to: +\begin{codeblock} +@\exposid{current_}@ += n; +return *this; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator-=}{repeat_view::iterator}% +\begin{itemdecl} +constexpr @\exposid{iterator}@& operator-=(difference_type n); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +If \tcode{Bound} is not \tcode{unreachable_sentinel_t}, +$\exposid{current_} - \tcode{n} \ge 0$. + +\pnum +\effects +Equivalent to: +\begin{codeblock} +@\exposid{current_}@ -= n; +return *this; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator[]}{repeat_view::iterator}% +\begin{itemdecl} +constexpr const W& operator[](difference_type n) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return *(*this + n);} +\end{itemdescr} + +\indexlibrarymember{operator==}{repeat_view::iterator}% +\begin{itemdecl} +friend constexpr bool operator==(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return x.\exposid{current_} == y.\exposid{current_};}. +\end{itemdescr} + +\indexlibrarymember{operator<=>}{repeat_view::iterator}% +\begin{itemdecl} +friend constexpr auto operator<=>(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return x.\exposid{current_} <=> y.\exposid{current_};}. +\end{itemdescr} + +\indexlibrarymember{operator+}{repeat_view::iterator}% +\begin{itemdecl} +friend constexpr @\exposid{iterator}@ operator+(@\exposid{iterator}@ i, difference_type n); +friend constexpr @\exposid{iterator}@ operator+(difference_type n, @\exposid{iterator}@ i); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +i += n; +return i; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator-}{repeat_view::iterator}% +\begin{itemdecl} +friend constexpr @\exposid{iterator}@ operator-(@\exposid{iterator}@ i, difference_type n); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +i -= n; +return i; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator-}{repeat_view::iterator}% +\begin{itemdecl} +friend constexpr difference_type operator-(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return static_cast(x.@\exposid{current_}@) - static_cast(y.@\exposid{current_}@); +\end{codeblock} +\end{itemdescr} + \rSec2[range.istream]{Istream view} \rSec3[range.istream.overview]{Overview} @@ -5220,6 +5651,21 @@ *(ranges::begin(E) + std::\linebreak{}min(ranges::distance(E), F)))}, except that \tcode{E} is evaluated only once. +\item +Otherwise, if \tcode{T} is +a specialization of \tcode{ranges::repeat_view}\iref{range.repeat.view}: +\begin{itemize} +\item +if \tcode{T} models \libconcept{sized_range}, +then +\begin{codeblock} +views::repeat(*E.@\exposid{value_}@, std::min(ranges::distance(E), F)) +\end{codeblock} +except that \tcode{E} is evaluated only once; +\item +otherwise, \tcode{views::repeat(*E.\exposid{value_}, static_cast(F))}. +\end{itemize} + \item Otherwise, \tcode{ranges::take_view(E, F)}. \end{itemize} @@ -5651,6 +6097,22 @@ std::min(ranges::distance(E), F)))}, except that \tcode{E} and \tcode{F} are each evaluated only once. +\item +Otherwise, if \tcode{T} is +a specialization of \tcode{ranges::repeat_view}\iref{range.repeat.view}: +\begin{itemize} +\item +if \tcode{T} models \libconcept{sized_range}, +then +\begin{codeblock} +views::repeat(*E.@\exposid{value_}@, ranges::distance(E) - std::min(ranges::distance(E), F)) +\end{codeblock} +except that \tcode{E} is evaluated only once; +\item +otherwise, ((void) F, \placeholdernc{decay-copy}(E)), +except that the evaluations of \tcode{E} and \tcode{F} are indeterminately sequenced. +\end{itemize} + \item Otherwise, \tcode{ranges::drop_view(E, F)}. \end{itemize} diff --git a/source/support.tex b/source/support.tex index 2560761550..581885c111 100644 --- a/source/support.tex +++ b/source/support.tex @@ -692,6 +692,7 @@ #define @\defnlibxname{cpp_lib_ranges_fold}@ 202207L // also in \libheader{algorithm} #define @\defnlibxname{cpp_lib_ranges_iota}@ 202202L // also in \libheader{numeric} #define @\defnlibxname{cpp_lib_ranges_join_with}@ 202202L // also in \libheader{ranges} +#define @\defnlibxname{cpp_lib_ranges_repeat}@ 202207L // also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_slide}@ 202202L // also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_starts_ends_with}@ 202106L // also in \libheader{algorithm} #define @\defnlibxname{cpp_lib_ranges_stride}@ 202207L // also in \libheader{ranges} From b5898afca1458ca155bd264f9743856476c579b3 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 5 Aug 2022 21:59:16 +0200 Subject: [PATCH 227/430] P2494R2 Relaxing range adaptors to allow for move only types Editorial changes: * template-heads have also been updated in the synopses of member class templates. --- source/ranges.tex | 79 ++++++++++++++++++++++++++-------------------- source/support.tex | 2 +- 2 files changed, 45 insertions(+), 36 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index 5b93f76c8a..d810425ffb 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -170,7 +170,7 @@ } // \ref{range.single}, single view - template<@\libconcept{copy_constructible}@ T> + template<@\libconcept{move_constructible}@ T> requires is_object_v class single_view; // freestanding @@ -256,7 +256,7 @@ namespace views { inline constexpr @\unspecnc@ filter = @\unspecnc@; } // freestanding // \ref{range.transform}, transform view - template<@\libconcept{input_range}@ V, @\libconcept{copy_constructible}@ F> + template<@\libconcept{input_range}@ V, @\libconcept{move_constructible}@ F> requires @\libconcept{view}@ && is_object_v && @\libconcept{regular_invocable}@> && @\exposconcept{can-reference}@>> @@ -421,7 +421,7 @@ namespace views { inline constexpr @\unspecnc@ zip = @\unspecnc@; } // freestanding // \ref{range.zip.transform}, zip transform view - template<@\libconcept{copy_constructible}@ F, @\libconcept{input_range}@... Views> + template<@\libconcept{move_constructible}@ F, @\libconcept{input_range}@... Views> requires (@\libconcept{view}@ && ...) && (sizeof...(Views) > 0) && is_object_v && @\libconcept{regular_invocable}@...> && @\exposconcept{can-reference}@...>> @@ -445,7 +445,7 @@ } // \ref{range.adjacent.transform}, adjacent transform view - template<@\libconcept{forward_range}@ V, @\libconcept{copy_constructible}@ F, size_t N> + template<@\libconcept{forward_range}@ V, @\libconcept{move_constructible}@ F, size_t N> requires @\seebelow@ class adjacent_transform_view; // freestanding @@ -2473,15 +2473,15 @@ \indexlibraryglobal{single_view}% \begin{codeblock} namespace std::ranges { - template<@\libconcept{copy_constructible}@ T> + template<@\libconcept{move_constructible}@ T> requires is_object_v class single_view : public view_interface> { private: - @\exposidnc{copyable-box}@ @\exposidnc{value_}@; // \expos{} (see \ref{range.copy.wrap}) + @\exposidnc{movable-box}@ @\exposidnc{value_}@; // \expos{} (see \ref{range.move.wrap}) public: single_view() requires @\libconcept{default_initializable}@ = default; - constexpr explicit single_view(const T& t); + constexpr explicit single_view(const T& t) requires @\libconcept{copy_constructible}@; constexpr explicit single_view(T&& t); template requires @\libconcept{constructible_from}@ @@ -2503,7 +2503,7 @@ \indexlibraryctor{single_view}% \begin{itemdecl} -constexpr explicit single_view(const T& t); +constexpr explicit single_view(const T& t) requires @\libconcept{copy_constructible}@;; \end{itemdecl} \begin{itemdescr} @@ -4072,31 +4072,32 @@ the initialization of the bound argument entities of the result, as specified above, are all well-formed. -\rSec2[range.copy.wrap]{Copyable wrapper} +\rSec2[range.move.wrap]{Movable wrapper} \pnum Many types in this subclause are specified in terms of -an exposition-only class template \exposid{copyable-box}. -\tcode{\exposid{copyable-box}} behaves exactly like \tcode{optional} +an exposition-only class template \exposid{movable-box}. +\tcode{\exposid{movable-box}} behaves exactly like \tcode{optional} with the following differences: \begin{itemize} -\item \tcode{\exposid{copyable-box}} constrains +\item \tcode{\exposid{movable-box}} constrains its type parameter \tcode{T} with \tcode{\libconcept{copy_constructible} \&\& is_object_v}. \item The default -constructor of \tcode{\exposid{copyable-box}} is equivalent to: +constructor of \tcode{\exposid{movable-box}} is equivalent to: \begin{codeblock} -constexpr @\exposid{copyable-box}@() noexcept(is_nothrow_default_constructible_v) +constexpr @\exposid{movable-box}@() noexcept(is_nothrow_default_constructible_v) requires @\libconcept{default_initializable}@ - : @\exposid{copyable-box}@{in_place} {} + : @\exposid{movable-box}@{in_place} {} \end{codeblock} \item If \tcode{\libconcept{copyable}} is not modeled, the copy assignment operator is equivalent to: \begin{codeblock} -constexpr @\exposid{copyable-box}@& operator=(const @\exposid{copyable-box}@& that) - noexcept(is_nothrow_copy_constructible_v) { +constexpr @\exposid{movable-box}@& operator=(const @\exposid{movable-box}@& that) + noexcept(is_nothrow_copy_constructible_v) + requires @\libconcept{copy_constructible}@ { if (this != addressof(that)) { if (that) emplace(*that); else reset(); @@ -4108,7 +4109,7 @@ \item If \tcode{\libconcept{movable}} is not modeled, the move assignment operator is equivalent to: \begin{codeblock} -constexpr @\exposid{copyable-box}@& operator=(@\exposid{copyable-box}@&& that) +constexpr @\exposid{movable-box}@& operator=(@\exposid{movable-box}@&& that) noexcept(is_nothrow_move_constructible_v) { if (this != addressof(that)) { if (that) emplace(std::move(*that)); @@ -4121,10 +4122,18 @@ \pnum \recommended -\tcode{\exposid{copyable-box}} should store only a \tcode{T} -if either \tcode{T} models \libconcept{copyable} or +\begin{itemize} +\item +If \tcode{\libconcept{copy_constructible}} is \tcode{true}, +\tcode{\exposid{movable-box}} should store only a \exposid{T} +if either \tcode{T} models \libconcept{copyable}, or \tcode{is_nothrow_move_constructible_v \&\& is_nothrow_copy_constructible_v} is \tcode{true}. +\item +Otherwise, \tcode{\exposid{movable-box}} should store only a \tcode{T} +if either \tcode{T} models \libconcept{movable} or +\tcode{is_nothrow_move_constructible_v} is \tcode{true}. +\end{itemize} \rSec2[range.nonprop.cache]{Non-propagating cache} @@ -4523,7 +4532,7 @@ class filter_view : public view_interface> { private: V @\exposid{base_}@ = V(); // \expos - @\exposidnc{copyable-box}@ @\exposid{pred_}@; // \expos + @\exposidnc{movable-box}@ @\exposid{pred_}@; // \expos // \ref{range.filter.iterator}, class \tcode{filter_view::\exposid{iterator}} class @\exposid{iterator}@; // \expos @@ -4943,7 +4952,7 @@ \indexlibrarymember{size}{transform_view}% \begin{codeblock} namespace std::ranges { - template<@\libconcept{input_range}@ V, @\libconcept{copy_constructible}@ F> + template<@\libconcept{input_range}@ V, @\libconcept{move_constructible}@ F> requires @\libconcept{view}@ && is_object_v && @\libconcept{regular_invocable}@> && @\exposconcept{can-reference}@>> @@ -4956,7 +4965,7 @@ template struct @\exposid{sentinel}@; // \expos V @\exposid{base_}@ = V(); // \expos - @\placeholdernc{copyable-box}@ @\exposid{fun_}@; // \expos + @\placeholdernc{movable-box}@ @\exposid{fun_}@; // \expos public: transform_view() requires @\libconcept{default_initializable}@ && @\libconcept{default_initializable}@ = default; @@ -5096,7 +5105,7 @@ \indexlibraryglobal{transform_view::iterator}% \begin{codeblock} namespace std::ranges { - template<@\libconcept{input_range}@ V, @\libconcept{copy_constructible}@ F> + template<@\libconcept{input_range}@ V, @\libconcept{move_constructible}@ F> requires @\libconcept{view}@ && is_object_v && @\libconcept{regular_invocable}@> && @\exposconcept{can-reference}@>> @@ -5480,7 +5489,7 @@ \indexlibraryglobal{transform_view::sentinel}% \begin{codeblock} namespace std::ranges { - template<@\libconcept{input_range}@ V, @\libconcept{copy_constructible}@ F> + template<@\libconcept{input_range}@ V, @\libconcept{move_constructible}@ F> requires @\libconcept{view}@ && is_object_v && @\libconcept{regular_invocable}@> && @\exposconcept{can-reference}@>> @@ -5910,7 +5919,7 @@ template class @\exposidnc{sentinel}@; // \expos V @\exposid{base_}@ = V(); // \expos - @\exposidnc{copyable-box}@ @\exposid{pred_}@; // \expos + @\exposidnc{movable-box}@ @\exposid{pred_}@; // \expos public: take_while_view() requires @\libconcept{default_initializable}@ && @\libconcept{default_initializable}@ = default; @@ -6277,7 +6286,7 @@ private: V @\exposid{base_}@ = V(); // \expos - @\placeholder{copyable-box}@ @\exposid{pred_}@; @\itcorr[-1]@ // \expos + @\placeholder{movable-box}@ @\exposid{pred_}@; @\itcorr[-1]@ // \expos }; template @@ -10007,12 +10016,12 @@ \indexlibrarymember{size}{zip_transform_view}% \begin{codeblock} namespace std::ranges { - template<@\libconcept{copy_constructible}@ F, @\libconcept{input_range}@... Views> + template<@\libconcept{mmove_constructible}@ F, @\libconcept{input_range}@... Views> requires (@\libconcept{view}@ && ...) && (sizeof...(Views) > 0) && is_object_v && @\libconcept{regular_invocable}@...> && @\exposconcept{can-reference}@...>> class zip_transform_view : public view_interface> { - @\exposidnc{copyable-box}@ @\exposid{fun_}@; // \expos + @\exposidnc{movable-box}@ @\exposid{fun_}@; // \expos zip_view @\exposid{zip_}@; // \expos using @\exposidnc{InnerView}@ = zip_view; // \expos @@ -10088,7 +10097,7 @@ \indexlibraryglobal{zip_transform_view::iterator}% \begin{codeblock} namespace std::ranges { - template<@\libconcept{copy_constructible}@ F, @\libconcept{input_range}@... Views> + template<@\libconcept{move_constructible}@ F, @\libconcept{input_range}@... Views> requires (@\libconcept{view}@ && ...) && (sizeof...(Views) > 0) && is_object_v && @\libconcept{regular_invocable}@...> && @\exposconcept{can-reference}@...>> @@ -10400,7 +10409,7 @@ \indexlibraryglobal{zip_transform_view::sentinel}% \begin{codeblock} namespace std::ranges { - template<@\libconcept{copy_constructible}@ F, @\libconcept{input_range}@... Views> + template<@\libconcept{move_constructible}@ F, @\libconcept{input_range}@... Views> requires (@\libconcept{view}@ && ...) && (sizeof...(Views) > 0) && is_object_v && @\libconcept{regular_invocable}@...> && @\exposconcept{can-reference}@...>> @@ -11165,12 +11174,12 @@ \indexlibrarymember{size}{adjacent_transform_view}% \begin{codeblock} namespace std::ranges { - template<@\libconcept{forward_range}@ V, @\libconcept{copy_constructible}@ F, size_t N> + template<@\libconcept{forward_range}@ V, @\libconcept{move_constructible}@ F, size_t N> requires @\libconcept{view}@ && (N > 0) && is_object_v && @\libconcept{regular_invocable}@, N)...> && @\exposconcept{can-reference}@, N)...>> class adjacent_transform_view : public view_interface> { - @\exposidnc{copyable-box}@ @\exposid{fun_}@; // \expos + @\exposidnc{movable-box}@ @\exposid{fun_}@; // \expos adjacent_view @\exposid{inner_}@; // \expos using @\exposidnc{InnerView}@ = adjacent_view; // \expos @@ -11244,7 +11253,7 @@ \indexlibraryglobal{adjacent_transform_view::iterator}% \begin{codeblock} namespace std::ranges { - template<@\libconcept{forward_range}@ V, @\libconcept{copy_constructible}@ F, size_t N> + template<@\libconcept{forward_range}@ V, @\libconcept{move_constructible}@ F, size_t N> requires @\libconcept{view}@ && (N > 0) && is_object_v && @\libconcept{regular_invocable}@, N)...> && @\exposconcept{can-reference}@, N)...>> @@ -11547,7 +11556,7 @@ \indexlibraryglobal{adjacent_transform_view::sentinel}% \begin{codeblock} namespace std::ranges { - template<@\libconcept{forward_range}@ V, @\libconcept{copy_constructible}@ F, size_t N> + template<@\libconcept{forward_range}@ V, @\libconcept{move_constructible}@ F, size_t N> requires @\libconcept{view}@ && (N > 0) && is_object_v && @\libconcept{regular_invocable}@, N)...> && @\exposconcept{can-reference}@, N)...>> diff --git a/source/support.tex b/source/support.tex index 581885c111..7f87026a32 100644 --- a/source/support.tex +++ b/source/support.tex @@ -681,7 +681,7 @@ #define @\defnlibxname{cpp_lib_polymorphic_allocator}@ 201902L // also in \libheader{memory_resource} #define @\defnlibxname{cpp_lib_print}@ 202207L // also in \libheader{print}, \libheader{ostream} #define @\defnlibxname{cpp_lib_quoted_string_io}@ 201304L // also in \libheader{iomanip} -#define @\defnlibxname{cpp_lib_ranges}@ 202202L +#define @\defnlibxname{cpp_lib_ranges}@ 202207L // also in \libheader{algorithm}, \libheader{functional}, \libheader{iterator}, \libheader{memory}, \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_as_const}@ 202207L // also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_as_rvalue}@ 202207L // also in \libheader{ranges} From 1df7957218cbfbe1aa81c40077fc7341b6b0f8dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Wed, 17 Aug 2022 21:59:14 +0100 Subject: [PATCH 228/430] [range.chunk.by.view] Change copyable-box to movable-box. This change wasn't requested by P2494R2, but is necessary. --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index d810425ffb..fb70857194 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -13302,7 +13302,7 @@ requires @\libconcept{view}@ && is_object_v class chunk_by_view : public view_interface> { V @\exposid{base_}@ = V(); // \expos - @\exposid{copyable-box}@ @\exposid{pred_}@ = Pred(); // \expos + @\exposid{movable-box}@ @\exposid{pred_}@ = Pred(); // \expos // \ref{range.chunk.by.iter}, class \tcode{chunk_by_view::\exposid{iterator}} class @\exposid{iterator}@; // \expos From d5aea2868081bbedf6e6fbdd556f1b0caaa380d9 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 5 Aug 2022 22:06:20 +0200 Subject: [PATCH 229/430] [range.repeat.view] Apply modifications from P2494R2 --- source/ranges.tex | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index fb70857194..0178c58b70 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -190,7 +190,7 @@ namespace views { inline constexpr @\unspecnc@ iota = @\unspecnc@; } // freestanding // \ref{range.repeat}, repeat view - template<@\libconcept{copy_constructible}@ W, @\libconcept{semiregular}@ Bound = unreachable_sentinel_t> + template<@\libconcept{move_constructible}@ W, @\libconcept{semiregular}@ Bound = unreachable_sentinel_t> requires (is_object_v && @\libconcept{same_as}@> && (@\exposid{is-integer-like}@ || @\libconcept{same_as}@)) class repeat_view; @@ -3365,7 +3365,7 @@ \begin{codeblock} namespace std::ranges { - template<@\libconcept{copy_constructible}@ W, @\libconcept{semiregular}@ Bound = unreachable_sentinel_t> + template<@\libconcept{move_constructible}@ W, @\libconcept{semiregular}@ Bound = unreachable_sentinel_t> requires (is_object_v && @\libconcept{same_as}@> && (@\exposid{is-integer-like}@ || @\libconcept{same_as}@)) class @\libglobal{repeat_view}@ : public view_interface> { @@ -3373,13 +3373,14 @@ // \ref{range.repeat.iterator}, class \tcode{range_view::\exposid{iterator}} struct @\exposid{iterator}@; // \expos - @\exposid{copyable-box}@ @\exposid{value_}@ = W(); // \expos, see \ref{range.copy.wrap} + @\exposid{movable-box}@ @\exposid{value_}@ = W(); // \expos, see \ref{range.move.wrap} Bound @\exposid{bound_}@ = Bound(); // \expos public: repeat_view() requires @\libconcept{default_initializable}@ = default; - constexpr explicit repeat_view(const W& value, Bound bound = Bound()); + constexpr explicit repeat_view(const W& value, Bound bound = Bound()) + requires @\libconcept{copy_constructible}@; constexpr explicit repeat_view(W&& value, Bound bound = Bound()); template requires @\libconcept{constructible_from}@ && @@ -3500,7 +3501,7 @@ \begin{codeblock} namespace std::ranges { - template<@\libconcept{copy_constructible}@ W, @\libconcept{semiregular}@ Bound = unreachable_sentinel_t> + template<@\libconcept{move_constructible}@ W, @\libconcept{semiregular}@ Bound = unreachable_sentinel_t> requires (is_object_v && @\libconcept{same_as}@> && (@\exposid{is-integer-like}@ || @\libconcept{same_as}@)) class repeat_view::@\exposid{iterator}@ { From ddbf4827b434ba453e32f02c688b20d29c39c938 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 29 Jul 2022 12:03:39 +0200 Subject: [PATCH 230/430] P2499R0 string_view range constructor should be explicit --- source/strings.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/strings.tex b/source/strings.tex index b46c8f912f..14b81b8661 100644 --- a/source/strings.tex +++ b/source/strings.tex @@ -643,7 +643,7 @@ template constexpr basic_string_view(It begin, End end); template - constexpr basic_string_view(R&& r); + constexpr explicit basic_string_view(R&& r); // \ref{string.view.iterators}, iterator support constexpr const_iterator begin() const noexcept; @@ -850,7 +850,7 @@ \indexlibraryctor{basic_string_view}% \begin{itemdecl} template - constexpr basic_string_view(R&& r); + constexpr explicit basic_string_view(R&& r); \end{itemdecl} \begin{itemdescr} From 7982cf0c8be69aff7e78034087b3ba0825f4b92a Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sun, 31 Jul 2022 00:59:55 +0200 Subject: [PATCH 231/430] P2502R2 std::generator: Synchronous Coroutine Generator for Ranges --- source/lib-intro.tex | 1 + source/ranges.tex | 689 ++++++++++++++++++++++++++++++++++++++++++- source/support.tex | 1 + 3 files changed, 689 insertions(+), 2 deletions(-) diff --git a/source/lib-intro.tex b/source/lib-intro.tex index da95382659..91f4693725 100644 --- a/source/lib-intro.tex +++ b/source/lib-intro.tex @@ -1087,6 +1087,7 @@ \tcode{} \\ \tcode{} \\ \tcode{} \\ +\tcode{} \\ \tcode{} \\ \tcode{} \\ \tcode{} \\ diff --git a/source/ranges.tex b/source/ranges.tex index 0178c58b70..5a260f2657 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -10,7 +10,7 @@ The following subclauses describe range and view requirements, and components for -range primitives +range primitives and range generators as summarized in \tref{range.summary}. \begin{libsumtab}{Ranges library summary}{range.summary} @@ -18,7 +18,8 @@ \ref{range.req} & Requirements & \\ \ref{range.utility} & Range utilities & \\ \ref{range.factories} & Range factories & \\ - \ref{range.adaptors} & Range adaptors & \\ + \ref{range.adaptors} & Range adaptors & \\ \rowsep + \ref{coro.generator} & Range generators & \libheader{generator} \\ \end{libsumtab} \rSec1[ranges.syn]{Header \tcode{} synopsis} @@ -140,6 +141,10 @@ // \ref{range.dangling}, dangling iterator handling struct dangling; // freestanding + // \ref{ranges.elementsof}, class template \tcode{elements_of} + template<@\libconcept{range}@ R, class Allocator = allocator> + struct elements_of; + template<@\libconcept{range}@ R> using borrowed_iterator_t = @\seebelow@; // freestanding @@ -2183,6 +2188,38 @@ denote \tcode{dangling}. \end{itemize} +\rSec2[ranges.elementsof]{Class template \tcode{elements_of}} + +Specializations of \tcode{elements_of} encapsulate a range and +act as a tag in overload sets to disambiguate +when a range should be treated as a sequence +rather than a single value. + +\begin{example} +\begin{codeblock} +template +std::generator f(std::ranges::input_range auto&& rng) { + if constexpr (YieldElements) + co_yield std::ranges::elements_of(rng); // yield each element of \tcode{rng} + else + co_yield rng; // yield \tcode{rng} as a single value +} +\end{codeblock} +\end{example} + +\begin{codeblock} +namespace std::ranges { + template<@\libconcept{range}@ R, class Allocator = allocator> + struct elements_of { + [[no_unique_address]] R range; + [[no_unique_address]] Allocator allocator = Allocator(); + }; + + template> + elements_of(R&&, Allocator = Allocator()) -> elements_of; +} +\end{codeblock} + \rSec2[range.utility.conv]{Range conversions} \rSec3[range.utility.conv.general]{General} @@ -14961,3 +14998,651 @@ for\newline every integer $0 \le i \le \tcode{sizeof...(Vs)}$. \end{itemize} \end{itemdescr} + +\rSec1[coro.generator]{Range generators} + +\rSec2[coroutine.generator.overview]{Overview} + +\pnum +Class template \tcode{generator} presents +a \libconcept{view} of the elements yielded by the evaluation of a coroutine. + +\pnum +A \tcode{generator} generates a sequence of elements by +repeatedly resuming the coroutine from which it was returned. +Elements of the sequence are produced by the coroutine +each time a \tcode{co_yield} statement is evaluated. +When the \tcode{co_yield} statement is of the form +\tcode{co_yield elements_of(rng)}, +each element of the range \tcode{rng} +is successively produced as an element of the sequence. +\begin{example} +\begin{codeblock} +std::generator ints(int start = 0) { + while (true) + co_yield start++; +} + +void f() { + for (auto i : ints() | std::views::take(3)) + std::cout << i << ' '; // prints 0 1 2 +} +\end{codeblock} +\end{example} + +\rSec2[generator.syn]{Header \tcode{} synopsis} + +\indexheader{generator}% +\begin{codeblock} +namespace std { + // \ref{coro.generator.class}, class template \tcode{generator} + template + class generator; +} +\end{codeblock} + +\rSec2[coro.generator.class]{Class template \tcode{generator}} + +\begin{codeblock} +namespace std { + template + class @\libglobal{generator}@ : public ranges::view_interface> { + private: + using @\exposid{value}@ = conditional_t, remove_cvref_t, V>; // \expos + using @\exposid{reference}@ = conditional_t, Ref&&, Ref>; // \expos + + // \ref{coro.generator.iterator}, class \tcode{generator::\exposid{iterator}} + class @\exposidnc{iterator}@; // \expos + + public: + using yielded = + conditional_t, @\exposid{reference}@, const @\exposid{reference}@&>; + + // \ref{coro.generator.promise}, class \tcode{generator::promise_type} + class promise_type; + + generator(const generator&) = delete; + generator(generator&& other) noexcept; + + ~generator(); + + generator& operator=(generator other) noexcept; + + @\exposid{iterator}@ begin(); + default_sentinel_t end() const noexcept; + + private: + coroutine_handle @\exposid{coroutine_}@ = nullptr; // \expos + unique_ptr>> @\exposid{active_}@; // \expos + }; +} +\end{codeblock} + +\pnum +\mandates +\begin{itemize} +\item +If \tcode{Allocator} is not \tcode{void}, +\tcode{allocator_traits::pointer} is a pointer type. +\item +\exposid{value} is a cv-unqualified object type. +\item +\exposid{reference} is either a reference type, or +a cv-unqualified object type that models \libconcept{copy_constructible}. +\item +Let \tcode{RRef} denote \tcode{remove_reference_t<\exposid{reference}>\&\&} +if \exposid{reference} is a reference type, +and \exposid{reference} otherwise. +Each of: +\begin{itemize} +\item \tcode{\libconcept{common_reference_with}<\exposid{reference}\&\&, \exposid{value}\&>}, +\item \tcode{\libconcept{common_reference_with}<\exposid{reference}\&\&, RRef\&\&>}, and +\item \tcode{\libconcept{common_reference_with}} +\end{itemize} +is modeled. +\begin{note} +These requirements ensure the exposition-only \exposid{iterator} type +can model \libconcept{indirectly_readable} and thus \libconcept{input_iterator}. +\end{note} +\end{itemize} + +\pnum +If \tcode{Allocator} is not \tcode{void}, +it shall meet the \oldconcept{Allocator} requirements. + +\pnum +Specializations of \tcode{generator} model +\libconcept{view} and \libconcept{input_range}. + +\pnum +The behavior of a program that adds a specialization +for \tcode{generator} is undefined. + +\rSec2[coro.generator.members]{Members} + +\indexlibraryctor{generator}% +\begin{itemdecl} +generator(generator&& other) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \exposid{coroutine_} with +\tcode{exchange(other.\exposid{coroutine_}, \{\})} and +\exposid{active_} with +\tcode{exchange(\brk{}other.active_, nullptr)}. + +\pnum +\begin{note} +Iterators previously obtained from \tcode{other} are not invalidated; +they become iterators into \tcode{*this}. +\end{note} +\end{itemdescr} + +\indexlibrarydtor{generator}% +\begin{itemdecl} +~generator(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +if (@\exposid{coroutine_}@) { + @\exposid{coroutine_}@.destroy(); +} +\end{codeblock} + +\pnum +\begin{note} +Ownership of recursively yielded generators +is held in awaitable objects +in the coroutine frame of the yielding generator, +so destroying the root generator +effectively destroys the entire stack of yielded generators. +\end{note} +\end{itemdescr} + +\indexlibrarymember{operator=}{generator}% +\begin{itemdecl} +generator& operator=(generator other) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +swap(@\exposid{coroutine_}@, other.@\exposid{coroutine_}@); +swap(@\exposid{active_}@, other.@\exposid{active_}@); +\end{codeblock} + +\pnum +\returns +\tcode{*this}. + +\pnum +\begin{note} +Iterators previously obtained from \tcode{other} are not invalidated; +they become iterators into \tcode{*this}. +\end{note} +\end{itemdescr} + +\indexlibrarymember{begin}{generator}% +\begin{itemdecl} +@\exposid{iterator}@ begin(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\exposid{coroutine_} refers to a coroutine +suspended at its initial suspend point\iref{dcl.fct.def.coroutine}. + +\pnum +\effects +Pushes \exposid{coroutine_} into \tcode{*\exposid{active_}}, +then evaluates \tcode{\exposid{coroutine_}.resume()}. + +\pnum +\returns +An \exposid{iterator} object +whose member \exposid{coroutine_} +refers to the same coroutine as does +\exposid{coroutine_}. + +\pnum +\begin{note} +A program that calls \tcode{begin} more than once on the same generator +has undefined behavior. +\end{note} +\end{itemdescr} + +\indexlibrarymember{end}{generator}% +\begin{itemdecl} +default_sentinel_t end() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{default_sentinel}. +\end{itemdescr} + +\rSec2[coro.generator.promise]{Class \tcode{generator::promise_type}} + +\begin{codeblock} +namespace std { + template + class generator::promise_type { + public: + generator get_return_object() noexcept; + + suspend_always initial_suspend() const noexcept { return {}; } + auto final_suspend() noexcept; + + suspend_always yield_value(yielded val) noexcept; + + auto yield_value(const remove_reference_t& lval) + requires is_rvalue_reference_v && + @\libconcept{constructible_from}@, const remove_reference_t&>; + + template + requires @\libconcept{same_as}@::yielded, yielded> + auto yield_value(ranges::elements_of&&, Unused> g) noexcept; + + template + requires @\libconcept{convertible_to}@, yielded> + auto yield_value(ranges::elements_of r) noexcept; + + void await_transform() = delete; + + void return_void() const noexcept {} + void unhandled_exception(); + + void* operator new(size_t size) + requires @\libconcept{same_as}@ || @\libconcept{default_initializable}@; + + template + requires @\libconcept{same_as}@ || @\libconcept{convertible_to}@ + void* operator new(size_t size, allocator_arg_t, const Alloc& alloc, const Args&...); + + template + requires @\libconcept{same_as}@ || @\libconcept{convertible_to}@ + void* operator new(size_t size, const This&, allocator_arg_t, const Alloc& alloc, + const Args&...); + + void operator delete(void* pointer, size_t size) noexcept; + + private: + add_pointer_t @\exposid{value_}@ = nullptr; // \expos + exception_ptr @\exposid{except_}@; // \expos + }; +} +\end{codeblock} + +\indexlibrarymember{get_return_object}{generator::promise_type}% +\begin{itemdecl} +generator get_return_object() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A \tcode{generator} object whose member \exposid{coroutine_} +is \tcode{coroutine_handle::\brk{}from_promise(*this)}, +and whose member \exposid{active_} points to an empty stack. +\end{itemdescr} + +\indexlibrarymember{final_suspend}{generator::promise_type}% +\begin{itemdecl} +auto final_suspend() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +A handle referring to the coroutine +whose promise object is \tcode{*this} +is at the top of \tcode{*\exposid{active_}} +of some \tcode{generator} object \tcode{x}. +This function is called by that coroutine +upon reaching its final suspend point\iref{dcl.fct.def.coroutine}. + +\pnum +\returns +An awaitable object of unspecified type\iref{expr.await} +whose member functions arrange for the +calling coroutine to be suspended, +pop the coroutine handle +from the top of \tcode{*x.\exposid{active_}}, +and resume execution of the coroutine referred to by +\tcode{x.\exposid{active_}->top()} +if \tcode{*x.\exposid{active_}} is not empty. +If it is empty, control flow returns to the +current coroutine caller or resumer\iref{dcl.fct.def.coroutine}. +\end{itemdescr} + +\indexlibrarymember{yield_value}{generator::promise_type}% +\begin{itemdecl} +suspend_always yield_value(yielded val) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{\exposid{value_} = addressof(val)}. + +\pnum +\returns +\tcode{\{\}}. +\end{itemdescr} + +\indexlibrarymember{yield_value}{generator::promise_type}% +\begin{itemdecl} +auto yield_value(const remove_reference_t& lval) + requires is_rvalue_reference_v && + @\libconcept{constructible_from}@, const remove_reference_t&>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +A handle referring to the coroutine +whose promise object is \tcode{*this} +is at the top of \tcode{*\exposid{active_}} +of some \tcode{generator} object \tcode{x}. + +\pnum +\returns +An awaitable object of an unspecified type\iref{expr.await} +that stores an object of type \tcode{remove_cvref_t} +direct-non-list-initialized with \tcode{lval}, +whose member functions arrange for +\exposid{value_} to point to that stored object +and then suspend the coroutine. + +\pnum +\throws +Any exception thrown by the initialization of the stored object. + +\pnum +\remarks +A \grammarterm{yield-expression} that calls this function +has type \tcode{void}\iref{expr.yield}. +\end{itemdescr} + +\indexlibrarymember{yield_value}{generator::promise_type}% +\begin{itemdecl} +template + requires @\libconcept{same_as}@::yielded, yielded> + auto yield_value(ranges::elements_of&&, Unused> g) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +A handle referring to the coroutine +whose promise object is \tcode{*this} +is at the top of \tcode{*\exposid{active_}} +of some \tcode{generator} object \tcode{x}. +The coroutine referred to by +\tcode{g.range.\exposid{coroutine_}} +is suspended at its initial suspend point. + +\pnum +\returns +An awaitable object of an unspecified type\iref{expr.await} +which takes ownership of the generator \tcode{g.range}, +whose member \tcode{await_ready} returns \tcode{false}, +whose member \tcode{await_suspend} +pushes \tcode{g.range.\exposid{coroutine_}} +into \tcode{*x.\exposid{active_}} +and resumes execution of the coroutine referred to +by \tcode{g.range.\brk{}\exposid{coroutine_}}, and +whose member \tcode{await_resume} evaluates +\tcode{rethrow_exception(\exposid{except_})} +if \tcode{bool(\exposid{ex\-cept_})} is \tcode{true}. +If \tcode{bool(\exposid{except_})} is \tcode{false}, +the \tcode{await_resume} member has no effects. + +\pnum +\remarks +A \grammarterm{yield-expression} that calls this function +has type \tcode{void}\iref{expr.yield}. +\end{itemdescr} + +\indexlibrarymember{yield_value}{generator::promise_type}% +\begin{itemdecl} +template + requires @\libconcept{convertible_to}@, yielded> + auto yield_value(ranges::elements_of r) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto nested = [](allocator_arg_t, Alloc, ranges::iterator_t i, + ranges::sentinel_t s) + -> generator, Alloc> { + for (; i != s; ++i) { + co_yield static_cast(*i); + } + }; +return yield_value(ranges::elements_of(nested( + allocator_arg, r.allocator, ranges::begin(r.range), ranges::end(r.range)))); +\end{codeblock} + +\pnum +\remarks +A \grammarterm{yield-expression} that calls this function +has type \tcode{void}\iref{expr.yield}. +\end{itemdescr} + +\indexlibrarymember{unhandled_exception}{generator::promise_type}% +\begin{itemdecl} +void unhandled_exception(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +A handle referring to the coroutine whose promise object is \tcode{*this} +is at the top of \tcode{*\exposid{active_}} +of some \tcode{generator} object \tcode{x}. + +\pnum +\effects +If the handle referring to the coroutine +whose promise object is \tcode{*this} +is the sole element of \tcode{*x.\exposid{active_}}, +equivalent to: \tcode{throw;} +Otherwise, assigns \tcode{current_exception()} to \exposid{except_}. +\end{itemdescr} + +\indexlibrarymember{operator new}{generator::promise_type}% +\begin{itemdecl} +void* operator new(size_t size) + requires @\libconcept{same_as}@ || @\libconcept{default_initializable}@; + +template + requires @\libconcept{same_as}@ || @\libconcept{convertible_to}@ + void* operator new(size_t size, allocator_arg_t, const Alloc& alloc, const Args&...); + +template + requires @\libconcept{same_as}@ || @\libconcept{convertible_to}@ + void* operator new(size_t size, const This&, allocator_arg_t, const Alloc& alloc, + const Args&...); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{A} be +\begin{itemize} +\item +\tcode{Allocator}, if it is not \tcode{void}, +\item +\tcode{Alloc} for the overloads with a template parameter \tcode{Alloc}, or +\item +\tcode{allocator} otherwise. +\end{itemize} +Let \tcode{B} be \tcode{allocator_traits::template rebind_alloc} +where \tcode{U} is an unspecified type whose size and alignment +are both \mname{STDCPP_DEFAULT_NEW_ALIGNMENT}. + +\pnum +\mandates +\tcode{allocator_traits::pointer} is a pointer type. + +\pnum +\effects +Initializes an allocator \tcode{b} of type \tcode{B} with \tcode{A(alloc)}, +for the overloads with a function parameter \tcode{alloc}, +and with \tcode{A()} otherwise. +Uses \tcode{b} to allocate storage for the smallest array +of \tcode{U} sufficient to provide storage for +a coroutine state of size \tcode{size}, and +unspecified additional state necessary to ensure that +\tcode{operator delete} can later deallocate this memory block +with an allocator equal to \tcode{b}. + +\pnum +\returns +A pointer to the allocated storage. +\end{itemdescr} + +\indexlibrarymember{operator delete}{generator::promise_type}% +\begin{itemdecl} +void operator delete(void* pointer, size_t size) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{pointer} was returned from an invocation of +one of the above overloads of \tcode{operator new} +with a \tcode{size} argument equal to \tcode{size}. + +\pnum +\effects +Deallocates the storage pointed to by \tcode{pointer} +using an allocator equivalent to that used to allocate it. +\end{itemdescr} + +\rSec2[coro.generator.iterator]{Class \tcode{generator::\exposid{iterator}}} + +\begin{codeblock} +namespace std { + template + class generator::@\exposid{iterator}@ { + public: + using value_type = @\exposid{value}@; + using difference_type = ptrdiff_t; + + @\exposid{iterator}@(@\exposid{iterator}@&& other) noexcept; + @\exposid{iterator}@& operator=(@\exposid{iterator}@&& other) noexcept; + + @\exposid{reference}@ operator*() const noexcept(is_nothrow_copy_constructible_v<@\exposid{reference}@>); + @\exposid{iterator}@& operator++(); + void operator++(int); + + friend bool operator==(@\exposid{iterator}@ i, default_sentinel_t); + + private: + coroutine_handle @\exposid{coroutine_}@; // \expos + }; +} +\end{codeblock} + +\indexlibraryctor{generator::iterator}% +\begin{itemdecl} +@\exposid{iterator}@(@\exposid{iterator}@&& other) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \exposid{coroutine_} +with \tcode{exchange(other.\exposid{coroutine_}, \{\})}. +\end{itemdescr} + +\indexlibrarymember{operator=}{generator::iterator}% +\begin{itemdecl} +@\exposid{iterator}@& operator=(@\exposid{iterator}@&& other) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to +\tcode{\exposid{coroutine_} = exchange(other.\exposid{coroutine_}, \{\})}. + +\pnum +\returns +\tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator*}{generator::iterator}% +\begin{itemdecl} +@\exposid{reference}@ operator*() const noexcept(is_nothrow_copy_constructible_v<@\exposid{reference}@>); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +For some \tcode{generator} object \tcode{x}, +\exposid{coroutine_} is in \tcode{*x.\exposid{active_}} and +\tcode{x.\exposid{active_}->top()} refers to +a suspended coroutine with promise object \tcode{p}. + +\pnum +\effects +Equivalent to: +\tcode{return static_cast<\exposid{reference}>(*p.\exposid{value_});} +\end{itemdescr} + +\indexlibrarymember{operator++}{generator::iterator}% +\begin{itemdecl} +@\exposid{iterator}@& operator++(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +For some \tcode{generator} object \tcode{x}, +\exposid{coroutine_} is in \tcode{*x.\exposid{active_}}. + +\pnum +\effects +Equivalent to \tcode{x.\exposid{active_}->top().resume()}. + +\pnum +\returns +\tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator++}{generator::iterator}% +\begin{itemdecl} +void operator++(int); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{++*this}. +\end{itemdescr} + +\indexlibrarymember{operator==}{generator::iterator}% +\begin{itemdecl} +friend bool operator==(@\exposid{iterator}@ i, default_sentinel_t); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return i.\exposid{coroutine_}.done();} +\end{itemdescr} diff --git a/source/support.tex b/source/support.tex index 7f87026a32..cca93aaecb 100644 --- a/source/support.tex +++ b/source/support.tex @@ -627,6 +627,7 @@ #define @\defnlibxname{cpp_lib_format}@ 202207L // also in \libheader{format} #define @\defnlibxname{cpp_lib_forward_like}@ 202207L // also in \libheader{utility} #define @\defnlibxname{cpp_lib_gcd_lcm}@ 201606L // also in \libheader{numeric} +#define @\defnlibxname{cpp_lib_generator}@ 202207L // also in \libheader{generator} #define @\defnlibxname{cpp_lib_generic_associative_lookup}@ 201304L // also in \libheader{map}, \libheader{set} #define @\defnlibxname{cpp_lib_generic_unordered_lookup}@ 201811L // also in \libheader{unordered_map}, \libheader{unordered_set} From f201a8648e8e55485081a5868f347c1f06b7f2a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Wed, 17 Aug 2022 22:39:30 +0100 Subject: [PATCH 232/430] [coro.generator, ranges.elementsof] Replace {R,r}ng with just {R,r}. It is more customary to refer to ranges as just "R", not "Rng". --- source/ranges.tex | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index 5a260f2657..1ecea21896 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -2198,11 +2198,11 @@ \begin{example} \begin{codeblock} template -std::generator f(std::ranges::input_range auto&& rng) { +std::generator f(std::ranges::input_range auto&& r) { if constexpr (YieldElements) - co_yield std::ranges::elements_of(rng); // yield each element of \tcode{rng} + co_yield std::ranges::elements_of(r); // yield each element of \tcode{r} else - co_yield rng; // yield \tcode{rng} as a single value + co_yield r; // yield \tcode{r} as a single value } \end{codeblock} \end{example} @@ -15013,8 +15013,8 @@ Elements of the sequence are produced by the coroutine each time a \tcode{co_yield} statement is evaluated. When the \tcode{co_yield} statement is of the form -\tcode{co_yield elements_of(rng)}, -each element of the range \tcode{rng} +\tcode{co_yield elements_of(r)}, +each element of the range \tcode{r} is successively produced as an element of the sequence. \begin{example} \begin{codeblock} @@ -15253,9 +15253,9 @@ requires @\libconcept{same_as}@::yielded, yielded> auto yield_value(ranges::elements_of&&, Unused> g) noexcept; - template - requires @\libconcept{convertible_to}@, yielded> - auto yield_value(ranges::elements_of r) noexcept; + template + requires @\libconcept{convertible_to}@, yielded> + auto yield_value(ranges::elements_of r) noexcept; void await_transform() = delete; @@ -15416,9 +15416,9 @@ \indexlibrarymember{yield_value}{generator::promise_type}% \begin{itemdecl} -template - requires @\libconcept{convertible_to}@, yielded> - auto yield_value(ranges::elements_of r) noexcept; +template + requires @\libconcept{convertible_to}@, yielded> + auto yield_value(ranges::elements_of r) noexcept; \end{itemdecl} \begin{itemdescr} @@ -15426,9 +15426,8 @@ \effects Equivalent to: \begin{codeblock} -auto nested = [](allocator_arg_t, Alloc, ranges::iterator_t i, - ranges::sentinel_t s) - -> generator, Alloc> { +auto nested = [](allocator_arg_t, Alloc, ranges::iterator_t i, ranges::sentinel_t s) + -> generator, Alloc> { for (; i != s; ++i) { co_yield static_cast(*i); } From 3dee2332565c1eb40ef8835b7f5322cf8a22ac5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Wed, 17 Aug 2022 22:59:50 +0100 Subject: [PATCH 233/430] [coro.generator.promise] Simpler wording for ownership transfer --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index 1ecea21896..260c7cd564 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -15395,7 +15395,7 @@ \pnum \returns An awaitable object of an unspecified type\iref{expr.await} -which takes ownership of the generator \tcode{g.range}, +into which \tcode{g.range} is moved, whose member \tcode{await_ready} returns \tcode{false}, whose member \tcode{await_suspend} pushes \tcode{g.range.\exposid{coroutine_}} From dcef4d07bb93d48d973f26985b4452bb22935f63 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 29 Jul 2022 19:28:12 +0200 Subject: [PATCH 234/430] P2508R1 Expose std::basic-format-string The feature test macros will be revised after all motions have been applied. --- source/utilities.tex | 96 ++++++++++++++++++++++---------------------- 1 file changed, 49 insertions(+), 47 deletions(-) diff --git a/source/utilities.tex b/source/utilities.tex index e78ed9dc4a..d39d832c75 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -13777,26 +13777,24 @@ using format_args = basic_format_args; using wformat_args = basic_format_args; - // \ref{format.fmt.string}, class template \exposid{basic-format-string} + // \ref{format.fmt.string}, class template \tcode{basic_format_string} template - struct @\exposid{basic-format-string}@; // \expos + struct basic_format_string; template - using @\exposid{format-string}@ = // \expos - @\exposid{basic-format-string}@...>; + using @\libglobal{format_string}@ = basic_format_string...>; template - using @\exposid{wformat-string}@ = // \expos - @\exposid{basic-format-string}@...>; + using @\libglobal{wformat_string}@ = basic_format_string...>; // \ref{format.functions}, formatting functions template - string format(@\exposid{format-string}@ fmt, Args&&... args); + string format(format_string fmt, Args&&... args); template - wstring format(@\exposid{wformat-string}@ fmt, Args&&... args); + wstring format(wformat_string fmt, Args&&... args); template - string format(const locale& loc, @\exposid{format-string}@ fmt, Args&&... args); + string format(const locale& loc, format_string fmt, Args&&... args); template - wstring format(const locale& loc, @\exposid{wformat-string}@ fmt, Args&&... args); + wstring format(const locale& loc, wformat_string fmt, Args&&... args); string vformat(string_view fmt, format_args args); wstring vformat(wstring_view fmt, wformat_args args); @@ -13804,13 +13802,13 @@ wstring vformat(const locale& loc, wstring_view fmt, wformat_args args); template - Out format_to(Out out, @\exposid{format-string}@ fmt, Args&&... args); + Out format_to(Out out, format_string fmt, Args&&... args); template - Out format_to(Out out, @\exposid{wformat-string}@ fmt, Args&&... args); + Out format_to(Out out, wformat_string fmt, Args&&... args); template - Out format_to(Out out, const locale& loc, @\exposid{format-string}@ fmt, Args&&... args); + Out format_to(Out out, const locale& loc, format_string fmt, Args&&... args); template - Out format_to(Out out, const locale& loc, @\exposid{wformat-string}@ fmt, Args&&... args); + Out format_to(Out out, const locale& loc, wformat_string fmt, Args&&... args); template Out vformat_to(Out out, string_view fmt, format_args args); @@ -13827,27 +13825,27 @@ }; template format_to_n_result format_to_n(Out out, iter_difference_t n, - @\exposid{format-string}@ fmt, Args&&... args); + format_string fmt, Args&&... args); template format_to_n_result format_to_n(Out out, iter_difference_t n, - @\exposid{wformat-string}@ fmt, Args&&... args); + wformat_string fmt, Args&&... args); template format_to_n_result format_to_n(Out out, iter_difference_t n, - const locale& loc, @\exposid{format-string}@ fmt, + const locale& loc, format_string fmt, Args&&... args); template format_to_n_result format_to_n(Out out, iter_difference_t n, - const locale& loc, @\exposid{wformat-string}@ fmt, + const locale& loc, wformat_string fmt, Args&&... args); template - size_t formatted_size(@\exposid{format-string}@ fmt, Args&&... args); + size_t formatted_size(format_string fmt, Args&&... args); template - size_t formatted_size(@\exposid{wformat-string}@ fmt, Args&&... args); + size_t formatted_size(wformat_string fmt, Args&&... args); template - size_t formatted_size(const locale& loc, @\exposid{format-string}@ fmt, Args&&... args); + size_t formatted_size(const locale& loc, format_string fmt, Args&&... args); template - size_t formatted_size(const locale& loc, @\exposid{wformat-string}@ fmt, Args&&... args); + size_t formatted_size(const locale& loc, wformat_string fmt, Args&&... args); // \ref{format.formatter}, formatter template struct formatter; @@ -14618,21 +14616,25 @@ Failure to allocate storage is reported by throwing an exception as described in~\ref{res.on.exception.handling}. -\rSec2[format.fmt.string]{Class template \exposid{basic-format-string}} +\rSec2[format.fmt.string]{Class template \tcode{basic_format_string}} \begin{codeblock} -template -struct @\exposid{basic-format-string}@ { // \expos -private: - basic_string_view @\exposid{str}@; // \expos +namespace std { + template + struct @\libglobal{basic_format_string}@ { + private: + basic_string_view @\exposidnc{str}@; // \expos -public: - template consteval @\exposid{basic-format-string}@(const T& s); -}; + public: + template consteval basic_format_string(const T& s); + + constexpr basic_string_view get() const noexcept { return @\exposid{str}@; } + }; +} \end{codeblock} \begin{itemdecl} -template consteval @\exposid{basic-format-string}@(const T& s); +template consteval basic_format_string(const T& s); \end{itemdecl} \begin{itemdescr} @@ -14662,7 +14664,7 @@ \indexlibraryglobal{format}% \begin{itemdecl} template - string format(@\exposid{format-string}@ fmt, Args&&... args); + string format(format_string fmt, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -14677,7 +14679,7 @@ \indexlibraryglobal{format}% \begin{itemdecl} template - wstring format(@\exposid{wformat-string}@ fmt, Args&&... args); + wstring format(wformat_string fmt, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -14692,7 +14694,7 @@ \indexlibraryglobal{format}% \begin{itemdecl} template - string format(const locale& loc, @\exposid{format-string}@ fmt, Args&&... args); + string format(const locale& loc, format_string fmt, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -14707,7 +14709,7 @@ \indexlibraryglobal{format}% \begin{itemdecl} template - wstring format(const locale& loc, @\exposid{wformat-string}@ fmt, Args&&... args); + wstring format(const locale& loc, wformat_string fmt, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -14743,7 +14745,7 @@ \indexlibraryglobal{format_to}% \begin{itemdecl} template - Out format_to(Out out, @\exposid{format-string}@ fmt, Args&&... args); + Out format_to(Out out, format_string fmt, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -14758,7 +14760,7 @@ \indexlibraryglobal{format_to}% \begin{itemdecl} template - Out format_to(Out out, @\exposid{wformat-string}@ fmt, Args&&... args); + Out format_to(Out out, wformat_string fmt, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -14773,7 +14775,7 @@ \indexlibraryglobal{format_to}% \begin{itemdecl} template - Out format_to(Out out, const locale& loc, @\exposid{format-string}@ fmt, Args&&... args); + Out format_to(Out out, const locale& loc, format_string fmt, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -14788,7 +14790,7 @@ \indexlibraryglobal{format_to}% \begin{itemdecl} template - Out format_to(Out out, const locale& loc, @\exposid{wformat-string}@ fmt, Args&&... args); + Out format_to(Out out, const locale& loc, wformat_string fmt, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -14846,17 +14848,17 @@ \begin{itemdecl} template format_to_n_result format_to_n(Out out, iter_difference_t n, - @\exposid{format-string}@ fmt, Args&&... args); + format_string fmt, Args&&... args); template format_to_n_result format_to_n(Out out, iter_difference_t n, - @\exposid{wformat-string}@ fmt, Args&&... args); + wformat_string fmt, Args&&... args); template format_to_n_result format_to_n(Out out, iter_difference_t n, - const locale& loc, @\exposid{format-string}@ fmt, + const locale& loc, format_string fmt, Args&&... args); template format_to_n_result format_to_n(Out out, iter_difference_t n, - const locale& loc, @\exposid{wformat-string}@ fmt, + const locale& loc, wformat_string fmt, Args&&... args); \end{itemdecl} @@ -14902,13 +14904,13 @@ \indexlibraryglobal{formatted_size}% \begin{itemdecl} template - size_t formatted_size(@\exposid{format-string}@ fmt, Args&&... args); + size_t formatted_size(format_string fmt, Args&&... args); template - size_t formatted_size(@\exposid{wformat-string}@ fmt, Args&&... args); + size_t formatted_size(wformat_string fmt, Args&&... args); template - size_t formatted_size(const locale& loc, @\exposid{format-string}@ fmt, Args&&... args); + size_t formatted_size(const locale& loc, format_string fmt, Args&&... args); template - size_t formatted_size(const locale& loc, @\exposid{wformat-string}@ fmt, Args&&... args); + size_t formatted_size(const locale& loc, wformat_string fmt, Args&&... args); \end{itemdecl} \begin{itemdescr} From 3c8ba258c3a26fd880ffb87064bfdf4120d92c0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Thu, 18 Aug 2022 00:04:55 +0100 Subject: [PATCH 235/430] [input.output] Change exposition-only format-string to format_string These exposition-only names were added by LWG Motion-11 P2093R14 ("Formatted output") and need to be updated. --- source/iostreams.tex | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/source/iostreams.tex b/source/iostreams.tex index ee3afe522c..c0bb5aee0b 100644 --- a/source/iostreams.tex +++ b/source/iostreams.tex @@ -4168,9 +4168,9 @@ // \ref{ostream.formatted.print}, print functions template - void print(ostream& os, @\exposid{format-string}@ fmt, Args&&... args); + void print(ostream& os, format_string fmt, Args&&... args); template - void println(ostream& os, @\exposid{format-string}@ fmt, Args&&... args); + void println(ostream& os, format_string fmt, Args&&... args); void vprint_unicode(ostream& os, string_view fmt, format_args args); void vprint_nonunicode(ostream& os, string_view fmt, format_args args); @@ -4222,14 +4222,14 @@ namespace std { // \ref{print.fun}, print functions template - void print(@\exposid{format-string}@ fmt, Args&&... args); + void print(format_string fmt, Args&&... args); template - void print(FILE* stream, @\exposid{format-string}@ fmt, Args&&... args); + void print(FILE* stream, format_string fmt, Args&&... args); template - void println(@\exposid{format-string}@ fmt, Args&&... args); + void println(format_string fmt, Args&&... args); template - void println(FILE* stream, @\exposid{format-string}@ fmt, Args&&... args); + void println(FILE* stream, format_string fmt, Args&&... args); void vprint_unicode(string_view fmt, format_args args); void vprint_unicode(FILE* stream, string_view fmt, format_args args); @@ -6808,7 +6808,7 @@ \indexlibraryglobal{print}% \begin{itemdecl} template - void print(ostream& os, @\exposid{format-string}@ fmt, Args&&... args); + void print(ostream& os, format_string fmt, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -6827,7 +6827,7 @@ \indexlibraryglobal{println}% \begin{itemdecl} template - void println(ostream& os, @\exposid{format-string}@ fmt, Args&&... args); + void println(ostream& os, format_string fmt, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -7700,7 +7700,7 @@ \indexlibraryglobal{print}% \begin{itemdecl} template - void print(@\exposid{format-string}@ fmt, Args&&... args); + void print(format_string fmt, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -7715,7 +7715,7 @@ \indexlibraryglobal{print}% \begin{itemdecl} template - void print(FILE* stream, @\exposid{format-string}@ fmt, Args&&... args); + void print(FILE* stream, format_string fmt, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -7734,7 +7734,7 @@ \indexlibraryglobal{println}% \begin{itemdecl} template - void println(@\exposid{format-string}@ fmt, Args&&... args); + void println(format_string fmt, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -7749,7 +7749,7 @@ \indexlibraryglobal{println}% \begin{itemdecl} template - void println(FILE* stream, @\exposid{format-string}@ fmt, Args&&... args); + void println(FILE* stream, format_string fmt, Args&&... args); \end{itemdecl} \begin{itemdescr} From 7870c6c585469bef144d29016b7ceada29538d03 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 29 Jul 2022 14:41:33 +0200 Subject: [PATCH 236/430] P2517R1 Add a conditional noexcept specification to std::apply --- source/utilities.tex | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/source/utilities.tex b/source/utilities.tex index d39d832c75..5b785a39da 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -1514,7 +1514,7 @@ // \ref{tuple.apply}, calling a function with a tuple of arguments template - constexpr decltype(auto) apply(F&& f, Tuple&& t); + constexpr decltype(auto) apply(F&& f, Tuple&& t) noexcept(@\seebelow@); template constexpr T make_from_tuple(Tuple&& t); @@ -2622,7 +2622,7 @@ \indexlibraryglobal{apply}% \begin{itemdecl} template - constexpr decltype(auto) apply(F&& f, Tuple&& t); + constexpr decltype(auto) apply(F&& f, Tuple&& t) noexcept(@\seebelow@); \end{itemdecl} \begin{itemdescr} @@ -2643,6 +2643,15 @@ return @\placeholdernc{apply-impl}@(std::forward(f), std::forward(t), make_index_sequence>>{}); \end{codeblock} + +\pnum +\remarks +Let \tcode{I} be the pack +\tcode{0, 1, ..., (tuple_size_v> - 1)}. +The exception specification is equivalent to: +\begin{codeblock} +noexcept(invoke(std::forward(f), get(std::forward(t))...)) +\end{codeblock} \end{itemdescr} \indexlibraryglobal{make_from_tuple}% From 1f909a633c0ecda18ba1629ee46280fade3754b5 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 29 Jul 2022 21:35:12 +0200 Subject: [PATCH 237/430] P2520R0 move_iterator should be a random access iterator Editorial changes: A misspelling of the header name in the feature test macro entry has been fixed. --- source/iterators.tex | 19 ++++++++++++++++++- source/support.tex | 1 + 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/source/iterators.tex b/source/iterators.tex index 1d26bbe0b0..a3a59b6010 100644 --- a/source/iterators.tex +++ b/source/iterators.tex @@ -4729,7 +4729,7 @@ class move_iterator { public: using iterator_type = Iterator; - using iterator_concept = input_iterator_tag; + using iterator_concept = @\seebelow@; using iterator_category = @\seebelow@; // not always present using value_type = iter_value_t; using difference_type = iter_difference_t; @@ -4779,6 +4779,23 @@ } \end{codeblock} +\pnum +The member \grammarterm{typedef-name} \tcode{iterator_concept} is defined +as follows: +\begin{itemize} +\item +If \tcode{Iterator} models \libconcept{random_access_iterator}, +then \tcode{iterator_concept} denotes \tcode{random_access_iterator_tag}. +\item +Otherwise, if \tcode{Iterator} models \libconcept{bidirectional_iterator}, +then \tcode{iterator_concept} denotes \tcode{bidirec\-tional_iterator_tag}. +\item +Otherwise, if \tcode{Iterator} models \libconcept{forward_iterator}, +then \tcode{iterator_concept} denotes \tcode{forward_itera\-tor_tag}. +\item +Otherwise, \tcode{iterator_concept} denotes \tcode{input_iterator_tag}. +\end{itemize} + \pnum The member \grammarterm{typedef-name} \tcode{iterator_category} is defined if and only if the \grammarterm{qualified-id} diff --git a/source/support.tex b/source/support.tex index cca93aaecb..152dc001c4 100644 --- a/source/support.tex +++ b/source/support.tex @@ -668,6 +668,7 @@ #define @\defnlibxname{cpp_lib_mdspan}@ 202207L // also in \libheader{mdspan} #define @\defnlibxname{cpp_lib_memory_resource}@ 201603L // also in \libheader{memory_resource} #define @\defnlibxname{cpp_lib_modules}@ 202207L +#define @\defnlibxname{cpp_lib_move_iterator_concept}@ 202207L // also in \libheader{iterator} #define @\defnlibxname{cpp_lib_move_only_function}@ 202110L // also in \libheader{functional} #define @\defnlibxname{cpp_lib_node_extract}@ 201606L // also in \libheader{map}, \libheader{set}, \libheader{unordered_map}, \libheader{unordered_set} From a3c3c01263fbfd7403afb20ea184539147246c26 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 29 Jul 2022 22:04:20 +0200 Subject: [PATCH 238/430] P2549R1 std::unexpected should have error() as member accessor --- source/utilities.tex | 72 ++++++++++++++++++++++---------------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/source/utilities.tex b/source/utilities.tex index 5b785a39da..4c5f857525 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -6929,10 +6929,10 @@ constexpr unexpected& operator=(const unexpected&) = default; constexpr unexpected& operator=(unexpected&&) = default; - constexpr const E& value() const & noexcept; - constexpr E& value() & noexcept; - constexpr const E&& value() const && noexcept; - constexpr E&& value() && noexcept; + constexpr const E& error() const & noexcept; + constexpr E& error() & noexcept; + constexpr const E&& error() const && noexcept; + constexpr E&& error() && noexcept; constexpr void swap(unexpected& other) noexcept(@\seebelow@); @@ -6942,7 +6942,7 @@ friend constexpr void swap(unexpected& x, unexpected& y) noexcept(noexcept(x.swap(y))); private: - E @\exposid{val}@; // \expos + E @\exposidnc{unex}@; // \expos }; template unexpected(E) -> unexpected; @@ -6979,11 +6979,11 @@ \pnum \effects -Direct-non-list-initializes \exposid{val} with \tcode{std::forward(e)}. +Direct-non-list-initializes \exposid{unex} with \tcode{std::forward(e)}. \pnum \throws -Any exception thrown by the initialization of \exposid{val}. +Any exception thrown by the initialization of \exposid{unex}. \end{itemdescr} \indexlibraryctor{unexpected}% @@ -7000,11 +7000,11 @@ \pnum \effects Direct-non-list-initializes -\exposid{val} with \tcode{std::forward(args)...}. +\exposid{unex} with \tcode{std::forward(args)...}. \pnum \throws -Any exception thrown by the initialization of \exposid{val}. +Any exception thrown by the initialization of \exposid{unex}. \end{itemdescr} \indexlibraryctor{unexpected}% @@ -7021,37 +7021,37 @@ \pnum \effects Direct-non-list-initializes -\exposid{val} with \tcode{il, std::forward(args)...}. +\exposid{unex} with \tcode{il, std::forward(args)...}. \pnum \throws -Any exception thrown by the initialization of \exposid{val}. +Any exception thrown by the initialization of \exposid{unex}. \end{itemdescr} \rSec3[expected.un.obs]{Observers} -\indexlibrarymember{value}{unexpected}% +\indexlibrarymember{error}{unexpected}% \begin{itemdecl} -constexpr const E& value() const & noexcept; -constexpr E& value() & noexcept; +constexpr const E& error() const & noexcept; +constexpr E& error() & noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns -\exposid{val}. +\exposid{unex}. \end{itemdescr} -\indexlibrarymember{value}{unexpected}% +\indexlibrarymember{error}{unexpected}% \begin{itemdecl} -constexpr E&& value() && noexcept; -constexpr const E&& value() const && noexcept; +constexpr E&& error() && noexcept; +constexpr const E&& error() const && noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns -\tcode{std::move(\exposid{val})}. +\tcode{std::move(\exposid{unex})}. \end{itemdescr} \rSec3[expected.un.swap]{Swap} @@ -7069,7 +7069,7 @@ \pnum \effects Equivalent to: -\tcode{using std::swap; swap(\exposid{val}, other.\exposid{val});} +\tcode{using std::swap; swap(\exposid{unex}, other.\exposid{unex});} \end{itemdescr} \begin{itemdecl} @@ -7097,12 +7097,12 @@ \begin{itemdescr} \pnum \mandates -The expression \tcode{x.value() == y.value()} is well-formed and +The expression \tcode{x.error() == y.error()} is well-formed and its result is convertible to \tcode{bool}. \pnum \returns -\tcode{x.value() == y.value()}. +\tcode{x.error() == y.error()}. \end{itemdescr} \rSec2[expected.bad]{Class template \tcode{bad_expected_access}} @@ -7120,7 +7120,7 @@ E&& error() && noexcept; const E&& error() const && noexcept; private: - E @\exposid{val}@; // \expos + E @\exposidnc{unex}@; // \expos }; } \end{codeblock} @@ -7139,7 +7139,7 @@ \begin{itemdescr} \pnum \effects -Initializes \exposid{val} with \tcode{std::move(e)}. +Initializes \exposid{unex} with \tcode{std::move(e)}. \end{itemdescr} \indexlibrarymember{error}{bad_expected_access}% @@ -7151,7 +7151,7 @@ \begin{itemdescr} \pnum \returns -\exposid{val}. +\exposid{unex}. \end{itemdescr} \indexlibrarymember{error}{bad_expected_access}% @@ -7163,7 +7163,7 @@ \begin{itemdescr} \pnum \returns -\tcode{std::move(\exposid{val})}. +\tcode{std::move(\exposid{unex})}. \end{itemdescr} \indexlibrarymember{what}{bad_expected_access}% @@ -7575,7 +7575,7 @@ \pnum \effects -Direct-non-list-initializes \exposid{unex} with \tcode{std::forward(e.value())}. +Direct-non-list-initializes \exposid{unex} with \tcode{std::forward(e.error())}. \pnum \ensures @@ -7905,12 +7905,12 @@ \item If \tcode{has_value()} is \tcode{true}, equivalent to: \begin{codeblock} -@\exposid{reinit-expected}@(@\exposid{unex}@, @\exposid{val}@, std::forward(e.value())); +@\exposid{reinit-expected}@(@\exposid{unex}@, @\exposid{val}@, std::forward(e.error())); @\exposid{has_val}@ = false; \end{codeblock} \item Otherwise, equivalent to: -\tcode{\exposid{unex} = std::forward(e.value());} +\tcode{\exposid{unex} = std::forward(e.error());} \end{itemize} \pnum @@ -8270,12 +8270,12 @@ \begin{itemdescr} \pnum \mandates -The expression \tcode{x.error() == e.value()} is well-formed and +The expression \tcode{x.error() == e.error()} is well-formed and its result is convertible to \tcode{bool}. \pnum \returns -\tcode{!x.has_value() \&\& static_cast(x.error() == e.value())}. +\tcode{!x.has_value() \&\& static_cast(x.error() == e.error())}. \end{itemdescr} \rSec2[expected.void]{Partial specialization of \tcode{expected} for \tcode{void} types} @@ -8516,7 +8516,7 @@ \pnum \effects Direct-non-list-initializes \exposid{unex} -with \tcode{std::forward(e.value())}. +with \tcode{std::forward(e.error())}. \pnum \ensures @@ -8703,12 +8703,12 @@ \item If \tcode{has_value()} is \tcode{true}, equivalent to: \begin{codeblock} -construct_at(addressof(@\exposid{unex}@), std::forward(e.value())); +construct_at(addressof(@\exposid{unex}@), std::forward(e.error())); @\exposid{has_val}@ = false; \end{codeblock} \item Otherwise, equivalent to: -\tcode{\exposid{unex} = std::forward(e.value());} +\tcode{\exposid{unex} = std::forward(e.error());} \end{itemize} \pnum @@ -8897,12 +8897,12 @@ \begin{itemdescr} \pnum \mandates -The expression \tcode{x.error() == e.value()} is well-formed and +The expression \tcode{x.error() == e.error()} is well-formed and its result is convertible to \tcode{bool}. \pnum \returns -\tcode{!x.has_value() \&\& static_cast(x.error() == e.value())}. +\tcode{!x.has_value() \&\& static_cast(x.error() == e.error())}. \end{itemdescr} \rSec1[bitset]{Bitsets} From c6436e1886f8d2c644a89875d1baa6be9b6765fe Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 3 Aug 2022 22:44:26 -0700 Subject: [PATCH 239/430] P2585R1 Improving default container formatting Editorial changes: * Constructors have been renamed from "formatter" to "range-default-formatter" to match the renaming of the class. --- source/containers.tex | 153 -------------------- source/utilities.tex | 317 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 294 insertions(+), 176 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index dae29df486..e54959650a 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -13035,159 +13035,6 @@ \end{codeblock} \end{itemdescr} -\rSec1[assoc.format]{Associative formatting} - -\pnum -For each of -\tcode{map}, -\tcode{multimap}, -\tcode{unordered_map}, -\tcode{unordered_multimap}, -\tcode{flat_map}, and -\tcode{flat_multimap}, -the library provides the following formatter specialization -where \tcode{\placeholder{map-type}} is the name of the template: - -\indexlibraryglobal{formatter}% -\begin{codeblock} -namespace std { - template T, class... U> - requires @\libconcept{formattable}@ - struct formatter<@\placeholder{map-type}@, charT> { - private: - using @\exposid{maybe-const-map}@ = // \expos - @\exposid{fmt-maybe-const}@<@\placeholder{map-type}@, charT>; - range_formatter>, - charT> @\exposid{underlying_}@; // \expos - public: - constexpr formatter(); - - template - constexpr typename ParseContext::iterator - parse(ParseContext& ctx); - - template - typename FormatContext::iterator - format(@\exposid{maybe-const-map}@& r, FormatContext& ctx) const; - }; -} -\end{codeblock} - -\indexlibraryctor{formatter}% -\begin{itemdecl} -constexpr formatter(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: -\begin{codeblock} -@\exposid{underlying_}@.set_brackets(@\exposid{STATICALLY-WIDEN}@("{"), @\exposid{STATICALLY-WIDEN}@("}")); -@\exposid{underlying_}@.underlying().set_brackets({}, {}); -@\exposid{underlying_}@.underlying().set_separator(@\exposid{STATICALLY-WIDEN}@(": ")); -\end{codeblock} -\end{itemdescr} - -\indexlibrarymember{parse}{formatter}% -\begin{itemdecl} -template - constexpr typename ParseContext::iterator - parse(ParseContext& ctx); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: \tcode{return \exposid{underlying_}.parse(ctx);} -\end{itemdescr} - -\indexlibrarymember{format}{formatter}% -\begin{itemdecl} -template - typename FormatContext::iterator - format(@\exposid{maybe-const-map}@& r, FormatContext& ctx) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: \tcode{return \exposid{underlying_}.format(r, ctx);} -\end{itemdescr} - -\pnum -For each of -\tcode{set}, -\tcode{multiset}, -\tcode{unordered_set}, -\tcode{unordered_multiset}, -\tcode{flat_set}, and -\tcode{flat_multiset}, -the library provides the following formatter specialization -where \tcode{\placeholder{set-type}} is the name of the template: - -\indexlibraryglobal{formatter}% -\begin{codeblock} -namespace std { -template - requires @\libconcept{formattable}@ - struct formatter<@\placeholder{set-type}@, charT> { - private: - range_formatter @\exposid{underlying_}@; // \expos - public: - constexpr formatter(); - - template - constexpr typename ParseContext::iterator - parse(ParseContext& ctx); - - template - typename FormatContext::iterator - format(const @\placeholder{set-type}@& r, FormatContext& ctx) const; - }; -} -\end{codeblock} - -\indexlibraryctor{formatter}% -\begin{itemdecl} -constexpr formatter(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: -\begin{codeblock} -@\exposid{underlying_}@.set_brackets(@\exposid{STATICALLY-WIDEN}@("{"), @\exposid{STATICALLY-WIDEN}@("}")); -\end{codeblock} -\end{itemdescr} - -\indexlibrarymember{parse}{formatter}% -\begin{itemdecl} -template - constexpr typename ParseContext::iterator - parse(ParseContext& ctx); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: \tcode{return \exposid{underlying_}.parse(ctx);} -\end{itemdescr} - -\indexlibrarymember{format}{formatter}% -\begin{itemdecl} -template - typename FormatContext::iterator - format(const @\placeholder{set-type}@& r, FormatContext& ctx) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: \tcode{return \exposid{underlying_}.format(r, ctx);} -\end{itemdescr} - \rSec1[container.adaptors]{Container adaptors} \rSec2[container.adaptors.general]{In general} diff --git a/source/utilities.tex b/source/utilities.tex index 4c5f857525..8ca8da324c 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -13859,17 +13859,36 @@ // \ref{format.formatter}, formatter template struct formatter; - // \ref{format.formatter.spec}, formatter specializations - template - requires (!@\libconcept{same_as}@>, R>) && - @\libconcept{formattable}@, charT> - struct formatter; - // \ref{format.range.formatter}, class template \tcode{range_formatter} + enum class range_format { + disabled, + map, + set, + sequence, + string, + debug_string + }; + + template + constexpr @\unspec@ format_kind = @\unspec@; + + template + requires @\libconcept{same_as}@> + constexpr range_format format_kind = @\seebelow@; + template requires @\libconcept{same_as}@, T> && @\libconcept{formattable}@ class range_formatter; + template + struct @\exposid{range-default-formatter}@; // \expos + + // \ref{format.formatter.spec}, formatter specializations + template + requires (format_kind != range_format::disabled) && + @\libconcept{formattable}@, charT> + struct formatter : @\exposid{range-default-formatter}@, R, charT> { }; + // \ref{format.parse.ctx}, class template \tcode{basic_format_parse_context} template class basic_format_parse_context; using format_parse_context = basic_format_parse_context; @@ -15749,6 +15768,61 @@ then there shall be no \tcode{n} option and no \fmtgrammarterm{range-underlying-spec}. +\indexlibraryglobal{format_kind} +\begin{itemdecl} +template + requires @\libconcept{same_as}@> + constexpr range_format format_kind = @\seebelow@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +A program that instantiates the primary template of \tcode{format_kind} +is ill-formed. + +\pnum +For a type \tcode{R}, \tcode{format_kind} is defined as follows: +\begin{itemize} +\item +If \tcode{\libconcept{same_as}>, R>} +is \tcode{true}, +\tcode{format_kind} is \tcode{range_format::disabled}. +\begin{note} +This prevents constraint recursion for ranges whose +reference type is the same range type. +For example, +\tcode{std::filesystem::path} is a range of \tcode{std::filesystem::path}. +\end{note} + +\item +Otherwise, if the \grammarterm{qualified-id} \tcode{R::key_type} +is valid and denotes a type: +\begin{itemize} +\item +If the \grammarterm{qualified-id} \tcode{R::mapped_type} +is valid and denotes a type, +let \tcode{U} be \tcode{remove_cvref_t>}. +If either \tcode{U} is a specialization of \tcode{pair} or +\tcode{U} is a specialization of \tcode{tuple} and +\tcode{tuple_size_v == 2}, +\tcode{format_kind} is \tcode{range_format::map}. +\item +Otherwise, \tcode{format_kind} is \tcode{range_format::set}. +\end{itemize} + +\item +Otherwise, \tcode{format_kind} is \tcode{range_format::sequence}. +\end{itemize} + +\pnum +\remarks +Pursuant to \ref{namespace.std}, users may specialize \tcode{format_kind} +for cv-unqualified program-defined types +that model \tcode{ranges::\libconcept{input_range}}. +Such specializations shall be usable in constant expressions\iref{expr.const} +and have type \tcode{const range_format}. +\end{itemdescr} + \indexlibraryglobal{range_formatter}% \begin{codeblock} namespace std { @@ -15884,13 +15958,11 @@ An iterator past the end of the output range. \end{itemdescr} -\indexlibraryglobal{formatter}% +\indexlibraryglobal{\exposid{range-default-formatter}}% \begin{codeblock} namespace std { template - requires (!@\libconcept{same_as}@>, R>) && - @\libconcept{formattable}@, charT> - struct formatter { + struct @\exposid{range-default-formatter}@ { private: using @\exposid{maybe-const-r}@ = @\exposid{fmt-maybe-const}@; range_formatter>, @@ -15912,16 +15984,7 @@ } \end{codeblock} -\pnum -\begin{note} -The \tcode{(!\libconcept{same_as}>, R>)} -constraint prevents constraint recursion -for ranges whose reference type is the same range type. -For example, \tcode{std::filesystem::path} -is a range of \tcode{std::filesystem::path}. -\end{note} - -\indexlibrarymember{set_separator}{formatter}% +\indexlibrarymember{set_separator}{\exposid{range-default-formatter}}% \begin{itemdecl} constexpr void set_separator(basic_string_view sep); \end{itemdecl} @@ -15932,7 +15995,7 @@ Equivalent to: \tcode{\exposid{underlying_}.set_separator(sep);} \end{itemdescr} -\indexlibrarymember{set_brackets}{formatter}% +\indexlibrarymember{set_brackets}{\exposid{range-default-formatter}}% \begin{itemdecl} constexpr void set_brackets(basic_string_view opening, basic_string_view closing); \end{itemdecl} @@ -15943,7 +16006,7 @@ Equivalent to: \tcode{\exposid{underlying_}.set_brackets(opening, closing);} \end{itemdescr} -\indexlibrarymember{parse}{formatter}% +\indexlibrarymember{parse}{\exposid{range-default-formatter}}% \begin{itemdecl} template constexpr typename ParseContext::iterator @@ -15956,7 +16019,7 @@ Equivalent to: \tcode{return \exposid{underlying_}.parse(ctx);} \end{itemdescr} -\indexlibrarymember{format}{formatter}% +\indexlibrarymember{format}{\exposid{range-default-formatter}}% \begin{itemdecl} template typename FormatContext::iterator @@ -15969,6 +16032,214 @@ Equivalent to: \tcode{return \exposid{underlying_}.format(elems, ctx);} \end{itemdescr} +\indexlibraryglobal{\exposid{range-default-formatter}}% +\begin{codeblock} +namespace std { + template + struct @\exposid{range-default-formatter}@ { + private: + using @\exposid{maybe-const-map}@ = @\exposid{fmt-maybe-const}@; // \expos + using @\exposid{element-type}@ = // \expos + remove_cvref_t>; + range_formatter<@\exposid{element-type}@, charT> @\exposid{underlying_}@; // \expos + public: + constexpr @\exposid{range-default-formatter}@(); + + template + constexpr typename ParseContext::iterator + parse(ParseContext& ctx); + + template + typename FormatContext::iterator + format(@\exposid{maybe-const-map}@& r, FormatContext& ctx) const; + }; +} +\end{codeblock} + +\indexlibraryctor{\exposid{range-default-formatter}}% +\begin{itemdecl} +constexpr @\exposid{range-default-formatter}@(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +Either: +\begin{itemize} +\item +\exposid{element-type} is a specialization of \tcode{pair}, or +\item +\exposid{element-type} is a specialization of \tcode{tuple} and +\tcode{tuple_size_v == 2}. +\end{itemize} + +\pnum +\effects +Equivalent to: +\begin{codeblock} +@\exposid{underlying_}@.set_brackets(@\exposid{STATICALLY-WIDEN}@("{"), @\exposid{STATICALLY-WIDEN}@("}")); +@\exposid{underlying_}@.underlying().set_brackets({}, {}); +@\exposid{underlying_}@.underlying().set_separator(@\exposid{STATICALLY-WIDEN}@(": ")); +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{parse}{\exposid{range-default-formatter}}% +\begin{itemdecl} +template + constexpr typename ParseContext::iterator + parse(ParseContext& ctx); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return \exposid{underlying_}.parse(ctx);} +\end{itemdescr} + +\indexlibrarymember{format}{\exposid{range-default-formatter}}% +\begin{itemdecl} +template + typename FormatContext::iterator + format(@\exposid{maybe-const-map}@& r, FormatContext& ctx) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return \exposid{underlying_}.format(r, ctx);} +\end{itemdescr} + +\indexlibraryglobal{\exposid{range-default-formatter}}% +\begin{codeblock} +namespace std { + template + struct @\exposid{range-default-formatter}@ { + private: + using @\exposid{maybe-const-set}@ = @\exposid{fmt-maybe-const}@; // \expos + range_formatter>, + charT> @\exposid{underlying_}@; // \expos + + public: + constexpr @\exposid{range-default-formatter}@(); + + template + constexpr typename ParseContext::iterator + parse(ParseContext& ctx); + + template + typename FormatContext::iterator + format(@\exposid{maybe-const-set}@& r, FormatContext& ctx) const; + }; +} +\end{codeblock} + +\indexlibraryctor{\exposid{range-default-formatter}}% +\begin{itemdecl} +constexpr @\exposid{range-default-formatter}@(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +@\exposid{underlying_}@.set_brackets(@\exposid{STATICALLY-WIDEN}@("{"), @\exposid{STATICALLY-WIDEN}@("}")); +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{parse}{\exposid{range-default-formatter}}% +\begin{itemdecl} +template + constexpr typename ParseContext::iterator + parse(ParseContext& ctx); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return \exposid{underlying_}.parse(ctx);} +\end{itemdescr} + +\indexlibrarymember{format}{\exposid{range-default-formatter}}% +\begin{itemdecl} +template + typename FormatContext::iterator + format(@\exposid{maybe-const-set}@& r, FormatContext& ctx) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return \exposid{underlying_}.format(r, ctx);} +\end{itemdescr} + +\indexlibraryglobal{\exposid{range-default-formatter}}% +\begin{codeblock} +namespace std { + template + requires (K == range_format::string || + K == range_format::debug_string) + struct @\exposid{range-default-formatter}@ { + private: + formatter, charT> @\exposid{underlying_}@; // \expos + + public: + template + constexpr typename ParseContext::iterator + parse(ParseContext& ctx); + + template + typename FormatContext::iterator + format(@\seebelow@& str, FormatContext& ctx) const; + }; +} +\end{codeblock} + +\pnum +\mandates +\tcode{\libconcept{same_as}>, charT>} +is \tcode{true}. + +\indexlibrarymember{parse}{\exposid{range-default-formatter}}% +\begin{itemdecl} +template + constexpr typename ParseContext::iterator + parse(ParseContext& ctx); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto i = @\exposid{underlying_}@.parse(ctx); +if constexpr (K == range_format::debug_string) { + @\exposid{underlying_}@.set_debug_format(); +} +return i; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{format}{\exposid{range-default-formatter}}% +\begin{itemdecl} +template + typename FormatContext::iterator + format(@\seebelow@& r, FormatContext& ctx) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +The type of \tcode{r} is \tcode{const R\&} +if \tcode{\libconcept{input_range}} is \tcode{true} and +\tcode{R\&} otherwise. + +\pnum +\effects +Let \tcode{\placeholder{s}} be a \tcode{basic_string} such that +\tcode{ranges::equal(\placeholder{s}, r)} is \tcode{true}. +Equivalent to: \tcode{return \exposid{underlying_}.format(\placeholder{s}, ctx);} +\end{itemdescr} + \rSec2[format.arguments]{Arguments} \rSec3[format.arg]{Class template \tcode{basic_format_arg}} From a83592088f87ec3998110c3ae4fd238f90d96dca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Thu, 18 Aug 2022 13:55:49 +0100 Subject: [PATCH 240/430] [format.range] Add subclause structure. The original, large subclause contained several class template synopses without any intervening separation. The header synopsis is rearranged to follow the document order. --- source/utilities.tex | 232 +++++++++++++++++++++++-------------------- 1 file changed, 123 insertions(+), 109 deletions(-) diff --git a/source/utilities.tex b/source/utilities.tex index 8ca8da324c..240255ab61 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -13859,7 +13859,26 @@ // \ref{format.formatter}, formatter template struct formatter; - // \ref{format.range.formatter}, class template \tcode{range_formatter} + // \ref{format.formattable}, concept \libconcept{formattable} + template + concept formattable = @\seebelow@; + + template + concept @\defexposconcept{const-formattable-range}@ = // \expos + ranges::@\libconcept{input_range}@ && + @\libconcept{formattable}@, charT>; + + template + using @\exposid{fmt-maybe-const}@ = // \expos + conditional_t<@\exposconcept{const-formattable-range}@, const R, R>; + + // \ref{format.parse.ctx}, class template \tcode{basic_format_parse_context} + template class basic_format_parse_context; + using format_parse_context = basic_format_parse_context; + using wformat_parse_context = basic_format_parse_context; + + // \ref{format.range}, formatting of ranges + // \ref{format.range.fmtkind}, variable template \tcode{format_kind} enum class range_format { disabled, map, @@ -13876,37 +13895,21 @@ requires @\libconcept{same_as}@> constexpr range_format format_kind = @\seebelow@; + // \ref{format.range.formatter}, class template \tcode{range_formatter} template requires @\libconcept{same_as}@, T> && @\libconcept{formattable}@ class range_formatter; + // \ref{format.range.fmtdef}, class template \tcode{\exposid{range-default-formatter}} template struct @\exposid{range-default-formatter}@; // \expos - // \ref{format.formatter.spec}, formatter specializations + // \ref{format.range.fmtmap}, \ref{format.range.fmtset}, \ref{format.range.fmtstr}, specializations for maps, sets, and strings template requires (format_kind != range_format::disabled) && @\libconcept{formattable}@, charT> struct formatter : @\exposid{range-default-formatter}@, R, charT> { }; - // \ref{format.parse.ctx}, class template \tcode{basic_format_parse_context} - template class basic_format_parse_context; - using format_parse_context = basic_format_parse_context; - using wformat_parse_context = basic_format_parse_context; - - // \ref{format.formattable}, concept \libconcept{formattable} - template - concept formattable = @\seebelow@; - - template - concept @\defexposconcept{const-formattable-range}@ = // \expos - ranges::@\libconcept{input_range}@ && - @\libconcept{formattable}@, charT>; - - template - using @\exposid{fmt-maybe-const}@ = // \expos - conditional_t<@\exposconcept{const-formattable-range}@, const R, R>; - // \ref{format.arguments}, arguments // \ref{format.arg}, class template \tcode{basic_format_arg} template class basic_format_arg; @@ -15668,7 +15671,97 @@ \end{codeblock} \end{example} -\rSec2[format.range.formatter]{Class template \tcode{range_formatter}} +\rSec2[format.range]{Formatting of ranges} + +\rSec3[format.range.fmtkind]{Variable template \tcode{format_kind}} + +\indexlibraryglobal{format_kind} +\begin{itemdecl} +template + requires @\libconcept{same_as}@> + constexpr range_format format_kind = @\seebelow@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +A program that instantiates the primary template of \tcode{format_kind} +is ill-formed. + +\pnum +For a type \tcode{R}, \tcode{format_kind} is defined as follows: +\begin{itemize} +\item +If \tcode{\libconcept{same_as}>, R>} +is \tcode{true}, +\tcode{format_kind} is \tcode{range_format::disabled}. +\begin{note} +This prevents constraint recursion for ranges whose +reference type is the same range type. +For example, +\tcode{std::filesystem::path} is a range of \tcode{std::filesystem::path}. +\end{note} + +\item +Otherwise, if the \grammarterm{qualified-id} \tcode{R::key_type} +is valid and denotes a type: +\begin{itemize} +\item +If the \grammarterm{qualified-id} \tcode{R::mapped_type} +is valid and denotes a type, +let \tcode{U} be \tcode{remove_cvref_t>}. +If either \tcode{U} is a specialization of \tcode{pair} or +\tcode{U} is a specialization of \tcode{tuple} and +\tcode{tuple_size_v == 2}, +\tcode{format_kind} is \tcode{range_format::map}. +\item +Otherwise, \tcode{format_kind} is \tcode{range_format::set}. +\end{itemize} + +\item +Otherwise, \tcode{format_kind} is \tcode{range_format::sequence}. +\end{itemize} + +\pnum +\remarks +Pursuant to \ref{namespace.std}, users may specialize \tcode{format_kind} +for cv-unqualified program-defined types +that model \tcode{ranges::\libconcept{input_range}}. +Such specializations shall be usable in constant expressions\iref{expr.const} +and have type \tcode{const range_format}. +\end{itemdescr} + +\rSec3[format.range.formatter]{Class template \tcode{range_formatter}} + +\indexlibraryglobal{range_formatter}% +\begin{codeblock} +namespace std { + template + requires @\libconcept{same_as}@, T> && @\libconcept{formattable}@ + class range_formatter { + formatter @\exposid{underlying_}@; // \expos + basic_string_view @\exposid{separator_}@ = @\exposid{STATICALLY-WIDEN}@(", "); // \expos + basic_string_view @\exposid{opening-bracket_}@ = @\exposid{STATICALLY-WIDEN}@("["); // \expos + basic_string_view @\exposid{closing-bracket_}@ = @\exposid{STATICALLY-WIDEN}@("]"); // \expos + + public: + constexpr void set_separator(basic_string_view sep); + constexpr void set_brackets(basic_string_view opening, + basic_string_view closing); + constexpr formatter& underlying() { return @\exposid{underlying_}@; } + constexpr const formatter& underlying() const { return @\exposid{underlying_}@; } + + template + constexpr typename ParseContext::iterator + parse(ParseContext& ctx); + + template + requires @\libconcept{formattable}@, charT> && + @\libconcept{same_as}@>, T> + typename FormatContext::iterator + format(R&& r, FormatContext& ctx) const; + }; +} +\end{codeblock} \pnum The class template \tcode{range_formatter} is a utility @@ -15768,92 +15861,6 @@ then there shall be no \tcode{n} option and no \fmtgrammarterm{range-underlying-spec}. -\indexlibraryglobal{format_kind} -\begin{itemdecl} -template - requires @\libconcept{same_as}@> - constexpr range_format format_kind = @\seebelow@; -\end{itemdecl} - -\begin{itemdescr} -\pnum -A program that instantiates the primary template of \tcode{format_kind} -is ill-formed. - -\pnum -For a type \tcode{R}, \tcode{format_kind} is defined as follows: -\begin{itemize} -\item -If \tcode{\libconcept{same_as}>, R>} -is \tcode{true}, -\tcode{format_kind} is \tcode{range_format::disabled}. -\begin{note} -This prevents constraint recursion for ranges whose -reference type is the same range type. -For example, -\tcode{std::filesystem::path} is a range of \tcode{std::filesystem::path}. -\end{note} - -\item -Otherwise, if the \grammarterm{qualified-id} \tcode{R::key_type} -is valid and denotes a type: -\begin{itemize} -\item -If the \grammarterm{qualified-id} \tcode{R::mapped_type} -is valid and denotes a type, -let \tcode{U} be \tcode{remove_cvref_t>}. -If either \tcode{U} is a specialization of \tcode{pair} or -\tcode{U} is a specialization of \tcode{tuple} and -\tcode{tuple_size_v == 2}, -\tcode{format_kind} is \tcode{range_format::map}. -\item -Otherwise, \tcode{format_kind} is \tcode{range_format::set}. -\end{itemize} - -\item -Otherwise, \tcode{format_kind} is \tcode{range_format::sequence}. -\end{itemize} - -\pnum -\remarks -Pursuant to \ref{namespace.std}, users may specialize \tcode{format_kind} -for cv-unqualified program-defined types -that model \tcode{ranges::\libconcept{input_range}}. -Such specializations shall be usable in constant expressions\iref{expr.const} -and have type \tcode{const range_format}. -\end{itemdescr} - -\indexlibraryglobal{range_formatter}% -\begin{codeblock} -namespace std { - template - requires @\libconcept{same_as}@, T> && @\libconcept{formattable}@ - class range_formatter { - formatter @\exposid{underlying_}@; // \expos - basic_string_view @\exposid{separator_}@ = @\exposid{STATICALLY-WIDEN}@(", "); // \expos - basic_string_view @\exposid{opening-bracket_}@ = @\exposid{STATICALLY-WIDEN}@("["); // \expos - basic_string_view @\exposid{closing-bracket_}@ = @\exposid{STATICALLY-WIDEN}@("]"); // \expos - - public: - constexpr void set_separator(basic_string_view sep); - constexpr void set_brackets(basic_string_view opening, - basic_string_view closing); - constexpr formatter& underlying() { return @\exposid{underlying_}@; } - constexpr const formatter& underlying() const { return @\exposid{underlying_}@; } - - template - constexpr typename ParseContext::iterator - parse(ParseContext& ctx); - - template - requires @\libconcept{formattable}@, charT> && - @\libconcept{same_as}@>, T> - typename FormatContext::iterator - format(R&& r, FormatContext& ctx) const; - }; -} -\end{codeblock} - \indexlibrarymember{set_separator}{range_formatter}% \begin{itemdecl} constexpr void set_separator(basic_string_view sep); @@ -15958,6 +15965,8 @@ An iterator past the end of the output range. \end{itemdescr} +\rSec3[format.range.fmtdef]{Class template \tcode{\exposid{range-default-formatter}}} + \indexlibraryglobal{\exposid{range-default-formatter}}% \begin{codeblock} namespace std { @@ -16032,6 +16041,8 @@ Equivalent to: \tcode{return \exposid{underlying_}.format(elems, ctx);} \end{itemdescr} +\rSec3[format.range.fmtmap]{Specialization of \tcode{\exposid{range-default-formatter}} for maps} + \indexlibraryglobal{\exposid{range-default-formatter}}% \begin{codeblock} namespace std { @@ -16109,6 +16120,8 @@ Equivalent to: \tcode{return \exposid{underlying_}.format(r, ctx);} \end{itemdescr} +\rSec3[format.range.fmtset]{Specialization of \tcode{\exposid{range-default-formatter}} for sets} + \indexlibraryglobal{\exposid{range-default-formatter}}% \begin{codeblock} namespace std { @@ -16173,12 +16186,13 @@ Equivalent to: \tcode{return \exposid{underlying_}.format(r, ctx);} \end{itemdescr} +\rSec3[format.range.fmtstr]{Specialization of \tcode{\exposid{range-default-formatter}} for strings} + \indexlibraryglobal{\exposid{range-default-formatter}}% \begin{codeblock} namespace std { template - requires (K == range_format::string || - K == range_format::debug_string) + requires (K == range_format::string || K == range_format::debug_string) struct @\exposid{range-default-formatter}@ { private: formatter, charT> @\exposid{underlying_}@; // \expos From 290f89b5deeadf77f96981cddbbfacfd8bdb4ce6 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Thu, 28 Jul 2022 16:18:19 -0700 Subject: [PATCH 241/430] P2590R2 Explicit lifetime management --- source/basic.tex | 12 +++++- source/memory.tex | 95 ++++++++++++++++++++++++++++++++++++++++++++++ source/support.tex | 14 ++----- 3 files changed, 110 insertions(+), 11 deletions(-) diff --git a/source/basic.tex b/source/basic.tex index ba765a09d4..e29c74255a 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -3334,7 +3334,7 @@ returns a pointer to a suitable created object. \begin{note} Some functions in the \Cpp{} standard library implicitly create objects% -\iref{allocator.traits.members,c.malloc,cstring.syn,bit.cast}. +\iref{obj.lifetime,allocator.traits.members,c.malloc,cstring.syn,bit.cast}. \end{note} \indextext{object model|)} @@ -5309,6 +5309,16 @@ even though they have the same address. \end{note} +\pnum +A byte of storage \placeholder{b} +is \defnx{reachable through}{storage!reachable through a pointer value} +a pointer value that points to an object \placeholder{x} +if there is an object \placeholder{y}, +pointer-interconvertible with \placeholder{x}, +such that \placeholder{b} is within the storage occupied by +\placeholder{y}, or the immediately-enclosing array object +if \placeholder{y} is an array element. + \pnum \indextext{pointer|seealso{\tcode{void*}}}% \indextext{\idxcode{void*}!type}% diff --git a/source/memory.tex b/source/memory.tex index 7c5f586fee..ba7d78f72b 100644 --- a/source/memory.tex +++ b/source/memory.tex @@ -84,6 +84,24 @@ template [[nodiscard]] constexpr T* assume_aligned(T* ptr); // freestanding + // \ref{obj.lifetime}, explicit lifetime management + template + T* start_lifetime_as(void* p) noexcept; + template + const T* start_lifetime_as(const void* p) noexcept; + template + volatile T* start_lifetime_as(volatile void* p) noexcept; + template + const volatile T* start_lifetime_as(const volatile void* p) noexcept; + template + T* start_lifetime_as_array(void* p, size_t n) noexcept; + template + const T* start_lifetime_as_array(const void* p, size_t n) noexcept; + template + volatile T* start_lifetime_as_array(volatile void* p, size_t n) noexcept; + template + const volatile T* start_lifetime_as_array(const volatile void* p, size_t n) noexcept; + // \ref{allocator.tag}, allocator argument tag struct allocator_arg_t { // freestanding explicit allocator_arg_t() = default; // freestanding @@ -810,6 +828,83 @@ \end{note} \end{itemdescr} +\rSec2[obj.lifetime]{Explicit lifetime management} + +\indexlibraryglobal{start_lifetime_as}% +\begin{itemdecl} +template + T* start_lifetime_as(void* p) noexcept; +template + const T* start_lifetime_as(const void* p) noexcept; +template + volatile T* start_lifetime_as(volatile void* p) noexcept; +template + const volatile T* start_lifetime_as(const volatile void* p) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +\tcode{T} is an implicit-lifetime type. + +\pnum +\expects +\range{p}{(char*)p + sizeof(T)} denotes a region of allocated storage +that is +a subset of the region of storage +reachable through\iref{basic.compound} \tcode{p} and +suitably aligned for the type \tcode{T}. + +\pnum +\effects +Implicitly creates objects\iref{intro.object} within the denoted region +as follows: +% FIXME: One expects a process to follow; what are we saying here? +an object \placeholder{a} of type \tcode{T}, whose address is \tcode{p}, and +objects nested within \placeholder{a}. +The object representation of \placeholder{a} +is the contents of the storage prior to the call to \tcode{start_lifetime_as}. +The value of each created object \placeholder{o} +of trivially-copyable type \tcode{U} +is determined in the same manner as for a call +to \tcode{bit_cast(E)}\iref{bit.cast}, +where \tcode{E} is an lvalue of type \tcode{U} denoting \placeholder{o}, +except that the storage is not accessed. +The value of any other created object is unspecified. +\begin{note} +The unspecified value can be indeterminate. +\end{note} + +\pnum +\returns +% FIXME: What is "a"? We need to introduce "a" outside of the \effects clause +A pointer to \placeholder{a}. +\end{itemdescr} + +\indexlibraryglobal{start_lifetime_as_array}% +\begin{itemdecl} +template + T* start_lifetime_as_array(void* p, size_t n) noexcept; +template + const T* start_lifetime_as_array(const void* p, size_t n) noexcept; +template + volatile T* start_lifetime_as_array(volatile void* p, size_t n) noexcept; +template + const volatile T* start_lifetime_as_array(const volatile void* p, size_t n) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +\tcode{n > 0} is \tcode{true}. + +\pnum +\effects +Equivalent to: +\tcode{return *start_lifetime_as(p);} +where \tcode{U} is the type ``array of \tcode{n} \tcode{T}''. +\end{itemdescr} + \rSec2[allocator.tag]{Allocator argument tag} \indexlibraryglobal{allocator_arg_t}% diff --git a/source/support.tex b/source/support.tex index 152dc001c4..f2ec75aaac 100644 --- a/source/support.tex +++ b/source/support.tex @@ -719,6 +719,7 @@ #define @\defnlibxname{cpp_lib_spanstream}@ 202106L // also in \libheader{spanstream} #define @\defnlibxname{cpp_lib_ssize}@ 201902L // also in \libheader{iterator} #define @\defnlibxname{cpp_lib_stacktrace}@ 202011L // also in \libheader{stacktrace} +#define @\defnlibxname{cpp_lib_start_lifetime_as}@ 202207L // also in \libheader{memory} #define @\defnlibxname{cpp_lib_starts_ends_with}@ 201711L // also in \libheader{string}, \libheader{string_view} #define @\defnlibxname{cpp_lib_stdatomic_h}@ 202011L // also in \libheader{stdatomic.h} #define @\defnlibxname{cpp_lib_string_contains}@ 202011L // also in \libheader{string}, \libheader{string_view} @@ -3065,8 +3066,9 @@ An object \placeholder{X} that is within its lifetime\iref{basic.life} and whose type is similar\iref{conv.qual} to \tcode{T} is located at the address \placeholder{A}. -All bytes of storage that would be reachable through the result -are reachable through \tcode{p} (see below). +All bytes of storage that would be +reachable through\iref{basic.compound} the result +are reachable through \tcode{p}. \pnum \returns @@ -3078,14 +3080,6 @@ may be used in a core constant expression if and only if the (converted) value of its argument may be used in place of the function invocation. -A byte of storage \placeholder{b} is -reachable through a pointer value -that points to an object \placeholder{Y} -if there is an object \placeholder{Z}, -pointer-interconvertible with \placeholder{Y}, -such that \placeholder{b} is within the storage occupied by -\placeholder{Z}, or -the immediately-enclosing array object if \placeholder{Z} is an array element. \pnum \begin{note} From 15b6f612bcaba33f364313d4ea64971a7b3173ea Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Thu, 28 Jul 2022 16:26:33 -0700 Subject: [PATCH 242/430] [obj.lifetime] Clarify wording for implicitly created objects. --- source/memory.tex | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/memory.tex b/source/memory.tex index ba7d78f72b..34b1812a8c 100644 --- a/source/memory.tex +++ b/source/memory.tex @@ -858,10 +858,10 @@ \pnum \effects Implicitly creates objects\iref{intro.object} within the denoted region +consisting of an object \placeholder{a} of type \tcode{T} +whose address is \tcode{p}, and +objects nested within \placeholder{a}, as follows: -% FIXME: One expects a process to follow; what are we saying here? -an object \placeholder{a} of type \tcode{T}, whose address is \tcode{p}, and -objects nested within \placeholder{a}. The object representation of \placeholder{a} is the contents of the storage prior to the call to \tcode{start_lifetime_as}. The value of each created object \placeholder{o} From bb57616f5276ef96aac88677666f87406b77a822 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Thu, 28 Jul 2022 16:35:09 -0700 Subject: [PATCH 243/430] [obj.lifetime] Clarify what the 'a' mentioned in the \returns clause refers to --- source/memory.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/memory.tex b/source/memory.tex index 34b1812a8c..5201806b2d 100644 --- a/source/memory.tex +++ b/source/memory.tex @@ -877,8 +877,8 @@ \pnum \returns -% FIXME: What is "a"? We need to introduce "a" outside of the \effects clause -A pointer to \placeholder{a}. +% FIXME: We should introduce "a" outside of the \effects clause +A pointer to the \placeholder{a} defined in the \Fundescx{Effects} paragraph. \end{itemdescr} \indexlibraryglobal{start_lifetime_as_array}% From 6a9fab0acd9450cbe65c7e24268aef6b681d3a18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Wed, 17 Aug 2022 23:20:45 +0100 Subject: [PATCH 244/430] [xrefdelta] Add entry for ranges.copy.wrap, update prior redirection --- source/xrefdelta.tex | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/xrefdelta.tex b/source/xrefdelta.tex index 8c6dd51293..f81f0a2eef 100644 --- a/source/xrefdelta.tex +++ b/source/xrefdelta.tex @@ -62,7 +62,9 @@ \movedxref{fs.req.general}{fs.req} % P2325R3 Views should not be required to be default constructible -\movedxref{range.semi.wrap}{range.copy.wrap} +% P2494R2 Relaxing range adaptors to allow for move only types +% range.semi.wrap => range.copy.wrap => range.move.wrap +\movedxref{range.semi.wrap}{range.move.wrap} % P2210R2 Superior String Splitting \movedxref{range.split.outer}{range.lazy.split.outer} From e24445344d26e3d9a3ad92b939b8c034daa47eb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Sun, 14 Aug 2022 20:53:03 +0100 Subject: [PATCH 245/430] [mdspan.*] Replace remaining "pointer"s with "data_handle_type". These edits are part of LWG Motion 4 (P2604R0) but were accidentally omitted. --- source/containers.tex | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index e54959650a..d283f2a9df 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -20111,15 +20111,16 @@ constexpr mdspan(mdspan&& rhs) = default; template - constexpr explicit mdspan(pointer ptr, OtherIndexTypes... exts); + constexpr explicit mdspan(data_handle_type ptr, OtherIndexTypes... exts); template - constexpr explicit(N != rank_dynamic()) mdspan(pointer p, span exts); + constexpr explicit(N != rank_dynamic()) + mdspan(data_handle_type p, span exts); template constexpr explicit(N != rank_dynamic()) - mdspan(pointer p, const array& exts); - constexpr mdspan(pointer p, const extents_type& ext); - constexpr mdspan(pointer p, const mapping_type& m); - constexpr mdspan(pointer p, const mapping_type& m, const accessor_type& a); + mdspan(data_handle_type p, const array& exts); + constexpr mdspan(data_handle_type p, const extents_type& ext); + constexpr mdspan(data_handle_type p, const mapping_type& m); + constexpr mdspan(data_handle_type p, const mapping_type& m, const accessor_type& a); template @@ -20281,7 +20282,7 @@ \indexlibraryctor{mdspan}% \begin{itemdecl} template - constexpr explicit mdspan(pointer p, OtherIndexTypes... exts); + constexpr explicit mdspan(data_handle_type p, OtherIndexTypes... exts); \end{itemdecl} \begin{itemdescr} @@ -20327,10 +20328,10 @@ \begin{itemdecl} template constexpr explicit(N != rank_dynamic()) - mdspan(pointer p, span exts); + mdspan(data_handle_type p, span exts); template constexpr explicit(N != rank_dynamic()) - mdspan(pointer p, const array& exts); + mdspan(data_handle_type p, const array& exts); \end{itemdecl} \begin{itemdescr} From 762480c9317759ffd6db76f7fef27744776e081d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Wed, 17 Aug 2022 11:41:51 +0100 Subject: [PATCH 246/430] [ranges] Remove now-unused exposition-only "tuple-or-pair". Also fix one missed replacement of "tuple-or-pair" with "tuple" as instructed by LWG-Motion 12 (P2165R4, "tuple-like objects"). --- source/ranges.tex | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index 260c7cd564..d9a44ff8b6 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -4263,15 +4263,10 @@ \begin{codeblock} namespace std::ranges { - template - using @\exposid{tuple-or-pair}@ = @\seebelow@; // \expos - template constexpr auto @\exposid{tuple-transform}@(F&& f, Tuple&& tuple) { // \expos return apply([&](Ts&&... elements) { - return @\exposid{tuple-or-pair}@...>( - invoke(f, std::forward(elements))... - ); + return tuple...>(invoke(f, std::forward(elements))...); }, std::forward(tuple)); } @@ -4283,17 +4278,6 @@ } \end{codeblock} -\pnum -Given some pack of types \tcode{Ts}, -the alias template \exposid{tuple-or-pair} is defined as follows: -\begin{itemize} -\item -If \tcode{sizeof...(Ts)} is 2, -\tcode{\exposid{tuple-or-pair}} denotes \tcode{pair}. -\item -Otherwise, \tcode{\exposid{tuple-or-pair}} denotes \tcode{tuple}. -\end{itemize} - \rSec2[range.all]{All view} \rSec3[range.all.general]{General} From b832e2702df41ebe79ddd9d159ac71e68e9b772a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Sun, 14 Aug 2022 22:26:15 +0100 Subject: [PATCH 247/430] [container.reqmnts] Remove stray `{}` --- source/containers.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/containers.tex b/source/containers.tex index d283f2a9df..89718ce7a9 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -203,7 +203,7 @@ that can represent any non-negative value of \tcode{X::difference_type}. \end{itemdescr} -\begin{itemdecl}{} +\begin{itemdecl} X u; X u = X(); \end{itemdecl} From 6faf321077882806ef4e054b95d322052bc9aa6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Fri, 5 Aug 2022 15:23:25 +0100 Subject: [PATCH 248/430] [over.match.{oper,class.deduct}] Add missing \keyword. --- source/overloading.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/overloading.tex b/source/overloading.tex index 5066e5c430..a43a964b5c 100644 --- a/source/overloading.tex +++ b/source/overloading.tex @@ -632,7 +632,7 @@ String operator + (const String&, const String&); void f() { - const char* p= "one" + "two"; // error: cannot add two pointers; overloaded \tcode{operator+} not considered + const char* p= "one" + "two"; // error: cannot add two pointers; overloaded \tcode{\keyword{operator}+} not considered // because neither operand has class or enumeration type int I = 1 + 1; // always evaluates to \tcode{2} even if class or enumeration types exist // that would perform the operation. @@ -1522,7 +1522,7 @@ F f1 = {Types{}, {}, {}}; // OK, \tcode{F} deduced F f2 = {Types{}, X{}, Y{}}; // OK, \tcode{F} deduced -F f3 = {Types{}, X{}, W{}}; // error: conflicting types deduced; \tcode{operator Y} not considered +F f3 = {Types{}, X{}, W{}}; // error: conflicting types deduced; \tcode{\keyword{operator} Y} not considered \end{codeblock} \end{example} From 946a56f812e5fc1e87265e704e19ad19c0e4a12c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Wed, 17 Aug 2022 15:42:14 +0100 Subject: [PATCH 249/430] [ranges.syn] Align "freestanding" comments --- source/ranges.tex | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index d9a44ff8b6..c1b19f9bea 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -65,7 +65,7 @@ template<@\libconcept{range}@ R> using sentinel_t = decltype(ranges::end(declval())); // freestanding template<@\libconcept{range}@ R> - using const_iterator_t = const_iterator>; // freestanding + using const_iterator_t = const_iterator>; // freestanding template<@\libconcept{range}@ R> using range_difference_t = iter_difference_t>; // freestanding template<@\libconcept{sized_range}@ R> @@ -75,7 +75,7 @@ template<@\libconcept{range}@ R> using range_reference_t = iter_reference_t>; // freestanding template<@\libconcept{range}@ R> - using range_const_reference_t = iter_const_reference_t>; // freestanding + using range_const_reference_t = iter_const_reference_t>; // freestanding template<@\libconcept{range}@ R> using range_rvalue_reference_t = iter_rvalue_reference_t>; // freestanding @@ -121,7 +121,7 @@ concept viewable_range = @\seebelow@; // freestanding template - concept constant_range = @\seebelow@; // freestanding + concept constant_range = @\seebelow@; // freestanding // \ref{view.interface}, class template \tcode{view_interface} template @@ -246,12 +246,12 @@ // \ref{range.as.rvalue}, as rvalue view template<@\libconcept{view}@ V> requires @\libconcept{input_range}@ - class as_rvalue_view; // freestanding + class as_rvalue_view; // freestanding template inline constexpr bool enable_borrowed_range> = enable_borrowed_range; - namespace views { inline constexpr @\unspecnc@ as_rvalue = @\unspecnc@; } // freestanding + namespace views { inline constexpr @\unspecnc@ as_rvalue = @\unspecnc@; } // freestanding // \ref{range.filter}, filter view template<@\libconcept{input_range}@ V, @\libconcept{indirect_unary_predicate}@> Pred> @@ -385,13 +385,13 @@ template<@\libconcept{view}@ V> requires @\libconcept{input_range}@ - class as_const_view; // freestanding + class as_const_view; // freestanding template - inline constexpr bool enable_borrowed_range> = // freestanding + inline constexpr bool enable_borrowed_range> = // freestanding enable_borrowed_range; - namespace views { inline constexpr @\unspec@ as_const = @\unspec@; } // freestanding + namespace views { inline constexpr @\unspecnc@ as_const = @\unspecnc@; } // freestanding // \ref{range.elements}, elements view template<@\libconcept{input_range}@ V, size_t N> From 676ce4f3223cd64386c17f43d28e10f07de85fd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Wed, 17 Aug 2022 11:41:04 +0100 Subject: [PATCH 250/430] [support.srcloc.cons] Use \effects macro instead --- source/support.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/support.tex b/source/support.tex index f2ec75aaac..64d2a509ad 100644 --- a/source/support.tex +++ b/source/support.tex @@ -3529,7 +3529,7 @@ \begin{itemdescr} \pnum -\Fundesc{Effects} +\effects The data members are initialized with valid but unspecified values. \end{itemdescr} From f09e7c5164d6dbc43e4a160aa4676725a83f488d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Wed, 17 Aug 2022 15:03:41 +0100 Subject: [PATCH 251/430] [expr.spaceship, fs.path.generic, temp.inst] Use em-dash for parentheticals, not en-dash. We are using em-dashes elsewhere already. --- source/expressions.tex | 4 ++-- source/iostreams.tex | 2 +- source/templates.tex | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/expressions.tex b/source/expressions.tex index 771923fd34..c081510d7d 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -6432,11 +6432,11 @@ are not predefined; if a standard library declaration\iref{compare.syn,std.modules} of such a class type does not precede\iref{basic.lookup.general} -a use of that type -- +a use of that type --- even an implicit use in which the type is not named (e.g., via the \keyword{auto} specifier\iref{dcl.spec.auto} in a defaulted three-way comparison\iref{class.spaceship} -or use of the built-in operator) -- the program is ill-formed. +or use of the built-in operator) --- the program is ill-formed. \rSec2[expr.rel]{Relational operators}% \indextext{expression!relational operators}% diff --git a/source/iostreams.tex b/source/iostreams.tex index c0bb5aee0b..6bb8483ad9 100644 --- a/source/iostreams.tex +++ b/source/iostreams.tex @@ -13479,7 +13479,7 @@ network or other resource locations. Some operating systems define a single letter followed by a colon -as a drive specifier -- a \grammarterm{root-name} +as a drive specifier --- a \grammarterm{root-name} identifying a specific device such as a disk drive. \end{note} diff --git a/source/templates.tex b/source/templates.tex index f7fd576ae7..0a3eb1a70f 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -5975,7 +5975,7 @@ the same template parameters and the same access as that of the function template \tcode{f} used at that point, except that the scope in which a closure type is -declared\iref{expr.prim.lambda.closure} -- and therefore its associated namespaces -- +declared\iref{expr.prim.lambda.closure} --- and therefore its associated namespaces --- remain as determined from the context of the definition for the default argument. This analysis is called From 5dd17bf20e46a2964131ec208b6ed31cc659c400 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Wed, 17 Aug 2022 23:18:35 +0100 Subject: [PATCH 252/430] [ranges] Add missing requirement on itemdecl, and fix spacing --- source/ranges.tex | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index c1b19f9bea..ac878e7747 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -3439,7 +3439,8 @@ \indexlibraryctor{repeat_view}% \begin{itemdecl} -constexpr explicit repeat_view(const W& value, Bound bound = Bound()); +constexpr explicit repeat_view(const W& value, Bound bound = Bound()) + requires @\libconcept{copy_constructible}@; \end{itemdecl} \begin{itemdescr} @@ -13323,11 +13324,11 @@ template<@\libconcept{forward_range}@ V, @\libconcept{indirect_binary_predicate}@, iterator_t> Pred> requires @\libconcept{view}@ && is_object_v class chunk_by_view : public view_interface> { - V @\exposid{base_}@ = V(); // \expos - @\exposid{movable-box}@ @\exposid{pred_}@ = Pred(); // \expos + V @\exposid{base_}@ = V(); // \expos + @\exposidnc{movable-box}@ @\exposid{pred_}@ = Pred(); // \expos // \ref{range.chunk.by.iter}, class \tcode{chunk_by_view::\exposid{iterator}} - class @\exposid{iterator}@; // \expos + class @\exposidnc{iterator}@; // \expos public: chunk_by_view() requires @\libconcept{default_initializable}@ && @\libconcept{default_initializable}@ = default; @@ -13341,8 +13342,8 @@ constexpr @\exposid{iterator}@ begin(); constexpr auto end(); - constexpr iterator_t @\exposid{find-next}@(iterator_t); // \expos - constexpr iterator_t @\exposid{find-prev}@(iterator_t) // \expos + constexpr iterator_t @\exposidnc{find-next}@(iterator_t); // \expos + constexpr iterator_t @\exposidnc{find-prev}@(iterator_t) // \expos requires @\libconcept{bidirectional_range}@; }; From 54925d078a5933073d69191fe89098d27d04ca6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johel=20Ernesto=20Guerrero=20Pe=C3=B1a?= Date: Tue, 16 Aug 2022 12:49:51 -0400 Subject: [PATCH 253/430] [format.formattable] Fix spacing of _requires-expression_ Resolves https://github.com/cplusplus/draft/pull/5700#discussion_r937166231. --- source/utilities.tex | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/utilities.tex b/source/utilities.tex index 240255ab61..9fa74f46fc 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -15083,11 +15083,11 @@ template concept @\deflibconcept{formattable}@ = @\libconcept{semiregular}@, charT>> && - requires (formatter, charT> f, - const formatter, charT> cf, - T t, - basic_format_context<@\placeholder{fmt-iter-for}@, charT> fc, - basic_format_parse_context pc) { + requires(formatter, charT> f, + const formatter, charT> cf, + T t, + basic_format_context<@\placeholder{fmt-iter-for}@, charT> fc, + basic_format_parse_context pc) { { f.parse(pc) } -> @\libconcept{same_as}@::iterator>; { cf.format(t, fc) } -> @\libconcept{same_as}@<@\placeholder{fmt-iter-for}@>; }; From bb1145f751e2de491873aac5a42faf0a6931c218 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Fri, 12 Aug 2022 12:03:55 +0100 Subject: [PATCH 254/430] [mdspan.{overview,extents.ctor}] Increase reuse of definitions --- source/containers.tex | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index 89718ce7a9..9b75089696 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -18224,6 +18224,10 @@ the product of $U_i - L_i$ for each dimension $i$ if its rank is greater than 0, and 1 otherwise. +\pnum +An integer $r$ is a \defn{rank index} of an index space $S$ +if $r$ is in the range $[0, \text{rank of $S$})$. + \pnum A pack of integers \tcode{idx} is a \defnadj{multidimensional}{index} in a multidimensional index space $S$ @@ -18232,15 +18236,11 @@ \item \tcode{sizeof...(idx)} is equal to the rank of $S$, and \item -for all $i$ in the range $[0, \text{rank of $S$})$, +for every rank index $i$ of $S$, the $i^\text{th}$ value of \tcode{idx} is an integer in the interval $[L_i, U_i)$ of $S$. \end{itemize} -\pnum -An integer $r$ is a \defn{rank index} of an index space $S$ -if $r$ is in the range $[0, \text{rank of $S$})$. - \rSec2[mdspan.extents]{Class template \tcode{extents}} \rSec3[mdspan.extents.overview]{Overview} @@ -18473,9 +18473,13 @@ \end{itemdecl} \begin{itemdescr} +\pnum +Let \tcode{N} be \tcode{sizeof...(OtherIndexTypes)}, +and let \tcode{exts_arr} be +\tcode{array\{static_cast<\\index_type>(std::move(exts))...\}}. + \pnum \constraints -Let \tcode{N} be \tcode{sizeof...(OtherIndexTypes)}. \begin{itemize} \item \tcode{(is_convertible_v \&\& ...)} is \tcode{true}, @@ -18490,17 +18494,11 @@ \end{note} \end{itemize} -\pnum -Let \tcode{exts_arr} be -\begin{codeblock} -array{static_cast(std::move(exts))...} -\end{codeblock} - \pnum \expects \begin{itemize} \item -If \tcode{sizeof...(OtherIndexTypes) != rank_dynamic()} is \tcode{true}, +If \tcode{N != rank_dynamic()} is \tcode{true}, \tcode{exts_arr[$r$]} equals $E_r$ for each $r$ for which $E_r$ is a static extent, and \item From a4abb90c28c63e926280aee76b3a8c43bddb97b6 Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Mon, 8 Aug 2022 22:25:18 +0800 Subject: [PATCH 255/430] [range.join.with.sentinel] Fix template format --- source/ranges.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index ac878e7747..d4b7708c3c 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -7401,7 +7401,7 @@ constexpr @\exposid{sentinel}@(@\exposid{sentinel}@ s) requires Const && @\libconcept{convertible_to}@, sentinel_t<@\exposid{Base}@>>; - template + template requires @\libconcept{sentinel_for}@, iterator_t<@\exposid{maybe-const}@>> friend constexpr bool operator==(const @\exposid{iterator}@& x, const @\exposid{sentinel}@& y); }; @@ -7430,7 +7430,7 @@ \end{itemdescr} \begin{itemdecl} -template +template requires @\libconcept{sentinel_for}@, iterator_t<@\exposid{maybe-const}@>> friend constexpr bool operator==(const @\exposid{iterator}@& x, const @\exposid{sentinel}@& y); \end{itemdecl} From a9301c388b8b68ee3919f27597adba17a2a72459 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johel=20Ernesto=20Guerrero=20Pe=C3=B1a?= Date: Thu, 18 Aug 2022 10:35:46 -0400 Subject: [PATCH 256/430] [format] Remove redundant `\tcode` around `\exposid` --- source/utilities.tex | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/utilities.tex b/source/utilities.tex index 9fa74f46fc..79f130fb3e 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -13900,7 +13900,7 @@ requires @\libconcept{same_as}@, T> && @\libconcept{formattable}@ class range_formatter; - // \ref{format.range.fmtdef}, class template \tcode{\exposid{range-default-formatter}} + // \ref{format.range.fmtdef}, class template \exposid{range-default-formatter} template struct @\exposid{range-default-formatter}@; // \expos @@ -15965,7 +15965,7 @@ An iterator past the end of the output range. \end{itemdescr} -\rSec3[format.range.fmtdef]{Class template \tcode{\exposid{range-default-formatter}}} +\rSec3[format.range.fmtdef]{Class template \exposid{range-default-formatter}} \indexlibraryglobal{\exposid{range-default-formatter}}% \begin{codeblock} @@ -16041,7 +16041,7 @@ Equivalent to: \tcode{return \exposid{underlying_}.format(elems, ctx);} \end{itemdescr} -\rSec3[format.range.fmtmap]{Specialization of \tcode{\exposid{range-default-formatter}} for maps} +\rSec3[format.range.fmtmap]{Specialization of \exposid{range-default-formatter} for maps} \indexlibraryglobal{\exposid{range-default-formatter}}% \begin{codeblock} @@ -16120,7 +16120,7 @@ Equivalent to: \tcode{return \exposid{underlying_}.format(r, ctx);} \end{itemdescr} -\rSec3[format.range.fmtset]{Specialization of \tcode{\exposid{range-default-formatter}} for sets} +\rSec3[format.range.fmtset]{Specialization of \exposid{range-default-formatter} for sets} \indexlibraryglobal{\exposid{range-default-formatter}}% \begin{codeblock} @@ -16186,7 +16186,7 @@ Equivalent to: \tcode{return \exposid{underlying_}.format(r, ctx);} \end{itemdescr} -\rSec3[format.range.fmtstr]{Specialization of \tcode{\exposid{range-default-formatter}} for strings} +\rSec3[format.range.fmtstr]{Specialization of \exposid{range-default-formatter} for strings} \indexlibraryglobal{\exposid{range-default-formatter}}% \begin{codeblock} From e97f917d3fd39d7fb2421105d8e45cb73bd24a1e Mon Sep 17 00:00:00 2001 From: Eelis van der Weegen Date: Thu, 18 Aug 2022 18:42:15 +0200 Subject: [PATCH 257/430] [range.zip.transform.view] Fix typo: mmove_constructible. --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index d4b7708c3c..9713628f66 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -10039,7 +10039,7 @@ \indexlibrarymember{size}{zip_transform_view}% \begin{codeblock} namespace std::ranges { - template<@\libconcept{mmove_constructible}@ F, @\libconcept{input_range}@... Views> + template<@\libconcept{move_constructible}@ F, @\libconcept{input_range}@... Views> requires (@\libconcept{view}@ && ...) && (sizeof...(Views) > 0) && is_object_v && @\libconcept{regular_invocable}@...> && @\exposconcept{can-reference}@...>> From f440cfa4e3ebf139b5acec3735e90d4acf5785e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Thu, 18 Aug 2022 15:25:55 +0100 Subject: [PATCH 258/430] [ranges.syn] Add missing "freestanding" comment for as_rvalue. --- source/ranges.tex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index 9713628f66..0d2820c87e 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -249,7 +249,8 @@ class as_rvalue_view; // freestanding template - inline constexpr bool enable_borrowed_range> = enable_borrowed_range; + inline constexpr bool enable_borrowed_range> = // freestanding + enable_borrowed_range; namespace views { inline constexpr @\unspecnc@ as_rvalue = @\unspecnc@; } // freestanding From 999005ab72ca0078b3361979584007dd9d991fac Mon Sep 17 00:00:00 2001 From: Yihe Li Date: Fri, 5 Aug 2022 08:49:10 +0800 Subject: [PATCH 259/430] [strings.general] Add header to "String classes" row --- source/strings.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/strings.tex b/source/strings.tex index 14b81b8661..44b8b76fc3 100644 --- a/source/strings.tex +++ b/source/strings.tex @@ -20,7 +20,7 @@ \begin{libsumtab}[x{2.1in}]{Strings library summary}{strings.summary} \ref{char.traits} & Character traits & \tcode{} \\ \ref{string.view} & String view classes & \tcode{} \\ \rowsep -\ref{string.classes} & String classes & \\ \rowsep +\ref{string.classes} & String classes & \tcode{} \\ \rowsep \ref{c.strings} & Null-terminated sequence utilities & \tcode{}, \tcode{}, \tcode{}, \tcode{}, \tcode{}, \tcode{} \\ From 1fbf5f8b683802849cfc8bb57fef3f48a61bd242 Mon Sep 17 00:00:00 2001 From: Yihe Li Date: Fri, 5 Aug 2022 08:49:40 +0800 Subject: [PATCH 260/430] [thread.general] Remove non-existent header --- source/threads.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/threads.tex b/source/threads.tex index 9ce34c9939..f5d47ec09d 100644 --- a/source/threads.tex +++ b/source/threads.tex @@ -14,7 +14,7 @@ \ref{thread.stoptoken}& Stop tokens & \tcode{} \\ \rowsep \ref{thread.threads} & Threads & \tcode{} \\ \rowsep \ref{atomics} & Atomic operations & - \tcode{} \tcode{} \tcode{} \\ \rowsep + \tcode{}, \tcode{} \\ \rowsep \ref{thread.mutex} & Mutual exclusion & \tcode{}, \tcode{} \\ \rowsep \ref{thread.condition}& Condition variables & \tcode{} \\ \rowsep From 0d7d1d70641a773f67b08f4de44e53f00e3b352d Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 24 Jun 2022 15:40:43 +0200 Subject: [PATCH 261/430] [temp.inst] Clarify referent of 'declaration' --- source/templates.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/templates.tex b/source/templates.tex index 0a3eb1a70f..e166e10446 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -5784,7 +5784,7 @@ \end{example} However, for the purpose of determining whether an instantiated redeclaration is valid according to~\ref{basic.def.odr} and \ref{class.mem}, -a declaration that corresponds to a definition in the template +an instantiated declaration that corresponds to a definition in the template is considered to be a definition. \begin{example} \begin{codeblock} From 99bc532e3c9440defd761985d2329da064b7f9f9 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Thu, 23 Jun 2022 23:17:13 +0200 Subject: [PATCH 262/430] [module.private.frag] Remove misleading example and broaden note --- source/modules.tex | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/source/modules.tex b/source/modules.tex index 075f05e62c..3701762ced 100644 --- a/source/modules.tex +++ b/source/modules.tex @@ -803,7 +803,7 @@ \begin{itemize} \item the point by which the definition of -an exported inline function +an inline function or variable is required\iref{dcl.inline}, \item @@ -833,12 +833,11 @@ export module A; export inline void fn_e(); // error: exported inline function \tcode{fn_e} not defined // before private module fragment -inline void fn_m(); // OK, module-linkage inline function +inline void fn_m(); // error: non-exported inline function \tcode{fn_m} not defined static void fn_s(); export struct X; export void g(X *x) { fn_s(); // OK, call to static function in same translation unit - fn_m(); // OK, call to module-linkage inline function } export X *factory(); // OK From 596137c054407d4d5f2ccf327bd5d3e2a8b4fef5 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Tue, 17 May 2022 09:49:27 +0800 Subject: [PATCH 263/430] [mem.poly.allocator.class.general] Clarify polymorphic_allocator etc. --- source/memory.tex | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/source/memory.tex b/source/memory.tex index 5201806b2d..000d3f4fb3 100644 --- a/source/memory.tex +++ b/source/memory.tex @@ -5498,7 +5498,8 @@ \pnum A specialization of class template \tcode{pmr::polymorphic_allocator} meets -the \oldconcept{Allocator} requirements\iref{allocator.requirements.general}. +the \oldconcept{Allocator} requirements\iref{allocator.requirements.general} +if its template argument is a \cv-unqualified object type. Constructed with different memory resources, different instances of the same specialization of \tcode{pmr::polymorphic_allocator} can exhibit entirely different allocation behavior. @@ -5507,8 +5508,9 @@ even though they use the same static allocator type. \pnum -All specializations of class template \tcode{pmr::polymorphic_allocator} -meet the allocator completeness requirements\iref{allocator.requirements.completeness}. +A specialization of class template \tcode{pmr::polymorphic_allocator} +meets the allocator completeness requirements\iref{allocator.requirements.completeness} +if its template argument is a \cv-unqualified object type. \indexlibraryglobal{polymorphic_allocator}% \indexlibrarymember{value_type}{polymorphic_allocator}% From 6a6823297b3d4c58c77aafefb3c0638a79552476 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johel=20Ernesto=20Guerrero=20Pe=C3=B1a?= Date: Thu, 18 Aug 2022 13:20:37 -0400 Subject: [PATCH 264/430] [ranges.cartesian.iterator] Add missing \exposid (#5737) --- source/ranges.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index 0d2820c87e..d932a0d49e 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -14653,8 +14653,8 @@ \end{itemdescr} \begin{itemdecl} -constexpr explicit @\exposid{iterator}@(tuple>, - iterator_t>...> current); +constexpr explicit @\exposid{iterator}@(tuple>, + iterator_t<@\exposid{maybe-const}@>...> current); \end{itemdecl} \begin{itemdescr} From 193cfc17cbb73e7e6c65d1e596ef9c1a035c7811 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 5 Nov 2021 19:58:41 +0100 Subject: [PATCH 265/430] [diff.dcl] Discuss 'alignas' placement restrictions --- source/compatibility.tex | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/source/compatibility.tex b/source/compatibility.tex index 991dd1523b..839dbc2fcc 100644 --- a/source/compatibility.tex +++ b/source/compatibility.tex @@ -2719,6 +2719,27 @@ Taking the size of an enumerator is not a common C coding practice. +\diffref{dcl.align} +\change +In \Cpp{}, +an \grammarterm{alignment-specifier} is an \grammarterm{attribute-specifier}. +In C, an \grammarterm{alignment-specifier} is a \gterm{declaration-specifier}. + +Example: +\begin{codeblock} +#include +unsigned alignas(8) int x; // valid C, invalid \Cpp{} +unsigned int y alignas(8); // valid \Cpp{}, invalid C +\end{codeblock} +\rationale +\Cpp{} requires unambiguous placement of the \grammarterm{alignment-specifier}. +\effect +Deletion of semantically well-defined feature. +\difficulty +Syntactic transformation. +\howwide +Seldom. + \rSec2[diff.class]{\ref{class}: classes} \diffref{class.name} [see also \ref{dcl.typedef}] From 8b2d70502c379b96ddb9d6eb97d5aafcc1d4765c Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 5 Nov 2021 20:00:00 +0100 Subject: [PATCH 266/430] [diff.dcl] Remove 'implicit int' discussion C99 has removed implicit int. --- source/compatibility.tex | 38 -------------------------------------- 1 file changed, 38 deletions(-) diff --git a/source/compatibility.tex b/source/compatibility.tex index 839dbc2fcc..1d3830326e 100644 --- a/source/compatibility.tex +++ b/source/compatibility.tex @@ -2485,44 +2485,6 @@ \howwide Seldom. -\diffref{dcl.type} -\change -Banning implicit \tcode{int}. - -In \Cpp{} a -\grammarterm{decl-specifier-seq} -must contain a -\grammarterm{type-specifier}{}, unless -it is followed by a declarator for a constructor, a destructor, or a -conversion function. -In the following example, the -left-hand column presents valid C; -the right-hand column presents -equivalent \Cpp{}: - -\begin{codeblock} -void f(const parm); void f(const int parm); -const n = 3; const int n = 3; -main() int main() - @\commentellip@ @\commentellip@ -\end{codeblock} - -\rationale -In \Cpp{}, implicit int creates several opportunities for -ambiguity between expressions involving function-like -casts and declarations. -Explicit declaration is increasingly considered -to be proper style. -Liaison with WG14 (C) indicated support for (at least) -deprecating implicit int in the next revision of C. -\effect -Deletion of semantically well-defined feature. -\difficulty -Syntactic transformation. -Can be automated. -\howwide -Common. - \diffref{dcl.spec.auto} \change The keyword \keyword{auto} cannot be used as a storage class specifier. From f91c425a8fe6f0dd826bd399a5bc82796aec8180 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 4 Mar 2022 21:20:21 +0100 Subject: [PATCH 267/430] [diff.expr] Remove 'implicit function declaration' discussion C99 has removed implicit function declarations. --- source/compatibility.tex | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/source/compatibility.tex b/source/compatibility.tex index 1d3830326e..7c581bf5d4 100644 --- a/source/compatibility.tex +++ b/source/compatibility.tex @@ -2275,21 +2275,6 @@ Some ISO C translators will give a warning if the cast is not used. -\diffref{expr.call} -\change -Implicit declaration of functions is not allowed. -\rationale -The type-safe nature of \Cpp{}. -\effect -Deletion of semantically well-defined feature. -Note: the original feature was labeled as ``obsolescent'' in ISO C. -\difficulty -Syntactic transformation. -Facilities for producing explicit function declarations are fairly -widespread commercially. -\howwide -Common. - \diffref{expr.post.incr,expr.pre.incr} \change Decrement operator is not allowed with \keyword{bool} operand. From b208eb4da5a97cf800f2822318fd487f332d82ad Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 22 Feb 2019 06:22:04 +0000 Subject: [PATCH 268/430] [meta.trans.other] Use "denotes" in decay, enable_if and conditional --- source/meta.tex | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/meta.tex b/source/meta.tex index e14e0bf049..04f6c7f907 100644 --- a/source/meta.tex +++ b/source/meta.tex @@ -1840,10 +1840,10 @@ \tcode{template\br struct decay;} & Let \tcode{U} be \tcode{remove_reference_t}. If \tcode{is_array_v} is - \tcode{true}, the member typedef \tcode{type} equals + \tcode{true}, the member typedef \tcode{type} denotes \tcode{remove_extent_t*}. If \tcode{is_function_v} is \tcode{true}, - the member typedef \tcode{type} equals \tcode{add_pointer_t}. Otherwise - the member typedef \tcode{type} equals \tcode{remove_cv_t}. + the member typedef \tcode{type} denotes \tcode{add_pointer_t}. Otherwise + the member typedef \tcode{type} denotes \tcode{remove_cv_t}. \begin{tailnote} This behavior is similar to the lvalue-to-rvalue\iref{conv.lval}, array-to-pointer\iref{conv.array}, and function-to-pointer\iref{conv.func} @@ -1857,15 +1857,15 @@ \tcode{template} \tcode{struct enable_if;} & If \tcode{B} is \tcode{true}, the member typedef \tcode{type} - shall equal \tcode{T}; otherwise, there shall be no member + denotes \tcode{T}; otherwise, there shall be no member \tcode{type}. \\ \rowsep \tcode{template}\br \tcode{struct conditional;} & - If \tcode{B} is \tcode{true}, the member typedef \tcode{type} shall equal \tcode{T}. - If \tcode{B} is \tcode{false}, the member typedef \tcode{type} shall equal \tcode{F}. \\ \rowsep + If \tcode{B} is \tcode{true}, the member typedef \tcode{type} denotes \tcode{T}. + If \tcode{B} is \tcode{false}, the member typedef \tcode{type} denotes \tcode{F}. \\ \rowsep \tcode{template} \tcode{struct common_type;} & From 769e15bd0559a8ff572d2c508f2cce0227229a39 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 22 Feb 2019 07:04:02 +0000 Subject: [PATCH 269/430] [meta.unary.prop.query] Use "is an array type" not "names an array type" --- source/meta.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/meta.tex b/source/meta.tex index 04f6c7f907..dc06efce94 100644 --- a/source/meta.tex +++ b/source/meta.tex @@ -1342,7 +1342,7 @@ \indexlibraryglobal{rank}% \tcode{template\br struct rank;} & - If \tcode{T} names an array type, an integer value representing + If \tcode{T} is an array type, an integer value representing the number of dimensions of \tcode{T}; otherwise, 0. \\ \rowsep \indexlibraryglobal{extent}% From 3d010460fc4159b6f99d430a3cf0eb0ff30d0053 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 22 Feb 2019 07:05:09 +0000 Subject: [PATCH 270/430] [meta.trans.ref] Use "is a referenceable type" and "denotes the type" --- source/meta.tex | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/source/meta.tex b/source/meta.tex index dc06efce94..191eb39f0e 100644 --- a/source/meta.tex +++ b/source/meta.tex @@ -1662,15 +1662,15 @@ \tcode{template\br struct remove_reference;} & If \tcode{T} has type ``reference to \tcode{T1}'' then the - member typedef \tcode{type} names \tcode{T1}; - otherwise, \tcode{type} names \tcode{T}.\\ \rowsep + member typedef \tcode{type} denotes \tcode{T1}; + otherwise, \tcode{type} denotes \tcode{T}.\\ \rowsep \indexlibraryglobal{add_lvalue_reference}% \tcode{template\br struct add_lvalue_reference;} & - If \tcode{T} names a referenceable type\iref{defns.referenceable} then - the member typedef \tcode{type} names \tcode{T\&}; - otherwise, \tcode{type} names \tcode{T}. + If \tcode{T} is a referenceable type\iref{defns.referenceable} then + the member typedef \tcode{type} denotes \tcode{T\&}; + otherwise, \tcode{type} denotes \tcode{T}. \begin{tailnote} This rule reflects the semantics of reference collapsing\iref{dcl.ref}. \end{tailnote} @@ -1679,13 +1679,13 @@ \indexlibraryglobal{add_rvalue_reference}% \tcode{template}\br \tcode{struct add_rvalue_reference;} & - If \tcode{T} names a referenceable type then - the member typedef \tcode{type} names \tcode{T\&\&}; - otherwise, \tcode{type} names \tcode{T}. + If \tcode{T} is a referenceable type then + the member typedef \tcode{type} denotes \tcode{T\&\&}; + otherwise, \tcode{type} denotes \tcode{T}. \begin{tailnote} This rule reflects the semantics of reference collapsing\iref{dcl.ref}. - For example, when a type \tcode{T} names a type \tcode{T1\&}, the type - \tcode{add_rvalue_reference_t} is not an rvalue reference. + For example, when a type \tcode{T} is a reference type \tcode{T1\&}, + the type \tcode{add_rvalue_reference_t} is not an rvalue reference. \end{tailnote} \\ \end{libreqtab2a} From 66cb97967adb501ff352b6e69815b4db10e095bf Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 22 Feb 2019 07:06:14 +0000 Subject: [PATCH 271/430] [meta.trans.sign] Use "is a ... type" and "denotes the type" --- source/meta.tex | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/source/meta.tex b/source/meta.tex index 191eb39f0e..fe5f4a8cc1 100644 --- a/source/meta.tex +++ b/source/meta.tex @@ -1703,13 +1703,13 @@ \indexlibraryglobal{make_signed}% \tcode{template}\br \tcode{struct make_signed;} & - If \tcode{T} names a (possibly cv-qualified) signed integer + If \tcode{T} is a (possibly cv-qualified) signed integer type\iref{basic.fundamental} then the member typedef - \tcode{type} names the type \tcode{T}; otherwise, - if \tcode{T} names a (possibly cv-qualified) unsigned integer - type then \tcode{type} names the corresponding + \tcode{type} denotes \tcode{T}; otherwise, + if \tcode{T} is a (possibly cv-qualified) unsigned integer + type then \tcode{type} denotes the corresponding signed integer type, with the same cv-qualifiers as \tcode{T}; - otherwise, \tcode{type} names the signed integer type with smallest + otherwise, \tcode{type} denotes the signed integer type with smallest rank\iref{conv.rank} for which \tcode{sizeof(T) == sizeof(type)}, with the same cv-qualifiers as \tcode{T}.\br @@ -1719,13 +1719,13 @@ \indexlibraryglobal{make_unsigned}% \tcode{template}\br \tcode{struct make_unsigned;} & - If \tcode{T} names a (possibly cv-qualified) unsigned integer + If \tcode{T} is a (possibly cv-qualified) unsigned integer type\iref{basic.fundamental} then the member typedef - \tcode{type} names the type \tcode{T}; otherwise, - if \tcode{T} names a (possibly cv-qualified) signed integer - type then \tcode{type} names the corresponding + \tcode{type} denotes \tcode{T}; otherwise, + if \tcode{T} is a (possibly cv-qualified) signed integer + type then \tcode{type} denotes the corresponding unsigned integer type, with the same cv-qualifiers as \tcode{T}; - otherwise, \tcode{type} names the unsigned integer type with smallest + otherwise, \tcode{type} denotes the unsigned integer type with smallest rank\iref{conv.rank} for which \tcode{sizeof(T) == sizeof(type)}, with the same cv-qualifiers as \tcode{T}.\br From 485192fb3872c1da42d6cc0ff89230ecb7760c9c Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 22 Feb 2019 07:06:46 +0000 Subject: [PATCH 272/430] [meta.trans.arr] Use "is a type" not "names a type" Also use "denotes" instead of "names" for member typedefs. --- source/meta.tex | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/meta.tex b/source/meta.tex index fe5f4a8cc1..6cfc5a3408 100644 --- a/source/meta.tex +++ b/source/meta.tex @@ -1746,9 +1746,9 @@ \indexlibraryglobal{remove_extent}% \tcode{template\br struct remove_extent;} & - If \tcode{T} names a type ``array of \tcode{U}'', - the member typedef \tcode{type} shall - be \tcode{U}, otherwise \tcode{T}. + If \tcode{T} is a type ``array of \tcode{U}'', + the member typedef \tcode{type} denotes \tcode{U}, + otherwise \tcode{T}. \begin{tailnote} For multidimensional arrays, only the first array dimension is removed. For a type ``array of \tcode{const U}'', the resulting type is @@ -1760,7 +1760,7 @@ \tcode{template\br struct remove_all_extents;} & If \tcode{T} is ``multi-dimensional array of \tcode{U}'', the resulting member - typedef \tcode{type} is \tcode{U}, otherwise \tcode{T}. \\ + typedef \tcode{type} denotes \tcode{U}, otherwise \tcode{T}. \\ \end{libreqtab2a} \pnum From e2d032255ad0f346144659ba43d3eb184163c8bb Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 22 Feb 2019 07:07:15 +0000 Subject: [PATCH 273/430] [meta.trans.ptr] Use "is a referenceable type" not "names ..." --- source/meta.tex | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/meta.tex b/source/meta.tex index 6cfc5a3408..22b3397368 100644 --- a/source/meta.tex +++ b/source/meta.tex @@ -1800,16 +1800,16 @@ struct remove_pointer;} & If \tcode{T} has type ``(possibly cv-qualified) pointer to \tcode{T1}'' then the member typedef \tcode{type} - names \tcode{T1}; otherwise, it names \tcode{T}.\\ \rowsep + denotes \tcode{T1}; otherwise, it denotes \tcode{T}.\\ \rowsep \indexlibraryglobal{add_pointer}% \tcode{template\br struct add_pointer;} & - If \tcode{T} names a referenceable type\iref{defns.referenceable} or a + If \tcode{T} is a referenceable type\iref{defns.referenceable} or a \cv{}~\keyword{void} type then - the member typedef \tcode{type} names the same type as + the member typedef \tcode{type} denotes \tcode{remove_reference_t*}; - otherwise, \tcode{type} names \tcode{T}. \\ + otherwise, \tcode{type} denotes \tcode{T}. \\ \end{libreqtab2a} \rSec3[meta.trans.other]{Other transformations} From 2c9482a15375291528e8742dc7972450c9597d96 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 22 Feb 2019 07:09:00 +0000 Subject: [PATCH 274/430] [meta.trans.other] Use "denotes" --- source/meta.tex | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/meta.tex b/source/meta.tex index 22b3397368..950d2c0690 100644 --- a/source/meta.tex +++ b/source/meta.tex @@ -1827,12 +1827,12 @@ \tcode{template\br struct type_identity;} & - The member typedef \tcode{type} names the type \tcode{T}. \\ \rowsep + The member typedef \tcode{type} denotes \tcode{T}. \\ \rowsep \indexlibraryglobal{remove_cvref}% \tcode{template\br struct remove_cvref;} & - The member typedef \tcode{type} names the same type as + The member typedef \tcode{type} denotes \tcode{remove_cv_t>}. \\ \rowsep @@ -1896,7 +1896,7 @@ \tcode{template}\br \tcode{struct underlying_type;} & - If \tcode{T} is an enumeration type, the member typedef \tcode{type} names + If \tcode{T} is an enumeration type, the member typedef \tcode{type} denotes the underlying type of \tcode{T}\iref{dcl.enum}; otherwise, there is no member \tcode{type}.\br \mandates \tcode{T} is not an incomplete enumeration type. \\ \rowsep @@ -1907,7 +1907,7 @@ & If the expression \tcode{\placeholdernc{INVOKE}(declval(), declval()...)} is well-formed when treated as an unevaluated operand\iref{term.unevaluated.operand}, - the member typedef \tcode{type} names the type + the member typedef \tcode{type} denotes the type \tcode{decltype(\placeholdernc{INVOKE}(declval(), declval()...))}; otherwise, there shall be no member \tcode{type}. Access checking is performed as if in a context unrelated to \tcode{Fn} and From c51087e82583b589481f03d4dad2190a569ce857 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 22 Feb 2019 07:16:14 +0000 Subject: [PATCH 275/430] [meta.trans.cv] use "denotes" in specification of member typedefs --- source/meta.tex | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/source/meta.tex b/source/meta.tex index 950d2c0690..57bd3631fb 100644 --- a/source/meta.tex +++ b/source/meta.tex @@ -1588,9 +1588,8 @@ \indexlibraryglobal{remove_const}% \tcode{template\br struct remove_const;} & - The member typedef \tcode{type} names - the same type as \tcode{T} - except that any top-level const-qualifier has been removed. + The member typedef \tcode{type} denotes the type formed + by removing any top-level const-qualifier from \tcode{T}. \begin{tailexample} \tcode{remove_const_t} evaluates to \tcode{volatile int}, whereas \tcode{remove_const_t} evaluates to @@ -1601,9 +1600,8 @@ \indexlibraryglobal{remove_volatile}% \tcode{template\br struct remove_volatile;} & - The member typedef \tcode{type} names - the same type as \tcode{T} - except that any top-level volatile-qualifier has been removed. + The member typedef \tcode{type} denotes the type formed + by removing any top-level volatile-qualifier from \tcode{T}. \begin{tailexample} \tcode{remove_volatile_t} evaluates to \tcode{const int}, @@ -1614,8 +1612,8 @@ \indexlibraryglobal{remove_cv}% \tcode{template\br struct remove_cv;} & - The member typedef \tcode{type} shall be the same as \tcode{T} - except that any top-level cv-qualifier has been removed. + The member typedef \tcode{type} denotes the type formed + by removing any top-level cv-qualifiers from \tcode{T}. \begin{tailexample} \tcode{remove_cv_t} evaluates to \tcode{int}, whereas \tcode{remove_cv_t} @@ -1627,23 +1625,20 @@ \tcode{template\br struct add_const;} & If \tcode{T} is a reference, function, or top-level const-qualified - type, then \tcode{type} names - the same type as \tcode{T}, otherwise + type, then \tcode{type} denotes \tcode{T}, otherwise \tcode{T const}. \\ \rowsep \indexlibraryglobal{add_volatile}% \tcode{template\br struct add_volatile;} & If \tcode{T} is a reference, function, or top-level volatile-qualified - type, then \tcode{type} names - the same type as \tcode{T}, otherwise + type, then \tcode{type} denotes \tcode{T}, otherwise \tcode{T volatile}. \\ \rowsep \indexlibraryglobal{add_cv}% \tcode{template\br struct add_cv;} & - The member typedef \tcode{type} names - the same type as + The member typedef \tcode{type} denotes \tcode{add_const_t>}. \\ \end{libreqtab2a} From 935ec9e8f13d41bc09f8a27a917008ddf2724a29 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Tue, 23 Apr 2019 10:33:16 +0100 Subject: [PATCH 276/430] [refwrap.unwrapref] Use "denotes" for member typedef --- source/meta.tex | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/meta.tex b/source/meta.tex index 57bd3631fb..11f69c16e7 100644 --- a/source/meta.tex +++ b/source/meta.tex @@ -1924,8 +1924,9 @@ & If \tcode{T} is a specialization \tcode{reference_wrapper} for some type \tcode{X}, - the member typedef \tcode{type} of \tcode{unwrap_reference} is \tcode{X\&}, - otherwise it is \tcode{T}. \\ \rowsep + the member typedef \tcode{type} of \tcode{unwrap_reference} + denotes \tcode{X\&}, + otherwise \tcode{type} denotes \tcode{T}. \\ \rowsep \indexlibraryglobal{unwrap_ref_decay}% \tcode{template} \tcode{unwrap_ref_decay;} From e412ba9b687e4cdd8ed7546b3ec44122b6baabc5 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 22 Apr 2022 18:20:59 +0100 Subject: [PATCH 277/430] [depr.meta.types] use "denotes" for member typedefs --- source/future.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/future.tex b/source/future.tex index 2f13822f8f..093dba383e 100644 --- a/source/future.tex +++ b/source/future.tex @@ -1433,7 +1433,7 @@ to \exposid{default-alignment}. \pnum -The member typedef \tcode{type} is a trivial standard-layout type +The member typedef \tcode{type} denotes a trivial standard-layout type suitable for use as uninitialized storage for any object whose size is at most \tcode{Len} and whose alignment is a divisor of \tcode{Align}. @@ -1473,7 +1473,7 @@ is a complete object type. \pnum -The member typedef \tcode{type} is a trivial standard-layout type +The member typedef \tcode{type} denotes a trivial standard-layout type suitable for use as uninitialized storage for any object whose type is listed in \tcode{Types}; its size shall be at least \tcode{Len}. From 887c0330bdd2e4b504854a5c9d34621e5d10a3d2 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Tue, 27 Nov 2018 21:27:28 +0100 Subject: [PATCH 278/430] [cmp.categories] Replace 'operator admits' phrasing. --- source/support.tex | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/source/support.tex b/source/support.tex index 64d2a509ad..558a999947 100644 --- a/source/support.tex +++ b/source/support.tex @@ -4331,10 +4331,10 @@ \pnum The \tcode{partial_ordering} type is typically used as the result type of a three-way comparison operator\iref{expr.spaceship} -that (a) admits all of the six -two-way comparison operators\iref{expr.rel,expr.eq}, -(b) does not imply substitutability, -and (c) permits two values to be incomparable. +for a type that admits +all of the six two-way comparison operators\iref{expr.rel,expr.eq}, +for which equality need not imply substitutability, +and that permits two values to be incomparable.% \begin{footnote} That is, \tcode{a < b}, \tcode{a == b}, and \tcode{a > b} might all be \tcode{false}. \end{footnote} @@ -4449,9 +4449,9 @@ \pnum The \tcode{weak_ordering} type is typically used as the result type of a three-way comparison operator\iref{expr.spaceship} -that (a) admits all of the six -two-way comparison operators\iref{expr.rel,expr.eq}, -and (b) does not imply substitutability. +for a type that admits +all of the six two-way comparison operators\iref{expr.rel,expr.eq} +and for which equality need not imply substitutability. \indexlibraryglobal{weak_ordering}% \indexlibrarymember{less}{weak_ordering}% @@ -4574,9 +4574,9 @@ \pnum The \tcode{strong_ordering} type is typically used as the result type of a three-way comparison operator\iref{expr.spaceship} -that (a) admits all of the six -two-way comparison operators\iref{expr.rel,expr.eq}, -and (b) does imply substitutability. +for a type that admits +all of the six two-way comparison operators\iref{expr.rel,expr.eq} +and for which equality does imply substitutability. \indexlibraryglobal{strong_ordering}% \indexlibrarymember{less}{strong_ordering}% From 1e3e4180ee26e06abe6eeb648537b36baa92c5b7 Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Fri, 19 Aug 2022 01:33:25 +0800 Subject: [PATCH 279/430] [range.as.const.view] Add missing angle bracket (#5745) --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index d932a0d49e..e035382a94 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -8659,7 +8659,7 @@ \begin{codeblock} namespace std::ranges { template<@\libconcept{input_range}@ V> - requires @\libconcept{view}@V> + requires @\libconcept{view}@ class as_const_view : public view_interface> { V @\exposid{base_}@ = V(); // \expos From d732538953bab8ccdbe4388cfb39b8542a01dc65 Mon Sep 17 00:00:00 2001 From: Arthur O'Dwyer Date: Thu, 21 Jul 2022 10:09:09 -0400 Subject: [PATCH 280/430] [map.cons,multimap.cons,multiset.cons,set.cons,associative.reqmts.general] "sorted with respect to `comp`" https://cplusplus.github.io/LWG/issue3713 LWG3713 points out that we temporarily lost the term of art "sorted with respect to `comp`," and brings back a definition for it. However, several places in the existing draft never actually used that term of art in the first place. Fix them up so that they do. --- source/containers.tex | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index 9b75089696..e2e781aa7f 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -2863,7 +2863,7 @@ \pnum \complexity $N \log N$ in general, where $N$ has the value \tcode{distance(i, j)}; -linear if \range{i}{j} is sorted with \tcode{value_comp()}. +linear if \range{i}{j} is sorted with respect to \tcode{value_comp()}. \end{itemdescr} \indexlibraryctor{set}% @@ -2890,7 +2890,7 @@ \pnum \complexity $N \log N$ in general, where $N$ has the value \tcode{distance(i, j)}; -linear if \range{i}{j} is sorted with \tcode{value_comp()}. +linear if \range{i}{j} is sorted with respect to \tcode{value_comp()}. \end{itemdescr} \indexlibraryctor{set}% @@ -2917,7 +2917,7 @@ \pnum \complexity $N \log N$ in general, where $N$ has the value \tcode{ranges::distance(rg)}; -linear if \tcode{rg} is sorted with \tcode{value_comp()}. +linear if \tcode{rg} is sorted with respect to \tcode{value_comp()}. \end{itemdescr} \indexlibraryctor{set}% @@ -2996,7 +2996,7 @@ \pnum \complexity $N \log N$ in general, where $N$ has the value \tcode{il.size() + a.size()}; -linear if \range{il.begin()}{il.end()} is sorted with \tcode{value_comp()}. +linear if \range{il.begin()}{il.end()} is sorted with respect to \tcode{value_comp()}. \end{itemdescr} \indexordmem{key_comp}% @@ -9819,7 +9819,7 @@ \complexity Linear in $N$ if the range \range{first}{last} -is already sorted using \tcode{comp} +is already sorted with respect to \tcode{comp} and otherwise $N \log N$, where $N$ is \tcode{last - first}. \end{itemdescr} @@ -9839,7 +9839,7 @@ \pnum \complexity -Linear in $N$ if \tcode{rg} is already sorted using \tcode{comp} and +Linear in $N$ if \tcode{rg} is already sorted with respect to \tcode{comp} and otherwise $N \log N$, where $N$ is \tcode{ranges::distance(rg)}. \end{itemdescr} @@ -10381,7 +10381,7 @@ \complexity Linear in $N$ if the range \range{first}{last} -is already sorted using \tcode{comp} +is already sorted with respect to \tcode{comp} and otherwise $N \log N$, where $N$ is \tcode{last - first}. @@ -10402,7 +10402,7 @@ \pnum \complexity -Linear in $N$ if \tcode{rg} is already sorted using \tcode{comp} and +Linear in $N$ if \tcode{rg} is already sorted with respect to \tcode{comp} and otherwise $N \log N$, where $N$ is \tcode{ranges::distance(rg)}. \end{itemdescr} @@ -10716,7 +10716,7 @@ \complexity Linear in $N$ if the range \range{first}{last} -is already sorted using \tcode{comp} +is already sorted with respect to \tcode{comp} and otherwise $N \log N$, where $N$ is \tcode{last - first}. @@ -10736,7 +10736,7 @@ \pnum \complexity -Linear in $N$ if \tcode{rg} is already sorted using \tcode{comp} and +Linear in $N$ if \tcode{rg} is already sorted with respect to \tcode{comp} and otherwise $N \log N$, where $N$ is \tcode{ranges::distance(rg)}. \end{itemdescr} @@ -11030,7 +11030,7 @@ Linear in $N$ if the range \range{first}{last} -is already sorted using \tcode{comp} and otherwise $N \log N$, +is already sorted with respect to \tcode{comp} and otherwise $N \log N$, where $N$ is \tcode{last - first}. \end{itemdescr} @@ -11050,7 +11050,7 @@ \pnum \complexity -Linear in $N$ if \tcode{rg} is already sorted using \tcode{comp} and +Linear in $N$ if \tcode{rg} is already sorted with respect to \tcode{comp} and otherwise $N \log N$, where $N$ is \tcode{ranges::distance(rg)}. \end{itemdescr} From 4db1d62426ef9a9cd8689585d43da38dd3731696 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Fri, 19 Aug 2022 01:36:40 +0800 Subject: [PATCH 281/430] [allocator.requirements.general] Use newer style for SimpleAllocator --- source/lib-intro.tex | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/source/lib-intro.tex b/source/lib-intro.tex index 91f4693725..dc4995847b 100644 --- a/source/lib-intro.tex +++ b/source/lib-intro.tex @@ -2729,21 +2729,18 @@ interface that meets the requirements of \ref{allocator.requirements.general}: \begin{codeblock} -template +template struct SimpleAllocator { - typedef Tp value_type; + using value_type = T; SimpleAllocator(@\textit{ctor args}@); - template SimpleAllocator(const SimpleAllocator& other); + template SimpleAllocator(const SimpleAllocator& other); - [[nodiscard]] Tp* allocate(std::size_t n); - void deallocate(Tp* p, std::size_t n); -}; + [[nodiscard]] T* allocate(std::size_t n); + void deallocate(T* p, std::size_t n); -template -bool operator==(const SimpleAllocator&, const SimpleAllocator&); -template -bool operator!=(const SimpleAllocator&, const SimpleAllocator&); + bool operator==(const SimpleAllocator&) const; +}; \end{codeblock} \end{example} From a458849089b29e3dfc5f9736799c1c6403223f8f Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sun, 12 Jun 2022 16:11:08 +0200 Subject: [PATCH 282/430] [thread.lock.unique.locking] Fix function call expressions --- source/threads.tex | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/source/threads.tex b/source/threads.tex index f5d47ec09d..e5822f6ac7 100644 --- a/source/threads.tex +++ b/source/threads.tex @@ -7301,11 +7301,11 @@ \pnum \ensures \tcode{owns == res}, where \tcode{res} is the value returned by -the call to \tcode{try_lock()}. +\tcode{pm->try_lock()}. \pnum \returns -The value returned by the call to \tcode{try_lock()}. +The value returned by \tcode{pm->try_lock()}. \pnum \throws @@ -7340,15 +7340,15 @@ \pnum \ensures \tcode{owns == res}, where \tcode{res} is the value returned by -the call to \tcode{try_lock_until(abs_time)}. +\tcode{pm->try_lock_until(abs_time)}. \pnum \returns -The value returned by the call to \tcode{try_lock_until(abs_time)}. +The value returned by \tcode{pm->try_lock_until(abs_time)}. \pnum \throws -Any exception thrown by \tcode{pm->try_lock_until()}. \tcode{system_error} when an +Any exception thrown by \tcode{pm->try_lock_until(abstime)}. \tcode{system_error} when an exception is required\iref{thread.req.exception}. \pnum @@ -7377,15 +7377,15 @@ \pnum \ensures -\tcode{owns == res}, where \tcode{res} is the value returned by the call to \tcode{try_lock_for(rel_time)}. +\tcode{owns == res}, where \tcode{res} is the value returned by \tcode{pm->try_lock_for(rel_time)}. \pnum \returns -The value returned by the call to \tcode{try_lock_for(rel_time)}. +The value returned by \tcode{pm->try_lock_for(rel_time)}. \pnum \throws -Any exception thrown by \tcode{pm->try_lock_for()}. \tcode{system_error} when an +Any exception thrown by \tcode{pm->try_lock_for(rel_time)}. \tcode{system_error} when an exception is required\iref{thread.req.exception}. \pnum From dd4ecf3d19bf8a04899324fc72c690880a328a64 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Fri, 13 May 2022 21:51:13 +0200 Subject: [PATCH 283/430] [stacktrace.basic.nonmem] Add missing \pnum before \recommended Also augment check script --- source/diagnostics.tex | 1 + source/threads.tex | 2 +- tools/check-source.sh | 4 +++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/source/diagnostics.tex b/source/diagnostics.tex index 9c2b82be09..9c8268c703 100644 --- a/source/diagnostics.tex +++ b/source/diagnostics.tex @@ -2345,6 +2345,7 @@ \returns A string with a description of \tcode{f}. +\pnum \recommended The description should provide information about the contained evaluation, including information from diff --git a/source/threads.tex b/source/threads.tex index e5822f6ac7..630a2d865b 100644 --- a/source/threads.tex +++ b/source/threads.tex @@ -11153,7 +11153,7 @@ Once evaluation of \tcode{invoke(std::move(g), std::move(xyz))} begins, the function is no longer considered deferred. -\recommended + \recommended If this policy is specified together with other policies, such as when using a \tcode{policy} value of \tcode{launch::async | launch::deferred}, implementations should defer invocation or the selection of the policy when no more concurrency can be effectively diff --git a/tools/check-source.sh b/tools/check-source.sh index 6d53272b64..de9403a933 100755 --- a/tools/check-source.sh +++ b/tools/check-source.sh @@ -206,7 +206,9 @@ done | fail 'subclause without siblings' || failed=1 # Library descriptive macros not immediately preceded by \pnum. for f in $texlibdesc; do - awk '/^\\pnum/ { seenpnum=1; next } /^\\index/ { next } /^\\(constraints|mandates|expects|effects|sync|ensures|returns|throws|complexity|remarks|errors)/ { if(seenpnum == 0) { print FILENAME ":" FNR ":" $0 } } { seenpnum=0 }' $f + sed -n '/begin{itemdescr}/,/end{itemdescr}/{=;p;}' < $f | + sed '/^[0-9]\+$/{N;s/\n/:/;}' | sed "s/.*/$f:&/" | + awk -F: '$3 ~ /^\\pnum/ { seenpnum=1; next } $3 ~ /^\\index/ { next } $3 ~ /^\\(constraints|mandates|expects|effects|sync|ensures|returns|throws|complexity|remarks|errors|recommended)/ { if(seenpnum == 0) { print $0 } } { seenpnum=0 }' done | fail '\\pnum missing' || failed=1 From fe24762404f5ac7bbd6f139a44dbfa42663ec796 Mon Sep 17 00:00:00 2001 From: Barry Revzin Date: Thu, 18 Aug 2022 16:03:10 -0500 Subject: [PATCH 284/430] [stmt.pre] List "compound-statement" explicitly as part of a selection statement This clarifies the substatements of `if consteval` (which has a compound-statement). --- source/statements.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/statements.tex b/source/statements.tex index 3aff25a9b7..0cecb9f5a1 100644 --- a/source/statements.tex +++ b/source/statements.tex @@ -46,7 +46,7 @@ \item for a \grammarterm{compound-statement}, any \grammarterm{statement} of its \grammarterm{statement-seq}, \item - for a \grammarterm{selection-statement}, any of its \grammarterm{statement}{s} (but not its \grammarterm{init-statement}), or + for a \grammarterm{selection-statement}, any of its \grammarterm{statement}{s} or \grammarterm{compound-statement}{s} (but not its \grammarterm{init-statement}), or \item for an \grammarterm{iteration-statement}, its \grammarterm{statement} (but not an \grammarterm{init-statement}). \end{itemize} From 32a3a0208084ed997203cd7ae4f3cc4482fcf9ec Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Fri, 19 Aug 2022 05:05:30 +0800 Subject: [PATCH 285/430] =?UTF-8?q?[const.iterators.alias]=20Use=20\libcon?= =?UTF-8?q?cept=20for=20input=5F=C2=ADiterator=20(#5746)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/iterators.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/iterators.tex b/source/iterators.tex index a3a59b6010..ed857a14c0 100644 --- a/source/iterators.tex +++ b/source/iterators.tex @@ -4201,7 +4201,7 @@ \begin{itemdescr} \pnum \result -If \tcode{S} models \tcode{input_iterator}, \tcode{const_iterator}. +If \tcode{S} models \libconcept{input_iterator}, \tcode{const_iterator}. Otherwise, \tcode{S}. \end{itemdescr} From 2940703c7ee125ce8194f668683ff5b0bbd7791b Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sun, 2 Jan 2022 21:46:02 +0100 Subject: [PATCH 286/430] [core] Replace 'enumerated type' with 'enumeration' The term "enumerated type" is defined in [enumerated.types] for use in the standard library, and is not synonymous with "enumeration type". --- source/basic.tex | 5 ++--- source/classes.tex | 2 +- source/expressions.tex | 4 ++-- source/lib-intro.tex | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/source/basic.tex b/source/basic.tex index e29c74255a..d2ff0bce92 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -5181,9 +5181,8 @@ different types at different times, \ref{class.union}; \item -\defnx{enumerations}{\idxcode{enum}}, which comprise a set of named constant values. -Each distinct enumeration constitutes a different -\defnadj{enumerated}{type}, \ref{dcl.enum}; +\defnx{enumerations}{\idxcode{enum}}, +which comprise a set of named constant values, \ref{dcl.enum}; \item \indextext{member pointer to|see{pointer to member}}% diff --git a/source/classes.tex b/source/classes.tex index 409e40fde9..18b57e45fa 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -770,7 +770,7 @@ \item every member template of class \tcode{T}; \item every enumerator of every member of class \tcode{T} that is an -unscoped enumerated type; and +unscoped enumeration type; and \item every member of every anonymous union that is a member of class \tcode{T}. diff --git a/source/expressions.tex b/source/expressions.tex index c081510d7d..52b4f4d56e 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -877,7 +877,7 @@ values of the bit-field; otherwise, it can be converted to \tcode{\keyword{unsigned} \keyword{int}} if \tcode{\keyword{unsigned} \keyword{int}} can represent all the values of the bit-field. If the bit-field is larger yet, no integral -promotion applies to it. If the bit-field has an enumerated type, it is +promotion applies to it. If the bit-field has enumeration type, it is treated as any other value of that type for promotion purposes. \pnum @@ -1146,7 +1146,7 @@ performed on both operands. \begin{footnote} As a consequence, operands of type \keyword{bool}, \keyword{char8_t}, \keyword{char16_t}, -\keyword{char32_t}, \keyword{wchar_t}, or an enumerated type are converted +\keyword{char32_t}, \keyword{wchar_t}, or of enumeration type are converted to some integral type. \end{footnote} Then the following rules are applied to the promoted operands: diff --git a/source/lib-intro.tex b/source/lib-intro.tex index dc4995847b..590670d176 100644 --- a/source/lib-intro.tex +++ b/source/lib-intro.tex @@ -566,7 +566,7 @@ \pnum Several types defined in \ref{input.output} are -\defnx{enumerated types}{type!enumerated}. +\defnadjx{enumerated}{types}{type}. Each enumerated type may be implemented as an enumeration or as a synonym for an enumeration. \begin{footnote} From a27e5a6ac3a0fc9cb8474b87b92734a923d495c0 Mon Sep 17 00:00:00 2001 From: Hubert Tong Date: Fri, 19 Aug 2022 10:36:20 -0400 Subject: [PATCH 287/430] [stmt.label, except.pre] Use new wording "control-flow-limited" statement (#5413) A new term of art (control-flow-limited statement) is introduced in [stmt.label] to express the restrictions on control flow into a statement (namely jumping to labels). Both [stmt.if] and [except.pre] are updated to use the new term. This rewords "shall not be used to" avoiding question of actual "use": the "shall not be used to" phrasing may be taken to refer only in cases where the actual use occurs or is the primary intent. Instead, the intended restriction can be written in terms of static properties of the constructs so restricted in the style of [stmt.if]. --- source/exceptions.tex | 4 ++-- source/statements.tex | 28 ++++++++++++++++------------ 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/source/exceptions.tex b/source/exceptions.tex index a436edfc57..a4c30a2b45 100644 --- a/source/exceptions.tex +++ b/source/exceptions.tex @@ -72,8 +72,8 @@ \indextext{\idxcode{switch}!and try block}% \indextext{\idxcode{goto}!and handler}% \indextext{\idxcode{switch}!and handler}% -A \tcode{goto} or \keyword{switch} statement shall not be used to transfer control -into a try block or into a handler. +The \grammarterm{compound-statement} of a try block or of a handler is a +control-flow-limited statement\iref{stmt.label}. \begin{example} \begin{codeblock} void f() { diff --git a/source/statements.tex b/source/statements.tex index 0cecb9f5a1..bca992c936 100644 --- a/source/statements.tex +++ b/source/statements.tex @@ -152,6 +152,18 @@ \indextext{label!\idxcode{default}}% Case labels and default labels shall occur only in \keyword{switch} statements. +\pnum +A \defnadj{control-flow-limited}{statement} is a statement \tcode{S} for which: +\begin{itemize} +\item + a \keyword{case} or \keyword{default} label appearing within \tcode{S} shall + be associated with a \keyword{switch} statement\iref{stmt.switch} within + \tcode{S}, and +\item + a label declared in \tcode{S} shall only be referred to by a + statement\iref{stmt.goto} in \tcode{S}. +\end{itemize} + \rSec1[stmt.expr]{Expression statement}% \indextext{statement!expression} @@ -277,6 +289,8 @@ enclosing templated entity\iref{temp.pre}, if the condition is not value-dependent after its instantiation, the discarded substatement (if any) is not instantiated. +Each substatement of a constexpr if statement is a control-flow-limited +statement\iref{stmt.label}. \begin{example} \begin{codeblock} if constexpr (sizeof(int[2])) {} // OK, narrowing allowed @@ -286,12 +300,6 @@ Odr-uses\iref{term.odr.use} in a discarded statement do not require an entity to be defined. \end{note} -A \keyword{case} or \keyword{default} label appearing within such an -\keyword{if} statement shall be associated with a \keyword{switch} -statement\iref{stmt.switch} within the same \keyword{if} statement. -A label\iref{stmt.label} declared in a substatement of a constexpr if -statement shall only be referred to by a statement\iref{stmt.goto} in -the same substatement. \begin{example} \begin{codeblock} template void g(T&& p, Rest&& ...rs) { @@ -364,12 +372,8 @@ \end{note} Otherwise, if the \keyword{else} part of the selection statement is present, then the second substatement is executed. -A \keyword{case} or \keyword{default} label -appearing within such an \keyword{if} statement -shall be associated with a \keyword{switch} statement -within the same \keyword{if} statement. -A label declared in a substatement of a consteval if statement -shall only be referred to by a statement in the same substatement. +Each substatement of a consteval if statement is a control-flow-limited +statement\iref{stmt.label}. \pnum An \keyword{if} statement of the form From 5aa000973bba1ce10ce0f4ca6a3bec61bcea2061 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 19 Aug 2022 10:47:42 -0400 Subject: [PATCH 288/430] [lex.charset] Add missing hyphens In P2071R2 and NameAliases.txt, 0+008E is named SINGLE-SHIFT-2, but it went into the draft as "single shift-2", losing the hyphen between the words. --- source/lex.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/lex.tex b/source/lex.tex index 3763160cc1..0f33bfda64 100644 --- a/source/lex.tex +++ b/source/lex.tex @@ -447,9 +447,9 @@ \unicode{008d}{reverse line feed} \\ \unicode{008d}{reverse index} \\ \unicode{008e}{single shift two} \\ -\unicode{008e}{single shift-2} \\ +\unicode{008e}{single-shift-2} \\ \unicode{008f}{single shift three} \\ -\unicode{008f}{single shift-3} \\ +\unicode{008f}{single-shift-3} \\ \unicode{0090}{device control string} \\ \unicode{0091}{private use one} \\ \unicode{0091}{private use-1} \\ From c3ec9e24a615b9aedd00578f1490d2b623b32102 Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Sat, 20 Aug 2022 04:01:00 +0800 Subject: [PATCH 289/430] [range.as.rvalue.overview] Add \libconcept for same_as (#5753) --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index e035382a94..cf824c2356 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -4446,7 +4446,7 @@ The expression \tcode{views::as_rvalue(E)} is expression-equivalent to: \begin{itemize} \item -\tcode{views::all(E)} if \tcode{same_as, range_reference_t>} is \tcode{true}. +\tcode{views::all(E)} if \tcode{\libconcept{same_as}, range_reference_t>} is \tcode{true}. \item Otherwise, \tcode{as_rvalue_view(E)}. \end{itemize} From 7a94ae19eb8e940a100795d630697d33e4b5fccb Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Sat, 20 Aug 2022 04:01:36 +0800 Subject: [PATCH 290/430] [range.cartesian.view] Use \exposid for bases_ (#5754) --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index cf824c2356..e3f2eb6bd0 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -14445,7 +14445,7 @@ all the underlying ranges, if such a type exists. \pnum -Let $p$ be the product of the sizes of all the ranges in \tcode{bases_}. +Let $p$ be the product of the sizes of all the ranges in \exposid{bases_}. \pnum \expects From 8275c19b3fa9e7cb09f84049ebd6207aceb7ca80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Fri, 19 Aug 2022 17:29:40 +0100 Subject: [PATCH 291/430] [range.cartesian.view] Fix definition of cartesian-product-is-common The original wording seems to have been a copy-paste error. --- source/ranges.tex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index e3f2eb6bd0..c38b37f97f 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -14288,7 +14288,8 @@ template concept @\defexposconcept{cartesian-product-is-common}@ = // \expos - @\exposconcept{cartesian-product-common-arg}@>; + (@\exposconcept{cartesian-product-common-arg}@ && ... && + @\exposconcept{cartesian-product-common-arg}@); template concept @\defexposconcept{cartesian-product-is-sized}@ = // \expos From 4117a1fc1aeb307d6b15c8aba8a54925fb1b4faf Mon Sep 17 00:00:00 2001 From: Mark de Wever Date: Fri, 19 Aug 2022 18:37:58 +0200 Subject: [PATCH 292/430] [format.string.escaped] Fix invalid examples While implementing new features introduced by P2286R8 Formatting Ranges I noticed some issues in the examples. These issues are in the paper too. For s3 the alternative would be to adjust the output instead of the input. --- source/utilities.tex | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/utilities.tex b/source/utilities.tex index 79f130fb3e..ba9975a15a 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -15367,15 +15367,15 @@ %% FIXME: their Unicode characters are not available in our font (Latin Modern). \begin{example} \begin{codeblock} -string s0 = format("[{}]", "h\tllo"); // \tcode{s0} has value: \tcode{[h llo]} -string s1 = format("[{:?}]", "h\tllo"); // \tcode{s1} has value: \tcode{["h\textbackslash tllo"]} -string s3 = format("[{:?}] [{:?}]", '\'', '"'); // \tcode{s3} has value: \tcode{['\textbackslash '', '"']} +string s0 = format("[{}]", "h\tllo"); // \tcode{s0} has value: \tcode{[h llo]} +string s1 = format("[{:?}]", "h\tllo"); // \tcode{s1} has value: \tcode{["h\textbackslash tllo"]} +string s3 = format("[{:?}, {:?}]", '\'', '"'); // \tcode{s3} has value: \tcode{['\textbackslash '', '"']} // The following examples assume use of the UTF-8 encoding string s4 = format("[{:?}]", string("\0 \n \t \x02 \x1b", 9)); - // \tcode{s4} has value: \tcode{[\textbackslash u\{0\} \textbackslash n \textbackslash t \textbackslash u\{2\} \textbackslash u\{1b\}]} -string s5 = format("[{:?}]", "\xc3\x28"); // invalid UTF-8 - // \tcode{s5} has value: \tcode{["\textbackslash x\{c3\}\textbackslash x\{28\}"]} + // \tcode{s4} has value: \tcode{["\textbackslash u\{0\} \textbackslash n \textbackslash t \textbackslash u\{2\} \textbackslash u\{1b\}"]} +string s5 = format("[{:?}]", "\xc3\x28"); // invalid UTF-8 + // \tcode{s5} has value: \tcode{["\textbackslash x\{c3\}\textbackslash x\{28\}"]} \end{codeblock} \end{example} From 2d548b2ec835510685cf2fcb175f7645aa798d72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Fri, 19 Aug 2022 09:35:25 +0100 Subject: [PATCH 293/430] [dcl.fct.def.default] Elaborate on the difference of two declarations This makes it clear that T_1 and T_2 may differ because of the present rule for the purposes of the blanket statement "other than as allowed by the preceding rules" futher below. --- source/declarations.tex | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/declarations.tex b/source/declarations.tex index 8df1c2cd06..52b5847d64 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -6168,7 +6168,9 @@ if $\tcode{F}_2$ has an implicit object parameter of type ``reference to \tcode{C}'', $\tcode{F}_1$ may be an explicit object member function whose - explicit object parameter is of type ``reference to \tcode{C}''; + explicit object parameter is of type ``reference to \tcode{C}'', + in which case $\tcode{T}_1$ would differ from $\tcode{T}_2$ + in that $\tcode{T}_1$ has an additional parameter; \item $\tcode{T}_1$ and $\tcode{T}_2$ may have differing exception specifications; and \item From e4fd79af0f3b1ea93d4257219a7823062601fe71 Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Sat, 20 Aug 2022 21:52:36 +0800 Subject: [PATCH 294/430] [ranges.cartesian.iterator] Add missing @ for libconcept (#5755) --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index c38b37f97f..db781d8340 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -14827,7 +14827,7 @@ \begin{itemdecl} friend constexpr bool operator==(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) - requires \libconcept{equality_comparable}>>; + requires @\libconcept{equality_comparable}@>>; \end{itemdecl} \begin{itemdescr} From 77d4ee637173a7cf9a914fc801a91ce1a63fc0dd Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Sun, 21 Aug 2022 01:20:34 +0800 Subject: [PATCH 295/430] [ranges] Make the prints message format consistent (#5756) --- source/ranges.tex | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index db781d8340..175be0dd3e 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -3395,7 +3395,7 @@ \begin{codeblock} for (int i : views::repeat(17, 4)) cout << i << ' '; -// prints: 17 17 17 17 +// prints \tcode{17 17 17 17} \end{codeblock} \end{example} @@ -13633,8 +13633,8 @@ \begin{example} \begin{codeblock} auto input = views::iota(0, 12) | views::stride(3); -ranges::copy(input, ostream_iterator(cout, " ")); // prints 0 3 6 9 -ranges::copy(input | views::reverse, ostream_iterator(cout, " ")); // prints 9 6 3 0 +ranges::copy(input, ostream_iterator(cout, " ")); // prints \tcode{0 3 6 9} +ranges::copy(input | views::reverse, ostream_iterator(cout, " ")); // prints \tcode{9 6 3 0} \end{codeblock} \end{example} @@ -14254,15 +14254,16 @@ \begin{example} \begin{codeblock} std::vector v { 0, 1, 2 }; -for (auto&& [a,b,c] : std::views::cartesian_product(v, v, v)) { +for (auto&& [a, b, c] : views::cartesian_product(v, v, v)) { std::cout << a << ' ' << b << ' ' << c << '\n'; - // 0 0 0 - // 0 0 1 - // 0 0 2 - // 0 1 0 - // 0 1 1 - // ... } +// The above prints +// \tcode{0 0 0} +// \tcode{0 0 1} +// \tcode{0 0 2} +// \tcode{0 1 0} +// \tcode{0 1 1} +// ... \end{codeblock} \end{example} @@ -15012,7 +15013,7 @@ void f() { for (auto i : ints() | std::views::take(3)) - std::cout << i << ' '; // prints 0 1 2 + std::cout << i << ' '; // prints \tcode{0 1 2} } \end{codeblock} \end{example} From d2ad0017c5584825fce1cbf741c160e4bd6108b3 Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Sun, 21 Aug 2022 01:22:25 +0800 Subject: [PATCH 296/430] [range.chunk.overview,range.slide.overview] Use maths, not code style for N/M (#5500) --- source/ranges.tex | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index 175be0dd3e..803e348cb4 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -11667,11 +11667,11 @@ \rSec3[range.chunk.overview]{Overview} \pnum -\tcode{chunk_view} takes a \libconcept{view} and a number \tcode{N} and +\tcode{chunk_view} takes a \libconcept{view} and a number $N$ and produces a range of \libconcept{view}s -that are \tcode{N}-sized non-overlapping successive chunks of +that are $N$-sized non-overlapping successive chunks of the elements of the original \libconcept{view}, in order. -The last \libconcept{view} in the range can have fewer than \tcode{N} elements. +The last \libconcept{view} in the range can have fewer than $N$ elements. \pnum \indexlibrarymember{chunk}{views}% @@ -12632,13 +12632,13 @@ \rSec3[range.slide.overview]{Overview} \pnum -\tcode{slide_view} takes a \libconcept{view} and a number \tcode{N} and +\tcode{slide_view} takes a \libconcept{view} and a number $N$ and produces a \libconcept{view} -whose $\tcode{M}^\text{th}$ element is a \libconcept{view} over -the $\tcode{M}^\text{th}$ through -$(\tcode{M} + \tcode{N} - 1)^\text{th}$ elements +whose $M^\text{th}$ element is a \libconcept{view} over +the $M^\text{th}$ through +$(M + N - 1)^\text{th}$ elements of the original \libconcept{view}. -If the original \libconcept{view} has fewer than \tcode{N} elements, +If the original \libconcept{view} has fewer than $N$ elements, the resulting \libconcept{view} is empty. \pnum From 1277923e3ac7a35a3713823b5782b57b86f956ed Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Sun, 21 Aug 2022 01:35:35 +0800 Subject: [PATCH 297/430] [range.chunk] Fix subclause headings (#5516) --- source/ranges.tex | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index 803e348cb4..44ae70a9d3 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -11698,7 +11698,7 @@ \end{codeblock} \end{example} -\rSec3[range.chunk.view.input]{\tcode{chunk_view} for input ranges} +\rSec3[range.chunk.view.input]{Class template \tcode{chunk_view} for input ranges} \indexlibrarymember{begin}{chunk_view}% \indexlibrarymember{end}{chunk_view}% @@ -12137,7 +12137,7 @@ Equivalent to: \tcode{return -(y - x);} \end{itemdescr} -\rSec3[range.chunk.view.fwd]{\tcode{chunk_view} for forward ranges} +\rSec3[range.chunk.view.fwd]{Class template \tcode{chunk_view} for forward ranges} \indexlibrarymember{begin}{chunk_view}% \indexlibrarymember{end}{chunk_view}% @@ -12224,7 +12224,7 @@ \end{codeblock} \end{itemdescr} -\rSec3[range.chunk.fwd.iter]{Class template \tcode{chunk_view::\exposid{iterator}} for forward ranges} +\rSec3[range.chunk.fwd.iter]{Class template \tcode{chunk_view::\exposid{iterator}} for forward ranges} \indexlibraryglobal{chunk_view::iterator}% \begin{codeblock} From 2f228c5cad223a5c8d686d91b054ee3bd2d2a123 Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Sun, 21 Aug 2022 05:01:17 +0800 Subject: [PATCH 298/430] [range.as.rvalue.view] Fix accidentally swapped concepts in template head Also fixes the whitespace style around the opening brace. --- source/ranges.tex | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index 44ae70a9d3..fca898a76f 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -4465,10 +4465,9 @@ \begin{codeblock} namespace std::ranges { - template<@\libconcept{input_range}@ V> - requires @\libconcept{view}@ - class @\libglobal{as_rvalue_view}@ : public view_interface> - { + template<@\libconcept{view}@ V> + requires @\libconcept{input_range}@ + class @\libglobal{as_rvalue_view}@ : public view_interface> { V @\exposid{base_}@ = V(); // \expos public: From 22133b42b1a20d542a8f4d18cc425e8c875e567b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Sat, 20 Aug 2022 22:04:26 +0100 Subject: [PATCH 299/430] [complex.members] Remove stray "template" from constructor This peculiar presentation had previously worked in conjuction with a subclause on "explicit specializations", but since those explicit specializations have been removed by P1467R9, the template head does not serve any useful purpose any longer. --- source/numerics.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/numerics.tex b/source/numerics.tex index c940e27b47..f4ac882ab8 100644 --- a/source/numerics.tex +++ b/source/numerics.tex @@ -353,7 +353,7 @@ \indexlibraryctor{complex}% \begin{itemdecl} -template constexpr complex(const T& re = T(), const T& im = T()); +constexpr complex(const T& re = T(), const T& im = T()); \end{itemdecl} \begin{itemdescr} From fee56834fb55355d617a88fe764f9fb20d92c329 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Sat, 20 Aug 2022 22:35:28 +0100 Subject: [PATCH 300/430] [expr.prim.lambda.capture] Add cross reference to [basic.scope.lambda] Suggested by CD review feedback. --- source/expressions.tex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/expressions.tex b/source/expressions.tex index 52b4f4d56e..1a602c4d15 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -2329,7 +2329,8 @@ \pnum An \grammarterm{init-capture} inhabits -the lambda scope of the \grammarterm{lambda-expression}. +the lambda scope\iref{basic.scope.lambda} +of the \grammarterm{lambda-expression}. An \grammarterm{init-capture} without ellipsis behaves as if it declares and explicitly captures a variable of the form ``\keyword{auto} \grammarterm{init-capture} \tcode{;}'', except that: From 8dce0bdfdf8e309481738daff50d656cd9bdcf49 Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Sun, 21 Aug 2022 15:56:13 +0800 Subject: [PATCH 301/430] [const.iterators.types,const.iterators.ops] Use \libconcept for range concepts (#5752) --- source/iterators.tex | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/iterators.tex b/source/iterators.tex index ed857a14c0..e4849c4ad3 100644 --- a/source/iterators.tex +++ b/source/iterators.tex @@ -4333,13 +4333,13 @@ If \tcode{Iterator} models \libconcept{contiguous_iterator}, then \tcode{iterator_concept} denotes \tcode{contiguous_iterator_tag}. \item -Otherwise, if \tcode{Iterator} models \tcode{random_access_iterator}, +Otherwise, if \tcode{Iterator} models \libconcept{random_access_iterator}, then \tcode{iterator_concept} denotes \tcode{random_access_iterator_tag}. \item -Otherwise, if \tcode{Iterator} models \tcode{bidirectional_iterator}, +Otherwise, if \tcode{Iterator} models \libconcept{bidirectional_iterator}, then \tcode{iterator_concept} denotes \tcode{bidirec\-tional_iterator_tag}. \item -Otherwise, if \tcode{Iterator} models \tcode{forward_iterator}, +Otherwise, if \tcode{Iterator} models \libconcept{forward_iterator}, then \tcode{iterator_concept} denotes \tcode{forward_itera\-tor_tag}. \item Otherwise, \tcode{iterator_concept} denotes \tcode{input_iterator_tag}. @@ -4347,7 +4347,7 @@ \pnum The member \grammarterm{typedef-name} \tcode{iterator_category} is defined -if and only if \tcode{Iterator} models \tcode{forward_iterator}. +if and only if \tcode{Iterator} models \libconcept{forward_iterator}. In that case, \tcode{basic_const_iterator::iterator_category} denotes the type \tcode{iterator_traits<\brk{}Iterator>::iterator_category}. @@ -4434,7 +4434,7 @@ \begin{itemdescr} \pnum \returns -If \tcode{Iterator} models \tcode{contiguous_iterator}, +If \tcode{Iterator} models \libconcept{contiguous_iterator}, \tcode{to_address(\exposid{current_})}; otherwise, \tcode{address\-of(*\exposid{current_})}. \end{itemdescr} From 6f70f82eead9ddc10830aedb99286d0db54725ad Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Mon, 22 Aug 2022 02:11:57 +0800 Subject: [PATCH 302/430] [range.repeat.view] Fix typo (#5765) --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index fca898a76f..733daf8a34 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -3408,7 +3408,7 @@ (@\exposid{is-integer-like}@ || @\libconcept{same_as}@)) class @\libglobal{repeat_view}@ : public view_interface> { private: - // \ref{range.repeat.iterator}, class \tcode{range_view::\exposid{iterator}} + // \ref{range.repeat.iterator}, class \tcode{repeat_view::\exposid{iterator}} struct @\exposid{iterator}@; // \expos @\exposid{movable-box}@ @\exposid{value_}@ = W(); // \expos, see \ref{range.move.wrap} From 9b23eab53f2f755632458f23fa024a1624dc9491 Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Mon, 22 Aug 2022 02:35:14 +0800 Subject: [PATCH 303/430] [range.repeat.view] Add \libconcept for same_as (#5764) --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index 733daf8a34..8ba8b52ed6 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -3527,7 +3527,7 @@ \indexlibrarymember{size}{repeat_view}% \begin{itemdecl} -constexpr auto size() const requires (!same_as); +constexpr auto size() const requires (!@\libconcept{same_as}@); \end{itemdecl} \begin{itemdescr} From 89df45a30a48f30d2ab367490b47c2c0a87f4aa6 Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Mon, 22 Aug 2022 01:51:41 +0800 Subject: [PATCH 304/430] [ranges.cartesian.iterator] Fix typo --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index 8ba8b52ed6..a35eefb3c0 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -14958,7 +14958,7 @@ for every integer\newline $0 \le N \le \tcode{sizeof...(Vs)}$, \item \tcode{is_nothrow_move_constructible_v>>}\newline -for every type \tcode{T} in \tcode{F, Vs...}. +for every type \tcode{T} in \tcode{First, Vs...}. \end{itemize} \end{itemdescr} From 35aa22acdf080fc5886d715a965aadd36de28c27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Sun, 21 Aug 2022 01:55:27 +0100 Subject: [PATCH 305/430] [expr.prim.id.unqual] Fix parameter name in example ("y", not "z") The misspelling was a misapplication of the motion paper P2579R0. Also harmonize the local use of whitespace. --- source/expressions.tex | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/source/expressions.tex b/source/expressions.tex index 1a602c4d15..3f9124022f 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -1513,6 +1513,7 @@ \begin{codeblock} void f() { float x, &r = x; + [=]() -> decltype((x)) { // lambda returns \tcode{float const\&} because this lambda is not \tcode{mutable} and // \tcode{x} is an lvalue decltype(x) y1; // \tcode{y1} has type \tcode{float} @@ -1522,14 +1523,16 @@ return y2; }; - [=](decltype((x)) y){ + [=](decltype((x)) y) { decltype((x)) z = x; // OK, \tcode{y} has type \tcode{float\&}, \tcode{z} has type \tcode{float const\&} }; - [=]{ - [](decltype((x)) y){}; // OK, lambda takes a parameter of type \tcode{float const\&} - [x=1](decltype((x)) z){ - decltype((x)) z = x; // OK, \tcode{y} has type \tcode{int\&}, \tcode{z} has type \tcode{int const\&} - }; + + [=] { + [](decltype((x)) y) {}; // OK, lambda takes a parameter of type \tcode{float const\&} + + [x=1](decltype((x)) y) { + decltype((x)) z = x; // OK, \tcode{y} has type \tcode{int\&}, \tcode{z} has type \tcode{int const\&} + }; }; } \end{codeblock} From 2841712fc15f831481d7bd39e084c213596ccfec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Sat, 20 Aug 2022 23:49:21 +0100 Subject: [PATCH 306/430] [vector.syn, vector.bool] Add subclause structure. After the addition of the formatting-related specialization, the original subclause contained several class template synopses without any intervening separation. The header synopsis is rearranged to follow the document order. --- source/containers.tex | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index e2e781aa7f..fd66ccaf4c 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -6095,23 +6095,26 @@ constexpr typename vector::size_type erase_if(vector& c, Predicate pred); - // \ref{vector.bool}, class \tcode{vector} - template class vector; + namespace pmr { + template + using vector = std::vector>; + } + + // \ref{vector.bool}, specialization of \tcode{vector} for \tcode{bool} + // \ref{vector.bool.pspc}, partial class template specialization \tcode{vector} + template + class vector; template constexpr bool @\exposid{is-vector-bool-reference}@ = @\seebelow@; // \expos - template requires @\exposid{is-vector-bool-reference}@ - struct formatter; - // hash support template struct hash; template struct hash>; - namespace pmr { - template - using vector = std::vector>; - } + // \ref{vector.bool.fmt}, formatter specialization for \tcode{vector} + template requires @\exposid{is-vector-bool-reference}@ + struct formatter; } \end{codeblock} @@ -9112,14 +9115,14 @@ \end{codeblock} \end{itemdescr} -\rSec2[vector.bool]{Class \tcode{vector}} +\rSec2[vector.bool]{Specialization of \tcode{vector} for \tcode{bool}} + +\rSec3[vector.bool.pspc]{Partial class template specialization \tcode{vector}} \pnum \indexlibraryglobal{vector}% -To optimize space allocation, a specialization of vector for -\tcode{bool} -elements is provided: - +To optimize space allocation, a partial specialization of \tcode{vector} for +\tcode{bool} elements is provided: \begin{codeblock} namespace std { template @@ -9312,6 +9315,8 @@ \tcode{vector} is not a program-defined specialization. \end{itemdescr} +\rSec3[vector.bool.fmt]{Formatter specialization for \tcode{vector}} + \indexlibraryglobal{formatter}% \begin{codeblock} namespace std { From 259b8d5d1beeaccf793783679ff4956e84774ea4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Mon, 22 Aug 2022 00:03:46 +0100 Subject: [PATCH 307/430] [alg.sorting.general] Make "comp" part of the defined term Suggested by CD review feedback. --- source/algorithms.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/algorithms.tex b/source/algorithms.tex index 43327ae0fe..2dfe75b014 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -6626,7 +6626,7 @@ \pnum \indexdefn{sequence!sorted!with respect to a comparator}% -A sequence is \term{sorted with respect to a comparator} \tcode{comp} +A sequence is \term{sorted with respect to a comparator \tcode{comp}} for a comparator \tcode{comp} if it is sorted with respect to \tcode{comp} and \tcode{identity\{\}} (the identity projection). From c2aee77b6413fe8ce09bf816d1e239fa2b93f4a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Mon, 22 Aug 2022 00:14:49 +0100 Subject: [PATCH 308/430] [mdspan.overview] Extend the definition to "size of a MD index space" Previously, only "size" was the defined term, but P0009R18 asks for the entire phrase to be the defined term. Suggested by CD review feedback. --- source/containers.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/containers.tex b/source/containers.tex index fd66ccaf4c..9b37ed922e 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -18225,7 +18225,7 @@ the $i^\text{th}$ dimension. The \defn{rank} of a multidimensional index space is the number of intervals it represents. -The \defn{size} of a multidimensional index space is +The \defn{size of a multidimensional index space} is the product of $U_i - L_i$ for each dimension $i$ if its rank is greater than 0, and 1 otherwise. From ac27094ee2f367faf32a37008f476d57b19fd999 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Mon, 22 Aug 2022 00:29:15 +0100 Subject: [PATCH 309/430] [mdspan.extents.expo] Add "exposition-only" comments to itemdecls Suggested by CD review feedback. --- source/containers.tex | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index 9b37ed922e..8a22414122 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -18291,15 +18291,15 @@ const extents&) noexcept; // \ref{mdspan.extents.expo}, exposition-only helpers - constexpr size_t @\exposid{fwd-prod-of-extents}@(rank_type) const noexcept; // \expos - constexpr size_t @\exposid{rev-prod-of-extents}@(rank_type) const noexcept; // \expos + constexpr size_t @\exposid{fwd-prod-of-extents}@(rank_type) const noexcept; // \expos + constexpr size_t @\exposid{rev-prod-of-extents}@(rank_type) const noexcept; // \expos template - static constexpr auto @\exposid{index-cast}@(OtherIndexType&&) noexcept; // \expos + static constexpr auto @\exposid{index-cast}@(OtherIndexType&&) noexcept; // \expos private: static constexpr rank_type @\exposid{dynamic-index}@(rank_type) noexcept; // \expos static constexpr rank_type @\exposid{dynamic-index-inv}@(rank_type) noexcept; // \expos - array @\exposid{dynamic-extents}@{}; // \expos + array @\exposid{dynamic-extents}@{}; // \expos }; template @@ -18337,7 +18337,7 @@ \rSec3[mdspan.extents.expo]{Exposition-only helpers} \begin{itemdecl} -static constexpr rank_type @\exposid{dynamic-index}@(rank_type i) noexcept; +static constexpr rank_type @\exposid{dynamic-index}@(rank_type i) noexcept; // \expos \end{itemdecl} \begin{itemdescr} @@ -18351,7 +18351,7 @@ \end{itemdescr} \begin{itemdecl} -static constexpr rank_type @\exposid{dynamic-index-inv}@(rank_type i) noexcept; +static constexpr rank_type @\exposid{dynamic-index-inv}@(rank_type i) noexcept; // \expos \end{itemdecl} \begin{itemdescr} @@ -18366,7 +18366,7 @@ \end{itemdescr} \begin{itemdecl} -constexpr size_t @\exposid{fwd-prod-of-extents}@(rank_type i) const noexcept; +constexpr size_t @\exposid{fwd-prod-of-extents}@(rank_type i) const noexcept; // \expos \end{itemdecl} \begin{itemdescr} @@ -18382,7 +18382,7 @@ \end{itemdescr} \begin{itemdecl} -constexpr size_t @\exposid{rev-prod-of-extents}@(rank_type i) const noexcept; +constexpr size_t @\exposid{rev-prod-of-extents}@(rank_type i) const noexcept; // \expos \end{itemdecl} \begin{itemdescr} @@ -18400,7 +18400,7 @@ \begin{itemdecl} template - static constexpr auto @\exposid{index-cast}@(OtherIndexType&& i) noexcept; + static constexpr auto @\exposid{index-cast}@(OtherIndexType&& i) noexcept; // \expos \end{itemdecl} \begin{itemdescr} From cce4e845272506ad2e0d732d78bce1dcfd02b7c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Mon, 22 Aug 2022 00:34:32 +0100 Subject: [PATCH 310/430] [mdspan.extents.ctor] Consistently use "r" as a maths variable, not code. Suggested by CD review feedback. --- source/containers.tex | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index 8a22414122..9c3f530dae 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -18453,8 +18453,8 @@ \item \tcode{sizeof...(OtherExtents)} is zero, or \item -\tcode{other.extent(r)} is representable as -a value of type \tcode{index_type} for every rank index \tcode{r} of \tcode{other}. +\tcode{other.extent($r$)} is representable as +a value of type \tcode{index_type} for every rank index $r$ of \tcode{other}. \end{itemize} \end{itemize} @@ -18556,8 +18556,8 @@ \item \tcode{N} is zero, or \item -\tcode{exts[r]} is nonnegative and -is representable as a value of type \tcode{index_type} for every rank index \tcode{r}. +\tcode{exts[$r$]} is nonnegative and +is representable as a value of type \tcode{index_type} for every rank index $r$. \end{itemize} \end{itemize} From a284ab6c16f387f95adb85e02ad9c07cf36b08a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Mon, 22 Aug 2022 00:43:14 +0100 Subject: [PATCH 311/430] [mdspan.layout.{reqmts,right.ctor}] Consistently use maths, not code Suggested by CD review feedback. --- source/containers.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index 9c3f530dae..66958f4c36 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -18849,7 +18849,7 @@ \returns \tcode{true} only if for all $k$ in the range $[0, \tcode{m.required_span_size()})$ -there exists an \tcode{i} such that \tcode{m(i...)} equals \tcode{k}. +there exists an \tcode{i} such that \tcode{m(i...)} equals $k$. \begin{note} A mapping can return \tcode{false} even if the condition is met. For certain layouts, it is possibly not feasible to determine efficiently @@ -19406,7 +19406,7 @@ If \tcode{extents_type::rank() > 0} is \tcode{true}, then for all $r$ in the range $[0, \tcode{extents_type::rank()})$, \tcode{other.stride($r$)} equals -\tcode{extents().\exposid{rev-prod-of-extents}(r)}. +\tcode{extents().\exposid{rev-prod-of-extents}($r$)}. \item \tcode{other.required_span_size()} is representable as a value of type \tcode{index_type}\iref{basic.fundamental}. From 3cc477e5b2b4e41e366a6147898569380ab96cd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Mon, 22 Aug 2022 00:48:25 +0100 Subject: [PATCH 312/430] [mdspan.layout.stride.overview] Add missing \exposid. --- source/containers.tex | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index 66958f4c36..9f85b87197 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -19528,9 +19528,9 @@ constexpr mapping() noexcept = default; constexpr mapping(const mapping&) noexcept = default; template - constexpr mapping(const extents_type&, span) noexcept; + constexpr mapping(const extents_type&, span) noexcept; template - constexpr mapping(const extents_type&, const array&) noexcept; + constexpr mapping(const extents_type&, const array&) noexcept; template constexpr explicit(@\seebelow@) mapping(const StridedLayoutMapping&) noexcept; @@ -19561,7 +19561,7 @@ private: extents_type @\exposid{extents_}@{}; // \expos - array @\exposid{strides_}@{}; // \expos + array @\exposid{strides_}@{}; // \expos }; } \end{codeblock} From 62d024620d93fc08611ce9e931fef95c9e064d03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Mon, 22 Aug 2022 00:52:22 +0100 Subject: [PATCH 313/430] [mdspan.accessor.reqmts] Replace "pointer" with "data_handle_type". This edit was part of LWG Motion 4 (P2604R0) but was accidentally omitted. --- source/containers.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/containers.tex b/source/containers.tex index 9f85b87197..63860ec1ef 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -19909,7 +19909,7 @@ \pnum \result A type that models \libconcept{copyable}, and -for which \tcode{is_nothrow_move_constructible_v} is \tcode{true}, +for which \tcode{is_nothrow_move_constructible_v} is \tcode{true}, \tcode{is_nothrow_move_assignable_v} is \tcode{true}, and \tcode{is_nothrow_swappable_v} is \tcode{true}. \begin{note} From 9369f4c7f116244193c7c2ed12ecc4a625790776 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Mon, 22 Aug 2022 00:56:57 +0100 Subject: [PATCH 314/430] [mdspan.layout.stride.expo] Replace "SizeType" with "IndexType". This edit was part of LWG Motion 3 (P2599R2) but was accidentally omitted. --- source/containers.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/containers.tex b/source/containers.tex index 63860ec1ef..3b47a55541 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -19607,7 +19607,7 @@ \begin{codeblock} template constexpr bool @\exposid{is-extents}@ = false; // \expos -template +template constexpr bool @\exposid{is-extents}@> = true; // \expos \end{codeblock} From fd7c919c681630425a48fd01b4c36c631c910303 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Mon, 22 Aug 2022 01:01:14 +0100 Subject: [PATCH 315/430] [mdspan.layout.stride.{ctor,obs}] Add cross references to [mdspan.layout.policy.reqmts] Suggested by CD review feedback. --- source/containers.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index 3b47a55541..b1e027d98a 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -19710,7 +19710,7 @@ \expects \begin{itemize} \item -\tcode{StridedLayoutMapping} meets the layout mapping requirements, +\tcode{StridedLayoutMapping} meets the layout mapping requirements\iref{mdspan.layout.policy.reqmts}, \item \tcode{other.stride($r$) > 0} is \tcode{true} for every rank index $r$ of \tcode{extents()}, @@ -19830,7 +19830,7 @@ \pnum \expects -\tcode{OtherMapping} meets the layout mapping requirements. +\tcode{OtherMapping} meets the layout mapping requirements\iref{mdspan.layout.policy.reqmts}. \pnum \returns From d0c287b45c5b7ec1d5cfffed2eeeed2e2682ed3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Mon, 22 Aug 2022 09:59:57 +0100 Subject: [PATCH 316/430] [flat.multi*] Fix typo ("mutli" => "multi") --- source/containers.tex | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index b1e027d98a..053f9b2767 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -15826,10 +15826,10 @@ const Allocator& a); template<@\exposconcept{container-compatible-range}@ R> - flat_mutlimap(from_range_t fr, R&& rg) + flat_multimap(from_range_t fr, R&& rg) : flat_multimap(fr, std::forward(rg), key_compare()) { } template<@\exposconcept{container-compatible-range}@ R, class Allocator> - flat_mutlimap(from_range_t, R&& rg, const Allocator& a); + flat_multimap(from_range_t, R&& rg, const Allocator& a); template<@\exposconcept{container-compatible-range}@ R> flat_multimap(from_range_t, R&& rg, const key_compare& comp) : flat_multimap(comp) { insert_range(std::forward(rg)); } @@ -16136,7 +16136,7 @@ template flat_multimap(InputIterator first, InputIterator last, const Allocator& a); template<@\exposconcept{container-compatible-range}@ R, class Allocator> - flat_mutlimap(from_range_t, R&& rg, const Allocator& a); + flat_multimap(from_range_t, R&& rg, const Allocator& a); template<@\exposconcept{container-compatible-range}@ R, class Allocator> flat_multimap(from_range_t, R&& rg, const key_compare& comp, const Allocator& a); template @@ -16860,7 +16860,7 @@ This means that a \tcode{flat_multiset} supports the \tcode{a_eq} operations in \ref{associative.reqmts}, but not the \tcode{a_uniq} operations. -For a \tcode{flat_mutliset}, +For a \tcode{flat_multiset}, both the \tcode{key_type} and \tcode{value_type} are \tcode{Key}. \pnum From 06cbf011ea876313132b51f3699b23f942f91123 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Mon, 22 Aug 2022 10:13:01 +0100 Subject: [PATCH 317/430] [containers] Add cross references to "erasure" subclauses In associative containers, the comment in the synopsis is augmented with the name of the class template, since each header contains two class templates (unique and multi). Also fixes some index entry spellings. --- source/containers.tex | 50 ++++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index 053f9b2767..1809382d2f 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -5983,6 +5983,7 @@ void swap(deque& x, deque& y) noexcept(noexcept(x.swap(y))); + // \ref{deque.erasure}, erasure template typename deque::size_type erase(deque& c, const U& value); @@ -6018,6 +6019,7 @@ void swap(forward_list& x, forward_list& y) noexcept(noexcept(x.swap(y))); + // \ref{forward.list.erasure}, erasure template typename forward_list::size_type erase(forward_list& c, const U& value); @@ -6053,6 +6055,7 @@ void swap(list& x, list& y) noexcept(noexcept(x.swap(y))); + // \ref{list.erasure}, erasure template typename list::size_type erase(list& c, const U& value); @@ -6088,6 +6091,7 @@ constexpr void swap(vector& x, vector& y) noexcept(noexcept(x.swap(y))); + // \ref{vector.erasure}, erasure template constexpr typename vector::size_type erase(vector& c, const U& value); @@ -9424,6 +9428,7 @@ map& y) noexcept(noexcept(x.swap(y))); + // \ref{map.erasure}, erasure for \tcode{map} template typename map::size_type erase_if(map& c, Predicate pred); @@ -9446,6 +9451,7 @@ multimap& y) noexcept(noexcept(x.swap(y))); + // \ref{multimap.erasure}, erasure for \tcode{multimap} template typename multimap::size_type erase_if(multimap& c, Predicate pred); @@ -9486,6 +9492,7 @@ set& y) noexcept(noexcept(x.swap(y))); + // \ref{set.erasure}, erasure for \tcode{set} template typename set::size_type erase_if(set& c, Predicate pred); @@ -9506,6 +9513,7 @@ multiset& y) noexcept(noexcept(x.swap(y))); + // \ref{multiset.erasure}, erasure for \tcode{multiset} template typename multiset::size_type erase_if(multiset& c, Predicate pred); @@ -11145,10 +11153,12 @@ unordered_multimap& y) noexcept(noexcept(x.swap(y))); + // \ref{unord.map.erasure}, erasure for \tcode{unordered_map} template typename unordered_map::size_type erase_if(unordered_map& c, Predicate pred); + // \ref{unord.multimap.erasure}, erasure for \tcode{unordered_multimap} template typename unordered_multimap::size_type erase_if(unordered_multimap& c, Predicate pred); @@ -11215,10 +11225,12 @@ unordered_multiset& y) noexcept(noexcept(x.swap(y))); + // \ref{unord.set.erasure}, erasure for \tcode{unordered_set} template typename unordered_set::size_type erase_if(unordered_set& c, Predicate pred); + // \ref{unord.multiset.erasure}, erasure for \tcode{unordered_multiset} template typename unordered_multiset::size_type erase_if(unordered_multiset& c, Predicate pred); @@ -13224,15 +13236,16 @@ struct sorted_unique_t { explicit sorted_unique_t() = default; }; inline constexpr sorted_unique_t sorted_unique{}; - template - size_t erase_if(flat_map& c, Predicate pred); - template struct uses_allocator, Allocator>; + // \ref{flat.map.erasure}, erasure for \tcode{flat_map} + template + size_t erase_if(flat_map& c, Predicate pred); + // \ref{flat.multimap}, class template \tcode{flat_multimap} template, class KeyContainer = vector, class MappedContainer = vector> @@ -13241,15 +13254,16 @@ struct sorted_equivalent_t { explicit sorted_equivalent_t() = default; }; inline constexpr sorted_equivalent_t sorted_equivalent{}; - template - size_t erase_if(flat_multimap& c, - Predicate pred); - template struct uses_allocator, Allocator>; + + // \ref{flat.multimap.erasure}, erasure for \tcode{flat_multimap} + template + size_t erase_if(flat_multimap& c, + Predicate pred); } \end{codeblock} @@ -13267,12 +13281,13 @@ struct sorted_unique_t { explicit sorted_unique_t() = default; }; inline constexpr sorted_unique_t sorted_unique{}; - template - size_t erase_if(flat_set& c, Predicate pred); - template struct uses_allocator, Allocator>; + // \ref{flat.set.erasure}, erasure for \tcode{flat_set} + template + size_t erase_if(flat_set& c, Predicate pred); + // \ref{flat.multiset}, class template \tcode{flat_multiset} template, class KeyContainer = vector> class flat_multiset; @@ -13280,11 +13295,12 @@ struct sorted_equivalent_t { explicit sorted_equivalent_t() = default; }; inline constexpr sorted_equivalent_t sorted_equivalent{}; - template - size_t erase_if(flat_multiset& c, Predicate pred); - template struct uses_allocator, Allocator>; + + // \ref{flat.set.erasure}, erasure for \tcode{flat_multiset} + template + size_t erase_if(flat_multiset& c, Predicate pred); } \end{codeblock} @@ -14513,7 +14529,7 @@ \rSec3[flat.map.overview]{Overview} \pnum -\indexlibraryglobal{flatmap}% +\indexlibraryglobal{flat_map}% A \tcode{flat_map} is a container adaptor that provides an associative container interface that supports unique keys @@ -17361,7 +17377,7 @@ \rSec3[flat.multiset.erasure]{Erasure} -\indexlibrarymember{erase_if}{flatmultiset}% +\indexlibrarymember{erase_if}{flat_multiset}% \begin{itemdecl} template size_t erase_if(flat_multiset& c, Predicate pred); From 3b1461021cb81fbbccd27494ecd60de7daf958b8 Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Mon, 22 Aug 2022 17:56:54 +0800 Subject: [PATCH 318/430] [range.adaptor.tuple] Fix tuple helper parameter name clash (#5769) The code as presented originally was ill-formed. --- source/ranges.tex | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index a35eefb3c0..e524b6a9c8 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -4266,17 +4266,17 @@ \begin{codeblock} namespace std::ranges { template - constexpr auto @\exposid{tuple-transform}@(F&& f, Tuple&& tuple) { // \expos + constexpr auto @\exposid{tuple-transform}@(F&& f, Tuple&& t) { // \expos return apply([&](Ts&&... elements) { return tuple...>(invoke(f, std::forward(elements))...); - }, std::forward(tuple)); + }, std::forward(t)); } template - constexpr void @\exposid{tuple-for-each}@(F&& f, Tuple&& tuple) { // \expos + constexpr void @\exposid{tuple-for-each}@(F&& f, Tuple&& t) { // \expos apply([&](Ts&&... elements) { (invoke(f, std::forward(elements)), ...); - }, std::forward(tuple)); + }, std::forward(t)); } \end{codeblock} From 90c2cfb1fb8e5cb4781a2d8affdc8856279ca09a Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Mon, 22 Aug 2022 09:32:17 +0800 Subject: [PATCH 319/430] [range.repeat.iterator] repeat_view::iterator is not a class template --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index e524b6a9c8..b49cc73422 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -3536,7 +3536,7 @@ Equivalent to: \tcode{return \exposid{to-unsigned-like}(\exposid{bound_});} \end{itemdescr} -\rSec3[range.repeat.iterator]{Class template \tcode{repeat_view::\exposid{iterator}}} +\rSec3[range.repeat.iterator]{Class \tcode{repeat_view::\exposid{iterator}}} \begin{codeblock} namespace std::ranges { From 4762e1b6fa3bcaf4fdc080e2160ab4e9e96f77b6 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Mon, 22 Aug 2022 15:32:10 +0800 Subject: [PATCH 320/430] Fix preconditions for start_lifetime_as_array(p, n) "n > 0 is true" can't be in "Mandates:", and it's in "Preconditions:" according to P2590R2. --- source/memory.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/memory.tex b/source/memory.tex index 000d3f4fb3..99d0514825 100644 --- a/source/memory.tex +++ b/source/memory.tex @@ -895,7 +895,7 @@ \begin{itemdescr} \pnum -\mandates +\expects \tcode{n > 0} is \tcode{true}. \pnum From 28f49c965a394c573fa927792f082a182d422029 Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Mon, 22 Aug 2022 19:29:40 +0800 Subject: [PATCH 321/430] [range.as.const.view] Fix order of constraints in class synopsis (#5760) The header and the class synopses used different orderings in P2446R0, and the ordering from the header synopsis is the desired one. --- source/ranges.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index b49cc73422..93b4a95bd6 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -8657,8 +8657,8 @@ \begin{codeblock} namespace std::ranges { - template<@\libconcept{input_range}@ V> - requires @\libconcept{view}@ + template<@\libconcept{view}@ V> + requires @\libconcept{input_range}@ class as_const_view : public view_interface> { V @\exposid{base_}@ = V(); // \expos From 03d73772246ec6e9fa0becb983be6dc08189d8b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Mon, 22 Aug 2022 12:23:51 +0100 Subject: [PATCH 322/430] [flat.*] Harmonize wording "supports the ... operations but not ..." --- source/containers.tex | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index 1809382d2f..b0f020a29f 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -14568,7 +14568,7 @@ A \tcode{flat_map} also provides most operations described in \ref{associative.reqmts} for unique keys. This means that a \tcode{flat_map} supports -the \tcode{a_uniq} operations in \ref{associative.reqmts}, +the \tcode{a_uniq} operations in \ref{associative.reqmts} but not the \tcode{a_eq} operations. For a \tcode{flat_map} the \tcode{key_type} is \tcode{Key} and @@ -15705,8 +15705,9 @@ \pnum A \tcode{flat_multimap} also provides most operations described in \ref{associative.reqmts} for equal keys. -This means that a \tcode{flat_multimap} supports the \tcode{a_eq} operations -in \ref{associative.reqmts} but not the \tcode{a_uniq} operations. +This means that a \tcode{flat_multimap} supports +the \tcode{a_eq} operations in \ref{associative.reqmts} +but not the \tcode{a_uniq} operations. For a \tcode{flat_multimap} the \tcode{key_type} is \tcode{Key} and the \tcode{value_type} is \tcode{pair}. @@ -16267,8 +16268,8 @@ A \tcode{flat_set} also provides most operations described in \ref{associative.reqmts} for unique keys. This means that a \tcode{flat_set} supports -the \tcode{a_uniq} operations in \ref{associative.reqmts}, -but not support the \tcode{a_eq} operations. +the \tcode{a_uniq} operations in \ref{associative.reqmts} +but not the \tcode{a_eq} operations. For a \tcode{flat_set}, both the \tcode{key_type} and \tcode{value_type} are \tcode{Key}. @@ -16874,7 +16875,7 @@ A \tcode{flat_multiset} also provides most operations described in \ref{associative.reqmts} for equal keys. This means that a \tcode{flat_multiset} supports -the \tcode{a_eq} operations in \ref{associative.reqmts}, +the \tcode{a_eq} operations in \ref{associative.reqmts} but not the \tcode{a_uniq} operations. For a \tcode{flat_multiset}, both the \tcode{key_type} and \tcode{value_type} are \tcode{Key}. From 9934675dd673bfa8e073bd3c2187575b47e6ea44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Mon, 22 Aug 2022 13:48:45 +0100 Subject: [PATCH 323/430] [flat.set.defn] Fix name of function parameter ("rg", not "range") --- source/containers.tex | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index b0f020a29f..5e628ffc2f 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -16363,13 +16363,13 @@ template<@\exposconcept{container-compatible-range}@ R> flat_set(from_range_t fr, R&& rg) - : flat_set(fr, std::forward(range), key_compare()) { } + : flat_set(fr, std::forward(rg), key_compare()) { } template<@\exposconcept{container-compatible-range}@ R, class Allocator> flat_set(from_range_t, R&& rg, const Allocator& a); template<@\exposconcept{container-compatible-range}@ R> flat_set(from_range_t, R&& rg, const key_compare& comp) : flat_set(comp) - { insert_range(std::forward(range)); } + { insert_range(std::forward(rg)); } template<@\exposconcept{container-compatible-range}@ R, class Allocator> flat_set(from_range_t, R&& rg, const key_compare& comp, const Allocator& a); @@ -16970,13 +16970,13 @@ template<@\exposconcept{container-compatible-range}@ R> flat_multiset(from_range_t fr, R&& rg) - : flat_multiset(fr, std::forward(range), key_compare()) { } + : flat_multiset(fr, std::forward(rg), key_compare()) { } template<@\exposconcept{container-compatible-range}@ R, class Allocator> flat_multiset(from_range_t, R&& rg, const Allocator& a); template<@\exposconcept{container-compatible-range}@ R> flat_multiset(from_range_t, R&& rg, const key_compare& comp) : flat_multiset(comp) - { insert_range(std::forward(range)); } + { insert_range(std::forward(rg)); } template<@\exposconcept{container-compatible-range}@ R, class Allocator> flat_multiset(from_range_t, R&& rg, const key_compare& comp, const Allocator& a); From faa173c296bfc3547e6f20af63329ac0e1a024be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Mon, 22 Aug 2022 14:06:39 +0100 Subject: [PATCH 324/430] [flat.multiset.ctor] Add missing parameter name "cont" --- source/containers.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/containers.tex b/source/containers.tex index 5e628ffc2f..6085fa7b03 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -17194,7 +17194,7 @@ \indexlibraryctor{flat_multiset}% \begin{itemdecl} template - flat_multiset(sorted_equivalent_t s, const container_type&, const Allocator& a); + flat_multiset(sorted_equivalent_t s, const container_type& cont, const Allocator& a); \end{itemdecl} \begin{itemdescr} From 1851ef6f7098e8b4805a1d2e0856d800d4fda1aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Mon, 22 Aug 2022 14:34:10 +0100 Subject: [PATCH 325/430] [flat.*.defn] Remove unnecessary linebreaks --- source/containers.tex | 40 ++++++++++++++-------------------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index 6085fa7b03..e4f9960bec 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -15839,8 +15839,7 @@ flat_multimap(InputIterator first, InputIterator last, const key_compare& comp, const Allocator& a); template - flat_multimap(InputIterator first, InputIterator last, - const Allocator& a); + flat_multimap(InputIterator first, InputIterator last, const Allocator& a); template<@\exposconcept{container-compatible-range}@ R> flat_multimap(from_range_t fr, R&& rg) @@ -15864,12 +15863,11 @@ flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, const Allocator& a); - flat_multimap(initializer_list il, - const key_compare& comp = key_compare()) + flat_multimap(initializer_list il, const key_compare& comp = key_compare()) : flat_multimap(il.begin(), il.end(), comp) { } template - flat_multimap(initializer_list il, - const key_compare& comp, const Allocator& a); + flat_multimap(initializer_list il, const key_compare& comp, + const Allocator& a); template flat_multimap(initializer_list il, const Allocator& a); @@ -16351,8 +16349,7 @@ explicit flat_set(const Allocator& a); template - flat_set(InputIterator first, InputIterator last, - const key_compare& comp = key_compare()) + flat_set(InputIterator first, InputIterator last, const key_compare& comp = key_compare()) : c(), compare(comp) { insert(first, last); } template @@ -16371,8 +16368,7 @@ : flat_set(comp) { insert_range(std::forward(rg)); } template<@\exposconcept{container-compatible-range}@ R, class Allocator> - flat_set(from_range_t, R&& rg, const key_compare& comp, - const Allocator& a); + flat_set(from_range_t, R&& rg, const key_compare& comp, const Allocator& a); template flat_set(sorted_unique_t, InputIterator first, InputIterator last, @@ -16385,12 +16381,10 @@ flat_set(sorted_unique_t, InputIterator first, InputIterator last, const Allocator& a); - flat_set(initializer_list il, - const key_compare& comp = key_compare()) + flat_set(initializer_list il, const key_compare& comp = key_compare()) : flat_set(il.begin(), il.end(), comp) { } template - flat_set(initializer_list il, - const key_compare& comp, const Allocator& a); + flat_set(initializer_list il, const key_compare& comp, const Allocator& a); template flat_set(initializer_list il, const Allocator& a); @@ -16401,8 +16395,7 @@ flat_set(sorted_unique_t, initializer_list il, const key_compare& comp, const Allocator& a); template - flat_set(sorted_unique_t, initializer_list il, - const Allocator& a); + flat_set(sorted_unique_t, initializer_list il, const Allocator& a); flat_set& operator=(initializer_list); @@ -16965,8 +16958,7 @@ flat_multiset(InputIterator first, InputIterator last, const key_compare& comp, const Allocator& a); template - flat_multiset(InputIterator first, InputIterator last, - const Allocator& a); + flat_multiset(InputIterator first, InputIterator last, const Allocator& a); template<@\exposconcept{container-compatible-range}@ R> flat_multiset(from_range_t fr, R&& rg) @@ -16978,8 +16970,7 @@ : flat_multiset(comp) { insert_range(std::forward(rg)); } template<@\exposconcept{container-compatible-range}@ R, class Allocator> - flat_multiset(from_range_t, R&& rg, const key_compare& comp, - const Allocator& a); + flat_multiset(from_range_t, R&& rg, const key_compare& comp, const Allocator& a); template flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, @@ -16992,12 +16983,10 @@ flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, const Allocator& a); - flat_multiset(initializer_list il, - const key_compare& comp = key_compare()) + flat_multiset(initializer_list il, const key_compare& comp = key_compare()) : flat_multiset(il.begin(), il.end(), comp) { } template - flat_multiset(initializer_list il, - const key_compare& comp, const Allocator& a); + flat_multiset(initializer_list il, const key_compare& comp, const Allocator& a); template flat_multiset(initializer_list il, const Allocator& a); @@ -17008,8 +16997,7 @@ flat_multiset(sorted_equivalent_t, initializer_list il, const key_compare& comp, const Allocator& a); template - flat_multiset(sorted_equivalent_t, initializer_list il, - const Allocator& a); + flat_multiset(sorted_equivalent_t, initializer_list il, const Allocator& a); flat_multiset& operator=(initializer_list); From a02728c7be86cdb246cc23f72b785b0b769b490b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Mon, 22 Aug 2022 15:05:57 +0100 Subject: [PATCH 326/430] [flat.*set] Remove further linebreaks --- source/containers.tex | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index e4f9960bec..2d879633b6 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -16378,8 +16378,7 @@ flat_set(sorted_unique_t, InputIterator first, InputIterator last, const key_compare& comp, const Allocator& a); template - flat_set(sorted_unique_t, InputIterator first, InputIterator last, - const Allocator& a); + flat_set(sorted_unique_t, InputIterator first, InputIterator last, const Allocator& a); flat_set(initializer_list il, const key_compare& comp = key_compare()) : flat_set(il.begin(), il.end(), comp) { } @@ -16609,8 +16608,7 @@ template explicit flat_set(const Allocator& a); template - flat_set(InputIterator first, InputIterator last, - const key_compare& comp, const Allocator& a); + flat_set(InputIterator first, InputIterator last, const key_compare& comp, const Allocator& a); template flat_set(InputIterator first, InputIterator last, const Allocator& a); template<@\exposconcept{container-compatible-range}@ R, class Allocator> @@ -17211,30 +17209,25 @@ flat_multiset(InputIterator first, InputIterator last, const key_compare& comp, const Allocator& a); template - flat_multiset(InputIterator first, InputIterator last, - const Allocator& a); + flat_multiset(InputIterator first, InputIterator last, const Allocator& a); template<@\exposconcept{container-compatible-range}@ R, class Allocator> flat_multiset(from_range_t, R&& rg, const Allocator& a); template<@\exposconcept{container-compatible-range}@ R, class Allocator> - flat_multiset(from_range_t, R&& rg, const key_compare& comp, - const Allocator& a); + flat_multiset(from_range_t, R&& rg, const key_compare& comp, const Allocator& a); template flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, const key_compare& comp, const Allocator& a); template - flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, - const Allocator& a); + flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, const Allocator& a); template - flat_multiset(initializer_list il, - const key_compare& comp, const Allocator& a); + flat_multiset(initializer_list il, const key_compare& comp, const Allocator& a); template flat_multiset(initializer_list il, const Allocator& a); template flat_multiset(sorted_equivalent_t, initializer_list il, const key_compare& comp, const Allocator& a); template - flat_multiset(sorted_equivalent_t, initializer_list il, - const Allocator& a); + flat_multiset(sorted_equivalent_t, initializer_list il, const Allocator& a); \end{itemdecl} \begin{itemdescr} From abd268b2506725c327c0197871090f73bc727331 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Mon, 22 Aug 2022 15:21:06 +0100 Subject: [PATCH 327/430] [flat.*set.*] Consistently use \exposid --- source/containers.tex | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index 2d879633b6..d6ba5b0b0c 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -16337,12 +16337,12 @@ flat_set(const container_type& cont, const Allocator& a); flat_set(sorted_unique_t, container_type cont) - : c(std::move(cont)), compare(key_compare()) { } + : @\exposid{c}@(std::move(cont)), @\exposid{compare}@(key_compare()) { } template flat_set(sorted_unique_t, const container_type& cont, const Allocator& a); explicit flat_set(const key_compare& comp) - : c(), compare(comp) { } + : @\exposid{c}@(), @\exposid{compare}@(comp) { } template flat_set(const key_compare& comp, const Allocator& a); template @@ -16350,7 +16350,7 @@ template flat_set(InputIterator first, InputIterator last, const key_compare& comp = key_compare()) - : c(), compare(comp) + : @\exposid{c}@(), @\exposid{compare}@(comp) { insert(first, last); } template flat_set(InputIterator first, InputIterator last, @@ -16373,7 +16373,7 @@ template flat_set(sorted_unique_t, InputIterator first, InputIterator last, const key_compare& comp = key_compare()) - : c(first, last), compare(comp) { } + : @\exposid{c}@(first, last), @\exposid{compare}@(comp) { } template flat_set(sorted_unique_t, InputIterator first, InputIterator last, const key_compare& comp, const Allocator& a); @@ -16546,14 +16546,14 @@ \pnum \effects Initializes \exposid{c} with \tcode{std::move(cont)}, -value-initializes \tcode{compare}, -sorts the range \range{begin()}{end()} with respect to \tcode{compare}, and +value-initializes \exposid{compare}, +sorts the range \range{begin()}{end()} with respect to \exposid{compare}, and finally erases all but the first element from each group of consecutive equivalent elements. \pnum \complexity -Linear in $N$ if \tcode{cont} is sorted with respect to \tcode{compare} and +Linear in $N$ if \tcode{cont} is sorted with respect to \exposid{compare} and otherwise $N \log N$, where $N$ is the value of \tcode{cont.size()} before this call. \end{itemdescr} @@ -16690,10 +16690,10 @@ \effects Adds elements to \exposid{c} as if by: \begin{codeblock} -c.insert(c.end(), first, last); +@\exposid{c}@.insert(@\exposid{c}@.end(), first, last); \end{codeblock} Then, -sorts the range of newly inserted elements with respect to \tcode{compare}; +sorts the range of newly inserted elements with respect to \exposid{compare}; merges the resulting sorted range and the sorted range of pre-existing elements into a single sorted range; and finally erases all but the first element @@ -16737,11 +16737,11 @@ Adds elements to \exposid{c} as if by: \begin{codeblock} for (const auto& e : rg) { - c.insert(c.end(), e); + @\exposid{c}@.insert(@\exposid{c}@.end(), e); } \end{codeblock} Then, -sorts the range of newly inserted elements with respect to \tcode{compare}; +sorts the range of newly inserted elements with respect to \exposid{compare}; merges the resulting sorted range and the sorted range of pre-existing elements into a single sorted range; and finally erases all but the first element @@ -16768,7 +16768,7 @@ Equivalent to: \begin{codeblock} ranges::swap(compare, y.compare); -ranges::swap(c, y.c); +ranges::swap(@\exposid{c}@, y.@\exposid{c}@); \end{codeblock} \end{itemdescr} @@ -16784,7 +16784,7 @@ \pnum \returns -\tcode{std::move(c)}. +\tcode{std::move(\exposid{c})}. \end{itemdescr} \indexlibrarymember{replace}{flat_set}% @@ -16795,12 +16795,12 @@ \begin{itemdescr} \pnum \expects -The elements of \tcode{cont} are sorted with respect to \tcode{compare}, and +The elements of \tcode{cont} are sorted with respect to \exposid{compare}, and \tcode{cont} contains no equal elements. \pnum \effects -Equivalent to: \tcode{c = std::move(cont);} +Equivalent to: \tcode{\exposid{c} = std::move(cont);} \end{itemdescr} \rSec3[flat.set.erasure]{Erasure} @@ -16936,12 +16936,12 @@ flat_multiset(const container_type& cont, const Allocator& a); flat_multiset(sorted_equivalent_t, container_type cont) - : c(std::move(cont)), compare(key_compare()) { } + : @\exposid{c}@(std::move(cont)), @\exposid{compare}@(key_compare()) { } template flat_multiset(sorted_equivalent_t, const container_type&, const Allocator& a); explicit flat_multiset(const key_compare& comp) - : c(), compare(comp) { } + : @\exposid{c}@(), @\exposid{compare}@(comp) { } template flat_multiset(const key_compare& comp, const Allocator& a); template @@ -16950,7 +16950,7 @@ template flat_multiset(InputIterator first, InputIterator last, const key_compare& comp = key_compare()) - : c(), compare(comp) + : @\exposid{c}@(), @\exposid{compare}@(comp) { insert(first, last); } template flat_multiset(InputIterator first, InputIterator last, @@ -16973,7 +16973,7 @@ template flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, const key_compare& comp = key_compare()) - : c(first, last), compare(comp) { } + : @\exposid{c}@(first, last), @\exposid{compare}@(comp) { } template flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, const key_compare& comp, const Allocator& a); From 96fce7b5259e1bfe1688cc60df2d6b2ecf3e7cd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Mon, 22 Aug 2022 11:49:41 +0100 Subject: [PATCH 328/430] [flat.*.{syn,erasure}] Change return type of erase_if to member size_type All other containers and container adapters use the member size_type, and the flat maps already did so in the item specification, but not in the synopsis. The current wording follows the approved proposals, but this change seems like an improvement. Suggested by CD review feedback. --- source/containers.tex | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index d6ba5b0b0c..015cf1c9d7 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -13244,7 +13244,8 @@ // \ref{flat.map.erasure}, erasure for \tcode{flat_map} template - size_t erase_if(flat_map& c, Predicate pred); + typename flat_map::size_type + erase_if(flat_map& c, Predicate pred); // \ref{flat.multimap}, class template \tcode{flat_multimap} template, @@ -13262,8 +13263,8 @@ // \ref{flat.multimap.erasure}, erasure for \tcode{flat_multimap} template - size_t erase_if(flat_multimap& c, - Predicate pred); + typename flat_multimap::size_type + erase_if(flat_multimap& c, Predicate pred); } \end{codeblock} @@ -13286,7 +13287,8 @@ // \ref{flat.set.erasure}, erasure for \tcode{flat_set} template - size_t erase_if(flat_set& c, Predicate pred); + typename flat_set::size_type + erase_if(flat_set& c, Predicate pred); // \ref{flat.multiset}, class template \tcode{flat_multiset} template, class KeyContainer = vector> @@ -13298,9 +13300,10 @@ template struct uses_allocator, Allocator>; - // \ref{flat.set.erasure}, erasure for \tcode{flat_multiset} + // \ref{flat.multiset.erasure}, erasure for \tcode{flat_multiset} template - size_t erase_if(flat_multiset& c, Predicate pred); + typename flat_multiset::size_type + erase_if(flat_multiset& c, Predicate pred); } \end{codeblock} @@ -16808,7 +16811,8 @@ \indexlibrarymember{erase_if}{flat_set}% \begin{itemdecl} template - size_t erase_if(flat_set& c, Predicate pred); + typename flat_set::size_type + erase_if(flat_set& c, Predicate pred); \end{itemdecl} \begin{itemdescr} @@ -17362,7 +17366,8 @@ \indexlibrarymember{erase_if}{flat_multiset}% \begin{itemdecl} template - size_t erase_if(flat_multiset& c, Predicate pred); + typename flat_multiset::size_type + erase_if(flat_multiset& c, Predicate pred); \end{itemdecl} \begin{itemdescr} From 7f11031bf6e41515a8779bdbfe741f4f9bbdfccc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Sat, 20 Aug 2022 21:14:55 +0100 Subject: [PATCH 329/430] [diff] Uniform style for examples For C++ differences, examples are always preceded by the phrase "For example:", do not use the usual [Example n: ... -- end example] style, and always appear in the "Effects on original feature" paragraph. For differences with C, a different set of styles is used (examples being part of paragraphs such as "Change" and "Rationale"), and that subclause remains unchanged by this commit. --- source/compatibility.tex | 123 +++++++++++++++++++++------------------ 1 file changed, 65 insertions(+), 58 deletions(-) diff --git a/source/compatibility.tex b/source/compatibility.tex index 7c581bf5d4..ae154dead4 100644 --- a/source/compatibility.tex +++ b/source/compatibility.tex @@ -34,11 +34,10 @@ Concatenation of \grammarterm{string-literal}s with different \grammarterm{encoding-prefix}es is now ill-formed. -\begin{example} +For example: \begin{codeblock} auto c = L"a" U"b"; // was conditionally-supported; now ill-formed \end{codeblock} -\end{example} \rSec2[diff.cpp20.dcl]{\ref{dcl.dcl}: declarations} @@ -53,8 +52,7 @@ may now be initialized with a UTF-8 string literal. This can affect initialization that includes arrays that are directly initialized within class types, typically aggregates. - -Example: +For example: \begin{codeblock} struct A { char8_t s[10]; @@ -80,7 +78,8 @@ Simplify the rules for implicit move. \effect Valid \CppXX{} code that relies on a returned \grammarterm{id-expression}'s -being an lvalue may change behavior or fail to compile. For example: +being an lvalue may change behavior or fail to compile. +For example: \begin{codeblock} decltype(auto) f(int&& x) { return (x); } // returns \tcode{int\&\&}; previously returned \tcode{int\&} int& g(int&& x) { return x; } // ill-formed; previously well-formed @@ -93,7 +92,8 @@ Enable repurposing a deprecated syntax to support multidimensional indexing. \effect Valid \CppXX{} code that uses a comma expression within a -subscript expression may fail to compile. For example: +subscript expression may fail to compile. +For example: \begin{codeblock} arr[1, 2] // was equivalent to \tcode{arr[(1, 2)]}, // now equivalent to \tcode{arr.operator[](1, 2)} or ill-formed @@ -108,6 +108,7 @@ Facilitate generic handling of throwing and non-throwing functions. \effect Valid ISO \CppXX{} code may be ill-formed in this revision of \Cpp{}. +For example: \begin{codeblock} template struct A { }; template void f(void (*)(A) noexcept(B)); @@ -145,7 +146,8 @@ \effect Valid \CppXX{} code relying on subsumption with \tcode{common_reference_with} -may fail to compile in this revision of \Cpp{}. For example: +may fail to compile in this revision of \Cpp{}. +For example: \begin{codeblock} template requires @\libconcept{equality_comparable_with}@ @@ -191,7 +193,8 @@ that are not copyable. \effect Valid \CppXX{} code that passes bit fields to formatting functions -may become ill-formed. For example: +may become ill-formed. +For example: \begin{codeblock} struct tiny { int bit: 1; @@ -215,6 +218,7 @@ on an xvalue expression with type \tcode{S} that is a specialization of \tcode{basic_string} may change meaning in this revision of \Cpp{}. +For example: \begin{codeblock} std::string s1 = "some long string that forces allocation", s2 = s1; std::move(s1).substr(10, 5); @@ -268,7 +272,7 @@ \tcode{module} or \tcode{import} may be interpreted differently in this revision of \Cpp{}. -\begin{example} +For example: \begin{codeblock} class module {}; module m1; // was variable declaration; now \grammarterm{module-declaration} @@ -278,7 +282,6 @@ import j1; // was variable declaration; now \grammarterm{module-import-declaration} ::import j2; // variable declaration \end{codeblock} -\end{example} \diffref{lex.header} \change @@ -289,13 +292,12 @@ When the identifier \tcode{import} is followed by a \tcode{<} character, a \grammarterm{header-name} token may be formed. -\begin{example} +For example: \begin{codeblock} template class import {}; import f(); // ill-formed; previously well-formed ::import g(); // OK \end{codeblock} -\end{example} \diffref{lex.key} \change @@ -342,7 +344,8 @@ \effect Valid \CppXVII{} code that contains a \tcode{<=} token immediately followed by a \tcode{>} token -may be ill-formed or have different semantics in this revision of \Cpp{}: +may be ill-formed or have different semantics in this revision of \Cpp{}. +For example: \begin{codeblock} namespace N { struct X {}; @@ -365,6 +368,7 @@ UTF-8 string literals having type ``array of \tcode{const char}'' and UTF-8 character literals having type ``\tcode{char}'' is not valid in this revision of \Cpp{}. +For example: \begin{codeblock} const auto *u8s = u8"text"; // \tcode{u8s} previously deduced as \tcode{const char*}; now deduced as \tcode{const char8_t*} const char *ps = u8s; // ill-formed; previously well-formed @@ -395,7 +399,7 @@ \effect Valid ISO \CppXVII{} code may be ill-formed or have undefined behavior in this revision of \Cpp{}. -\begin{example} +For example: \begin{codeblock} int f() { int a = 123; @@ -404,7 +408,6 @@ return a; // undefined behavior; previously returned 123 } \end{codeblock} -\end{example} \diffref{intro.races} \change @@ -443,6 +446,7 @@ Necessary for implementability. \effect Valid \CppXVII{} code may be ill-formed in this revision of \Cpp{}. +For example: \begin{codeblock} typedef struct { void f() {} // ill-formed; previously well-formed @@ -458,6 +462,7 @@ \effect Valid \CppXVII{} code may be ill-formed in this revision of \Cpp{}, with no diagnostic required. +For example: \begin{codeblock} // Translation unit 1 int f(int a = 42); @@ -480,6 +485,7 @@ a type with a user-declared constructor may be ill-formed or have different semantics in this revision of \Cpp{}. +For example: \begin{codeblock} struct A { // not an aggregate; previously an aggregate A() = delete; @@ -521,7 +527,8 @@ Catches bugs. \effect Valid \CppXVII{} code may fail to compile -in this revision of \Cpp{}. For example: +in this revision of \Cpp{}. +For example: \begin{codeblock} bool y[] = { "bc" }; // ill-formed; previously well-formed \end{codeblock} @@ -540,7 +547,8 @@ Necessary for new functionality. \effect Valid \CppXVII{} code may fail to compile -in this revision of \Cpp{}. For example: +in this revision of \Cpp{}. +For example: \begin{codeblock} struct S { explicit (S)(const S&); // ill-formed; previously well-formed @@ -557,7 +565,8 @@ Remove potentially error-prone option for redundancy. \effect Valid \CppXVII{} code may fail to compile -in this revision of \Cpp{}. For example: +in this revision of \Cpp{}. +For example: \begin{codeblock} template struct A { @@ -627,6 +636,7 @@ could invoke a different operator. Equality and inequality expressions between two objects of the same type could become ambiguous. +For example: \begin{codeblock} struct A { operator int() const; @@ -663,6 +673,7 @@ Previously valid code that uses a function name as the left operand of a \tcode{<} operator would become ill-formed. +For example: \begin{codeblock} struct A {}; bool operator<(void (*fp)(), A); @@ -801,7 +812,8 @@ \rationale Increase safety via preventing buffer overflow at compile time. \effect -Valid \CppXVII{} code may fail to compile in this revision of \Cpp{}: +Valid \CppXVII{} code may fail to compile in this revision of \Cpp{}. +For example: \begin{codeblock} auto p = new char[100]; char q[100]; @@ -819,6 +831,7 @@ Valid \CppXVII{} code that passes UTF-8 literals to \tcode{basic_ostream::operator<<} or \tcode{basic_ostream::operator<<} is now ill-formed. +For example: \begin{codeblock} std::cout << u8"text"; // previously called \tcode{operator<<(const char*)} and printed a string; // now ill-formed @@ -838,6 +851,7 @@ to \tcode{basic_ostream::operator<<} or that passes \keyword{char16_t} or \keyword{char32_t} characters or strings to \tcode{basic_ostream::operator<<} is now ill-formed. +For example: \begin{codeblock} std::cout << u"text"; // previously formatted the string as a pointer value; // now ill-formed @@ -854,6 +868,7 @@ Valid \CppXVII{} code that depends on the \tcode{u8string()} and \tcode{generic_u8string()} member functions of \tcode{std::filesystem::path} returning \tcode{std::string} is not valid in this revision of \Cpp{}. +For example: \begin{codeblock} std::filesystem::path p; std::string s1 = p.u8string(); // ill-formed; previously well-formed @@ -1042,7 +1057,8 @@ More intuitive deduction behavior. \effect Valid \CppXIV{} code may fail to compile or may change meaning -in this revision of \Cpp{}. For example: +in this revision of \Cpp{}. +For example: \begin{codeblock} auto x1{1}; // was \tcode{std::initializer_list}, now \tcode{int} auto x2{1, 2}; // was \tcode{std::initializer_list}, now ill-formed @@ -1102,6 +1118,7 @@ that names a constructor now makes the corresponding base class constructors visible to initializations of the derived class rather than declaring additional derived class constructors. +For example: \begin{codeblock} struct A { template A(T, typename T::type = 0); @@ -1240,7 +1257,7 @@ will execute differently when called with a non-const string's \tcode{.data()} member in this revision of \Cpp{}. - +For example: \begin{codeblock} int f(char *) = delete; int f(const char *); @@ -1258,7 +1275,8 @@ \effect Valid \CppXIV{} code that attempts to use associative containers having a comparison object with non-const function call operator -may fail to compile in this revision of \Cpp{}: +may fail to compile in this revision of \Cpp{}. +For example: \begin{codeblock} #include @@ -1332,8 +1350,8 @@ revision of \Cpp{}. For example, the following code is valid both in \CppXI{} and in this revision of \Cpp{}, but the macro invocation produces different outcomes because the single quotes delimit a \grammarterm{character-literal} in \CppXI{}, whereas they are digit -separators in this revision of \Cpp{}: - +separators in this revision of \Cpp{}. +For example: \begin{codeblock} #define M(x, ...) __VA_ARGS__ int x[2] = { M(1'2,3'4, 5) }; @@ -1355,7 +1373,6 @@ void* operator new(std::size_t, std::size_t); void operator delete(void*, std::size_t) noexcept; \end{codeblock} - In this revision of \Cpp{}, however, the declaration of \tcode{operator delete} might match a predefined usual (non-placement) \tcode{operator delete}\iref{basic.stc.dynamic}. If so, the @@ -1375,8 +1392,8 @@ lvalue-to-rvalue conversion, were considered gratuitous and surprising. \effect Valid \CppXI{} code that relies on the conversions may behave differently -in this revision of \Cpp{}: - +in this revision of \Cpp{}. +For example: \begin{codeblock} struct S { int x = 1; @@ -1388,14 +1405,11 @@ return s.x; } \end{codeblock} - In \CppXI{}, \tcode{f(true)} returns \tcode{1}. In this revision of \Cpp{}, it returns \tcode{2}. - \begin{codeblock} sizeof(true ? "" : throw 0) \end{codeblock} - In \CppXI{}, the expression yields \tcode{sizeof(const char*)}. In this revision of \Cpp{}, it yields \tcode{sizeof(const char[1])}. @@ -1410,15 +1424,16 @@ the object. \effect Valid \CppXI{} code may fail to compile in this revision of \Cpp{}. -For example, the following code is valid in \CppXI{} -but invalid in this revision of \Cpp{} because it declares the same member -function twice with different return types: +For example: \begin{codeblock} struct S { constexpr const int &f(); int &f(); }; \end{codeblock} +This code is valid in \CppXI{} +but invalid in this revision of \Cpp{} because it declares the same member +function twice with different return types. \diffref{dcl.init.aggr} \change @@ -1488,7 +1503,8 @@ this revision of \Cpp{}. Specifically, macros named \tcode{R}, \tcode{u8}, \tcode{u8R}, \tcode{u}, \tcode{uR}, \tcode{U}, \tcode{UR}, or \tcode{LR} will not be expanded when adjacent to a \grammarterm{string-literal} but will be interpreted as -part of the \grammarterm{string-literal}. For example: +part of the \grammarterm{string-literal}. +For example: \begin{codeblock} #define u8 "abc" const char* s = u8"def"; // Previously \tcode{"abcdef"}, now \tcode{"def"} @@ -1607,13 +1623,14 @@ \rationale Catches bugs. \effect -Valid \CppIII{} code may fail to compile in this revision of \Cpp{}. For -example, the following code is valid in \CppIII{} but invalid in this -revision of \Cpp{} because \tcode{double} to \tcode{int} is a narrowing -conversion: +Valid \CppIII{} code may fail to compile in this revision of \Cpp{}. +For example: \begin{codeblock} int x[] = { 2.0 }; \end{codeblock} +This code is valid in \CppIII{} but invalid in this +revision of \Cpp{} because \tcode{double} to \tcode{int} is a narrowing +conversion. \rSec2[diff.cpp03.class]{\ref{class}: classes} @@ -1661,15 +1678,15 @@ Change to semantics of well-defined expression. A valid \CppIII{} expression containing a right angle bracket (``\tcode{>}'') followed immediately by another right angle bracket may now be treated as closing two templates. -For example, the following code is valid in \CppIII{} because ``\tcode{>>}'' -is a right-shift operator, but invalid in this revision of \Cpp{} because -``\tcode{>>}'' closes two templates. - +For example: \begin{codeblock} template struct X { }; template struct Y { }; X< Y< 1 >> 2 > > x; \end{codeblock} +This code is valid in \CppIII{} because ``\tcode{>>}'' +is a right-shift operator, but invalid in this revision of \Cpp{} because +``\tcode{>>}'' closes two templates. \diffref{temp.dep.candidate} \change @@ -1996,7 +2013,8 @@ \effect Valid \CppIII{} code that relies on \tcode{std::ios_base} flag types being represented as \tcode{std::bitset} or as an integer type may fail to compile -with this revision of \Cpp{}. For example: +with this revision of \Cpp{}. +For example: \begin{codeblock} #include @@ -2043,26 +2061,21 @@ Type of \grammarterm{character-literal} is changed from \tcode{int} to \tcode{char}. \rationale This is needed for improved overloaded function argument type -matching. -For example: - +matching. For example: \begin{codeblock} int function( int i ); int function( char c ); function( 'x' ); \end{codeblock} - It is preferable that this call match the second version of function rather than the first. \effect Change to semantics of well-defined feature. ISO C programs which depend on - \begin{codeblock} sizeof('x') == sizeof(int) \end{codeblock} - will not work the same as \Cpp{} programs. \difficulty Simple. @@ -2112,7 +2125,6 @@ Change to semantics of well-defined feature. \difficulty Syntactic transformation. The fix is to add a cast: - \begin{codeblock} char* p = "abc"; // valid in C, invalid in \Cpp{} void f(char*) { @@ -2121,7 +2133,6 @@ f((char*)"def"); // OK, cast added } \end{codeblock} - \howwide Programs that have a legitimate reason to treat string literal objects as potentially modifiable memory are probably rare. @@ -2148,7 +2159,6 @@ static struct X b = { 0, &a }; static struct X a = { 1, &b }; \end{codeblock} - \rationale This avoids having different initialization rules for fundamental types and user-defined types. @@ -2243,7 +2253,6 @@ \diffref{conv.ptr} \change Converting \tcode{\keyword{void}*} to a pointer-to-object type requires casting. - \begin{codeblock} char a[10]; void* b=a; @@ -2318,13 +2327,12 @@ \effect Change to semantics of well-defined feature. Some C expressions that implicitly rely on lvalue-to-rvalue -conversions will yield different results. For example, - +conversions will yield different results. +For example, \begin{codeblock} char arr[100]; sizeof(0, arr) \end{codeblock} - yields \tcode{100} in \Cpp{} and @@ -2474,6 +2482,7 @@ \change The keyword \keyword{auto} cannot be used as a storage class specifier. +Example: \begin{codeblock} void f() { auto int x; // valid C, invalid \Cpp{} @@ -2497,7 +2506,6 @@ In C, an empty parameter list means that the number and type of the function arguments are unknown. Example: - \begin{codeblock} int f(); // means \tcode{int f(void)} in \Cpp{} // \tcode{int f(} unknown \tcode{)} in C @@ -2525,7 +2533,6 @@ In C, these type definitions are allowed. Example: - \begin{codeblock} void f( struct S { int a; } arg ) {} // valid C, invalid \Cpp{} enum E { A, B, C } f() {} // valid C, invalid \Cpp{} From d4280f38ddd489aecd8fb0da17a41f577db42e2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Sat, 20 Aug 2022 23:11:39 +0100 Subject: [PATCH 330/430] [memory.syn] Add missing "// freestanding" comment to "destroy" The comment was supposed to be added by P1642R11, but was accidentally omitted. --- source/memory.tex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/memory.tex b/source/memory.tex index 99d0514825..76a4c7ffa1 100644 --- a/source/memory.tex +++ b/source/memory.tex @@ -363,7 +363,8 @@ template constexpr void destroy_at(T* location); // freestanding template - constexpr void destroy(NoThrowForwardIterator first, NoThrowForwardIterator last); + constexpr void destroy(NoThrowForwardIterator first, // freestanding + NoThrowForwardIterator last); template void destroy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} NoThrowForwardIterator first, NoThrowForwardIterator last); From 47b0e73cc1e8d2ea344afedf60e07ec80df118f4 Mon Sep 17 00:00:00 2001 From: mordante Date: Mon, 22 Aug 2022 17:48:36 +0200 Subject: [PATCH 331/430] [format.string.std] Reorder std-format-spec field descriptions. (#5246) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Moves the wording describing the zero-padding before the description of the width; matching the order of the fields in the std-format-spec. The original order was introduced in the initial paper P0645R10 "Text Formatting". Since both fields had one paragraph of description, it wasn't too noticeable. P1868R2 "🦄 width: clarifying units of width and precision in std::format" expanded the wording of the width. Now it's not so easy to find the description of the zero-padding field. --- source/utilities.tex | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/source/utilities.tex b/source/utilities.tex index ba9975a15a..15ae98729a 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -14265,6 +14265,26 @@ % alter its behavior? trailing zeros are not removed from the result. +\pnum +A zero (\tcode{0}) character +preceding the \fmtgrammarterm{width} field +pads the field with leading zeros (following any indication of sign or base) +to the field width, +except when applied to an infinity or NaN. +This option is only valid for +arithmetic types other than \tcode{charT} and \tcode{bool} +or when an integer presentation type is specified. +If the \tcode{0} character and an \fmtgrammarterm{align} option both appear, +the \tcode{0} character is ignored. +\begin{example} +\begin{codeblock} +char c = 120; +string s1 = format("{:+06d}", c); // value of \tcode{s1} is \tcode{"+00120"} +string s2 = format("{:#06x}", 0xa); // value of \tcode{s2} is \tcode{"0x000a"} +string s3 = format("{:<06}", -42); // value of \tcode{s3} is \tcode{"-42\ \ \ "} (\tcode{0} is ignored because of \tcode{<} alignment) +\end{codeblock} +\end{example} + \pnum If \tcode{\{ \opt{\fmtgrammarterm{arg-id}} \}} is used in a \fmtgrammarterm{width} or \fmtgrammarterm{precision}, @@ -14336,26 +14356,6 @@ \pnum For a string in a non-Unicode encoding, the width of a string is unspecified. -\pnum -A zero (\tcode{0}) character -preceding the \fmtgrammarterm{width} field -pads the field with leading zeros (following any indication of sign or base) -to the field width, -except when applied to an infinity or NaN. -This option is only valid for -arithmetic types other than \tcode{charT} and \tcode{bool} -or when an integer presentation type is specified. -If the \tcode{0} character and an \fmtgrammarterm{align} option both appear, -the \tcode{0} character is ignored. -\begin{example} -\begin{codeblock} -char c = 120; -string s1 = format("{:+06d}", c); // value of \tcode{s1} is \tcode{"+00120"} -string s2 = format("{:#06x}", 0xa); // value of \tcode{s2} is \tcode{"0x000a"} -string s3 = format("{:<06}", -42); // value of \tcode{s3} is \tcode{"-42\ \ \ "} (\tcode{0} is ignored because of \tcode{<} alignment) -\end{codeblock} -\end{example} - \pnum % FIXME: What if it's an arg-id? The \fmtgrammarterm{nonnegative-integer} in From 517290b26fa8391d3b77d43ca8c271bb92695db7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Mon, 22 Aug 2022 17:06:34 +0100 Subject: [PATCH 332/430] [range.cartesian.view] Further fixing of cartesian-product-is-common The first fix in 8275c19b3fa9e7cb09f84049ebd6207aceb7ca80 was incorrect. Only Const needs to be dropped (which was an error in the paper), but ignoring Vs... is intentional. --- source/ranges.tex | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index 93b4a95bd6..747d2f7666 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -14288,8 +14288,7 @@ template concept @\defexposconcept{cartesian-product-is-common}@ = // \expos - (@\exposconcept{cartesian-product-common-arg}@ && ... && - @\exposconcept{cartesian-product-common-arg}@); + @\exposconcept{cartesian-product-common-arg}@; template concept @\defexposconcept{cartesian-product-is-sized}@ = // \expos From 101e7205882495cec1a944c7f6190b08bd131543 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Mon, 22 Aug 2022 17:23:46 +0100 Subject: [PATCH 333/430] [ranges] Add missing closing delimiters --- source/ranges.tex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index 747d2f7666..2c3fbe82aa 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -4278,6 +4278,7 @@ (invoke(f, std::forward(elements)), ...); }, std::forward(t)); } +} \end{codeblock} \rSec2[range.all]{All view} @@ -14953,7 +14954,7 @@ the logical AND of the following expressions: \begin{itemize} \item -\tcode{noexcept(ranges::iter_move(std::get<$N$>(i.\exposid{current_}))} +\tcode{noexcept(ranges::iter_move(std::get<$N$>(i.\exposid{current_})))} for every integer\newline $0 \le N \le \tcode{sizeof...(Vs)}$, \item \tcode{is_nothrow_move_constructible_v>>}\newline From cf2b0a7b3e8bfca45af0dff2104e4ba2dadfa7d3 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sat, 18 Jun 2022 21:31:07 +0200 Subject: [PATCH 334/430] [alg.move] Add missing \tcode formatting --- source/algorithms.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/algorithms.tex b/source/algorithms.tex index 2dfe75b014..51bd3e7bcc 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -5174,7 +5174,7 @@ into the range \range{result - $N$}{result} starting from \tcode{last - 1} and proceeding to \tcode{first}. \begin{footnote} -\tcode{move_backward} can be used instead of move +\tcode{move_backward} can be used instead of \tcode{move} when \tcode{last} is in the range \range{result - $N$}{result}. \end{footnote} For each positive integer $n \le N$, From c2419bb83d476875ea62b4ff63b721b8458415b6 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sat, 18 Jun 2022 21:35:35 +0200 Subject: [PATCH 335/430] [alg.fill] Remove extraneous empty line --- source/algorithms.tex | 1 - 1 file changed, 1 deletion(-) diff --git a/source/algorithms.tex b/source/algorithms.tex index 51bd3e7bcc..a3782a56be 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -5613,7 +5613,6 @@ ForwardIterator fill_n(ExecutionPolicy&& exec, ForwardIterator first, Size n, const T& value); - template O, @\libconcept{sentinel_for}@ S> constexpr O ranges::fill(O first, S last, const T& value); template R> From 17be256d2431f66842479bf7ab2e92f30fff3060 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sat, 18 Jun 2022 21:39:06 +0200 Subject: [PATCH 336/430] [alg.partitions] Indicate base of logarithm outside big-oh notation --- source/algorithms.tex | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/algorithms.tex b/source/algorithms.tex index a3782a56be..8ce4ead3fa 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -7560,13 +7560,12 @@ \item \tcode{\{i, last\}} for the overloads in namespace \tcode{ranges}. \end{itemize} - \pnum \complexity Let $N$ = \tcode{last - first}: \begin{itemize} \item - For the overloads with no \tcode{ExecutionPolicy}, at most $N \log N$ swaps, + For the overloads with no \tcode{ExecutionPolicy}, at most $N \log_2 N$ swaps, but only \bigoh{N} swaps if there is enough extra memory. Exactly $N$ applications of the predicate and projection. \item From c6e83c4dba380b235be59b21db6c54bdffcb997d Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sat, 18 Jun 2022 21:39:59 +0200 Subject: [PATCH 337/430] [set.difference] Fix grammar typo --- source/algorithms.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/algorithms.tex b/source/algorithms.tex index 8ce4ead3fa..a3d79b4766 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -8230,7 +8230,7 @@ \range{first2}{last2} contains $n$ elements that are equivalent to them, the last $\max(m - n, 0)$ elements from \range{first1}{last1} -is copied to the output range, in order. +are copied to the output range, in order. \end{itemdescr} \rSec3[set.symmetric.difference]{\tcode{set_symmetric_difference}} From 68e365415c707038f8af6c76f0f6f4cd3a4ce407 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sat, 18 Jun 2022 21:44:05 +0200 Subject: [PATCH 338/430] [uninitialized.move] Fix typos in parameter names --- source/algorithms.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/algorithms.tex b/source/algorithms.tex index a3d79b4766..39d344bdf2 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -11190,7 +11190,7 @@ \pnum \begin{note} -If an exception is thrown, some objects in the range \range{first}{last} are +If an exception is thrown, some objects in the range \range{ifirst}{ilast} are left in a valid, but unspecified state. \end{note} \end{itemdescr} @@ -11245,7 +11245,7 @@ \pnum \begin{note} If an exception is thrown, some objects in the range -\countedrange{first}{n} +\countedrange{ifirst}{n} are left in a valid but unspecified state. \end{note} \end{itemdescr} From c3c6761111cff26e0e742e4d14b5d9e0bd28c4aa Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sat, 18 Jun 2022 22:53:51 +0200 Subject: [PATCH 339/430] [rand.adapt.disc] Remove superfluous trailing semicolon --- source/numerics.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/numerics.tex b/source/numerics.tex index f4ac882ab8..a5be16a0a3 100644 --- a/source/numerics.tex +++ b/source/numerics.tex @@ -3241,7 +3241,7 @@ void discard(unsigned long long z); // property functions - const Engine& base() const noexcept { return e; }; + const Engine& base() const noexcept { return e; } // inserters and extractors template From 65c9e5bcb3068a1172a66a7507d26a93adae7981 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sat, 18 Jun 2022 22:55:17 +0200 Subject: [PATCH 340/430] [rand.adapt.ibits] Remove superfluous trailing semicolon --- source/numerics.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/numerics.tex b/source/numerics.tex index a5be16a0a3..6928778626 100644 --- a/source/numerics.tex +++ b/source/numerics.tex @@ -3343,7 +3343,7 @@ void discard(unsigned long long z); // property functions - const Engine& base() const noexcept { return e; }; + const Engine& base() const noexcept { return e; } // inserters and extractors template From 6ede23707505a18cdbb558108d635a0b21a1eeb0 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sat, 18 Jun 2022 22:55:47 +0200 Subject: [PATCH 341/430] [rand.adapt.shuf] Remove superfluous trailing semicolon --- source/numerics.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/numerics.tex b/source/numerics.tex index 6928778626..e84c99b852 100644 --- a/source/numerics.tex +++ b/source/numerics.tex @@ -3093,7 +3093,7 @@ void discard(unsigned long long z); // property functions - const Engine& base() const noexcept { return e; }; + const Engine& base() const noexcept { return e; } // inserters and extractors template @@ -3132,7 +3132,7 @@ sets \tcode{n} to $0$. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% independent_bits_engine engine adaptor: +% independent_bits_engine engine adaptor:\exposid{ \rSec3[rand.adapt.ibits]{Class template \tcode{independent_bits_engine}}% \indexlibraryglobal{independent_bits_engine}% From 5e44bc70b72b64e03e0d09564b2eaf45938a7752 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sat, 18 Jun 2022 22:58:11 +0200 Subject: [PATCH 342/430] [valarray.members] Fix bad reference to argument --- source/numerics.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/numerics.tex b/source/numerics.tex index e84c99b852..7c848a2faf 100644 --- a/source/numerics.tex +++ b/source/numerics.tex @@ -7554,7 +7554,7 @@ \begin{example} If the argument has the value $-2$, the first two elements of the result will be value-initialized\iref{dcl.init}; the third element of the result will be assigned the value -of the first element of the argument; etc. +of the first element of \tcode{*this}; etc. \end{example} \end{itemdescr} From 43b2bce231b04c1ccf7dc4bfd20e13f29c0e9c6c Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sun, 19 Jun 2022 21:29:54 +0200 Subject: [PATCH 343/430] [time.duration.io] Fix grammar typo --- source/time.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/time.tex b/source/time.tex index a59096095d..d9460d6c88 100644 --- a/source/time.tex +++ b/source/time.tex @@ -2145,7 +2145,7 @@ In the list above, the use of \tcode{\placeholder{num}} and \tcode{\placeholder{den}} -refer to the static data members of \tcode{Period::type}, +refers to the static data members of \tcode{Period::type}, which are converted to arrays of \tcode{charT} using a decimal conversion with no leading zeroes. \pnum From 6e9b678f03a1a4fa8218152596a1952c209d1f27 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sun, 19 Jun 2022 21:32:40 +0200 Subject: [PATCH 344/430] [time.cal.year.members] Fix erroneous qualified-id --- source/time.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/time.tex b/source/time.tex index d9460d6c88..2263d4b7cc 100644 --- a/source/time.tex +++ b/source/time.tex @@ -4681,7 +4681,7 @@ \indexlibrarymember{operator-}{year}% \begin{itemdecl} -constexpr year year::operator-() const noexcept; +constexpr year operator-() const noexcept; \end{itemdecl} \begin{itemdescr} From f0ab64a1dcb5bac1249ff67e838a7f899efeb586 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sun, 19 Jun 2022 21:39:48 +0200 Subject: [PATCH 345/430] [locale.codecvt.general] Remove extra space before template-argument-list --- source/locales.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/locales.tex b/source/locales.tex index e0533f7d71..e6b0ebd7ce 100644 --- a/source/locales.tex +++ b/source/locales.tex @@ -1655,7 +1655,7 @@ \indextext{UTF-32}% The specialization \tcode{codecvt} converts between the UTF-16 and UTF-8 encoding forms, and -the specialization \tcode{codecvt} \tcode{} +the specialization \tcode{codecvt} converts between the UTF-32 and UTF-8 encoding forms. \tcode{codecvt} converts between the native character sets for ordinary and wide characters. From bbb7552af35266accf98ae718912579527ee11b8 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sun, 19 Jun 2022 21:41:58 +0200 Subject: [PATCH 346/430] [locale.collate.general] Fix grammar typo --- source/locales.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/locales.tex b/source/locales.tex index e6b0ebd7ce..788abc1be0 100644 --- a/source/locales.tex +++ b/source/locales.tex @@ -3014,7 +3014,7 @@ The specializations required in \tref{locale.category.facets}\iref{locale.category}, namely \tcode{collate} and \tcode{collate}, -apply lexicographic ordering\iref{alg.lex.comparison}. +apply lexicographical ordering\iref{alg.lex.comparison}. \pnum Each function compares a string of characters \tcode{*p} From 324dfd448ec5b632fc922015414cd206920b5842 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sun, 19 Jun 2022 21:45:29 +0200 Subject: [PATCH 347/430] [ios.base.storage] Fix grammar typo --- source/iostreams.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/iostreams.tex b/source/iostreams.tex index 6bb8483ad9..1f38e71485 100644 --- a/source/iostreams.tex +++ b/source/iostreams.tex @@ -1458,7 +1458,7 @@ \tcode{iarray} as necessary to include the element \tcode{iarray[idx]}. Each newly allocated element of the array is initialized to zero. -The reference returned is invalid after any other operations on the +The reference returned is invalid after any other operation on the object. \begin{footnote} An implementation is free to implement both the integer @@ -1515,7 +1515,7 @@ \tcode{parray[idx]}. Each newly allocated element of the array is initialized to a null pointer. -The reference returned is invalid after any other operations on the +The reference returned is invalid after any other operation on the object. However, the value of the storage referred to is retained, so that until the next call to From fc53c9ede41d4992dc64f556bc32febb28ad0e1e Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sun, 19 Jun 2022 21:45:58 +0200 Subject: [PATCH 348/430] [fpos] Fix typo in exposition-only member --- source/iostreams.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/iostreams.tex b/source/iostreams.tex index 1f38e71485..29c271b9e2 100644 --- a/source/iostreams.tex +++ b/source/iostreams.tex @@ -1636,7 +1636,7 @@ // \ref{fpos.members}, members stateT state() const; void state(stateT); - private; + private: stateT st; // \expos }; } From 47273ceb655716f62fc1c9fe00a317b44c221267 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sun, 19 Jun 2022 21:47:05 +0200 Subject: [PATCH 349/430] [fpos.operations] Fix name of type trait --- source/iostreams.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/iostreams.tex b/source/iostreams.tex index 29c271b9e2..5acd80d41a 100644 --- a/source/iostreams.tex +++ b/source/iostreams.tex @@ -1681,7 +1681,7 @@ \oldconcept{Destructible} (\tref{cpp17.destructible}) requirements. If \tcode{is_trivially_copy_constructible_v} is \tcode{true}, then \tcode{fpos} has a trivial copy constructor. -If \tcode{is_trivially_copy_assignable} is \tcode{true}, +If \tcode{is_trivially_copy_assignable_v} is \tcode{true}, then \tcode{fpos} has a trivial copy assignment operator. If \tcode{is_trivially_destructible_v} is \tcode{true}, then \tcode{fpos} has a trivial destructor. From 04d7e61e9deaf2481d144e2c0a7d2478cff58764 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sun, 19 Jun 2022 21:49:00 +0200 Subject: [PATCH 350/430] [streambuf.cons] Fix grammar typo --- source/iostreams.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/iostreams.tex b/source/iostreams.tex index 5acd80d41a..7c31b348b3 100644 --- a/source/iostreams.tex +++ b/source/iostreams.tex @@ -3108,7 +3108,7 @@ \item the \tcode{getloc()} -member to a copy the global locale, +member to a copy of the global locale, \tcode{locale()}, at the time of construction. \end{itemize} From d2fe1a92b02b676f06e07d8b1bd670169f30645d Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Tue, 23 Aug 2022 03:52:57 +0800 Subject: [PATCH 351/430] [ranges.elementsof] Add missing indexing, fix spacing (#5774) --- source/ranges.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index 2c3fbe82aa..db6852288a 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -2198,8 +2198,8 @@ \begin{example} \begin{codeblock} -template -std::generator f(std::ranges::input_range auto&& r) { +template +std::generator f(std::ranges::@\libconcept{input_range}@ auto&& r) { if constexpr (YieldElements) co_yield std::ranges::elements_of(r); // yield each element of \tcode{r} else From f055ba09397bd479317a92c315e5a074f7c2e474 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sun, 17 Apr 2022 11:19:04 +0200 Subject: [PATCH 352/430] [atomics.syn] Move namespace-scope memory_order_* variables here --- source/threads.tex | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/source/threads.tex b/source/threads.tex index 630a2d865b..a383dd8181 100644 --- a/source/threads.tex +++ b/source/threads.tex @@ -2049,6 +2049,13 @@ namespace std { // \ref{atomics.order}, order and consistency enum class memory_order : @\unspec@; // freestanding + inline constexpr memory_order memory_order_relaxed = memory_order::relaxed; + inline constexpr memory_order memory_order_consume = memory_order::consume; + inline constexpr memory_order memory_order_acquire = memory_order::acquire; + inline constexpr memory_order memory_order_release = memory_order::release; + inline constexpr memory_order memory_order_acq_rel = memory_order::acq_rel; + inline constexpr memory_order memory_order_seq_cst = memory_order::seq_cst; + template T kill_dependency(T y) noexcept; // freestanding } @@ -2415,12 +2422,6 @@ enum class memory_order : @\unspec@ { relaxed, consume, acquire, release, acq_rel, seq_cst }; - inline constexpr memory_order memory_order_relaxed = memory_order::relaxed; - inline constexpr memory_order memory_order_consume = memory_order::consume; - inline constexpr memory_order memory_order_acquire = memory_order::acquire; - inline constexpr memory_order memory_order_release = memory_order::release; - inline constexpr memory_order memory_order_acq_rel = memory_order::acq_rel; - inline constexpr memory_order memory_order_seq_cst = memory_order::seq_cst; } \end{codeblock} From f400d80927fd580f99f5f2d94c3d07eaa47373d0 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sun, 17 Apr 2022 11:23:54 +0200 Subject: [PATCH 353/430] [ranges.syn] Move namespace-scope declarations for get(subrange) here --- source/ranges.tex | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index db6852288a..bac1bce583 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -138,6 +138,20 @@ template inline constexpr bool enable_borrowed_range> = true; // freestanding + template + requires ((N == 0 && @\libconcept{copyable}@) || N == 1) + constexpr auto get(const subrange& r); + + template + requires (N < 2) + constexpr auto get(subrange&& r); +} + +namespace std { + using ranges::get; +} + +namespace std::ranges { // \ref{range.dangling}, dangling iterator handling struct dangling; // freestanding @@ -1880,18 +1894,6 @@ template<@\libconcept{borrowed_range}@ R> subrange(R&&, @\placeholdernc{make-unsigned-like-t}@>) -> subrange, sentinel_t, subrange_kind::sized>; - - template - requires ((N == 0 && @\libconcept{copyable}@) || N == 1) - constexpr auto get(const subrange& r); - - template - requires (N < 2) - constexpr auto get(subrange&& r); -} - -namespace std { - using ranges::get; } \end{codeblock} From e9434db227e8b3113a477dcdd0c6c14ffe2c14b8 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Mon, 22 Aug 2022 18:56:41 +0100 Subject: [PATCH 354/430] [tuple.creation] Add missing semi-colon to example --- source/utilities.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/utilities.tex b/source/utilities.tex index 15ae98729a..d6ad0b1ec4 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -2517,7 +2517,7 @@ \begin{example} \begin{codeblock} int i; float j; -make_tuple(1, ref(i), cref(j)) +make_tuple(1, ref(i), cref(j)); \end{codeblock} creates a tuple of type \tcode{tuple}. \end{example} From 25bb0a278e8141613f2c813c50a74428e3da7b8b Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Mon, 22 Aug 2022 18:58:39 +0100 Subject: [PATCH 355/430] [util.smartptr.shared.obs], [util.smartptr.shared.create] use nullptr for null pointer constant --- source/memory.tex | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/memory.tex b/source/memory.tex index 76a4c7ffa1..3fd0b8c0f5 100644 --- a/source/memory.tex +++ b/source/memory.tex @@ -3619,7 +3619,7 @@ \begin{itemdescr} \pnum \expects -\tcode{get() != 0}. +\tcode{get() != nullptr}. \pnum \returns @@ -3642,7 +3642,7 @@ \begin{itemdescr} \pnum \expects -\tcode{get() != 0}. +\tcode{get() != nullptr}. \pnum \returns @@ -3665,7 +3665,7 @@ \begin{itemdescr} \pnum \expects -\tcode{get() != 0 \&\& i >= 0}. +\tcode{get() != nullptr \&\& i >= 0}. If \tcode{T} is \tcode{U[N]}, \tcode{i < N}. \pnum @@ -3731,7 +3731,7 @@ \begin{itemdescr} \pnum \returns -\tcode{get() != 0}. +\tcode{get() != nullptr}. \end{itemdescr} \indexlibrarymember{owner_before}{shared_ptr}% @@ -3797,7 +3797,7 @@ \pnum \ensures -\tcode{r.get() != 0 \&\& r.use_count() == 1}, +\tcode{r.get() != nullptr \&\& r.use_count() == 1}, where \tcode{r} is the return value. \pnum From 7a4324c21e4f66af801bc7e7fc78b94119253301 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Mon, 22 Aug 2022 21:52:22 +0100 Subject: [PATCH 356/430] [char.traits.require] use nullptr for null pointer constant --- source/strings.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/strings.tex b/source/strings.tex index 44b8b76fc3..d9bd3cef43 100644 --- a/source/strings.tex +++ b/source/strings.tex @@ -151,7 +151,7 @@ \tcode{X::find(p,n,c)} & \tcode{const X::char_type*} & \returns the smallest \tcode{q} in \tcode{[p,p+n)} such that -\tcode{X::eq(*q,c)} is \tcode{true}, zero otherwise. & linear \\ \rowsep +\tcode{X::eq(*q,c)} is \tcode{true}, \tcode{nullptr} otherwise. & linear \\ \rowsep \tcode{X::move(s,p,n)} & \tcode{X::char_type*} & for each \tcode{i} in \tcode{[0,n)}, performs \tcode{X::assign(s[i],p[i])}. Copies correctly even where the ranges \tcode{[p,p+n)} and \tcode{[s,s+n)} overlap.\br \returns \tcode{s}. & linear \\ \rowsep From b3b64b35ce456a7e54476b9a00185323b68fcd6d Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Mon, 22 Aug 2022 22:01:22 +0100 Subject: [PATCH 357/430] [unord.req.general] Use "constant" not "const" --- source/containers.tex | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index 015cf1c9d7..ea1aa5075c 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -5357,7 +5357,7 @@ \begin{itemdescr} \pnum \result -\tcode{iterator}; \tcode{const_iterator} for const \tcode{b}. +\tcode{iterator}; \tcode{const_iterator} for constant \tcode{b}. \pnum \returns @@ -5377,7 +5377,7 @@ \begin{itemdescr} \pnum \result -\tcode{iterator}; \tcode{const_iterator} for const \tcode{a_tran}. +\tcode{iterator}; \tcode{const_iterator} for constant \tcode{a_tran}. \pnum \returns @@ -5459,7 +5459,7 @@ \pnum \result \tcode{pair}; -\tcode{pair} for const \tcode{b}. +\tcode{pair} for constant \tcode{b}. \pnum \returns @@ -5480,7 +5480,7 @@ \pnum \result \tcode{pair}; -\tcode{pair} for const \tcode{a_tran}. +\tcode{pair} for constant \tcode{a_tran}. \pnum \returns @@ -5588,7 +5588,7 @@ \begin{itemdescr} \pnum \result -\tcode{local_iterator}; \tcode{const_local_iterator} for const \tcode{b}. +\tcode{local_iterator}; \tcode{const_local_iterator} for constant \tcode{b}. \pnum \expects @@ -5612,7 +5612,7 @@ \begin{itemdescr} \pnum \result -\tcode{local_iterator}; \tcode{const_local_iterator} for const \tcode{b}. +\tcode{local_iterator}; \tcode{const_local_iterator} for constant \tcode{b}. \pnum \expects From c760bb5d9a12690e171f91b8feac0feef4ca1392 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Mon, 22 Aug 2022 22:02:06 +0100 Subject: [PATCH 358/430] [unord.map.overview] Add line breaks in excessively long line --- source/containers.tex | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source/containers.tex b/source/containers.tex index ea1aa5075c..2fcf21ad17 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -11271,7 +11271,12 @@ of a container\iref{container.reqmts}, of an allocator-aware container\iref{container.alloc.reqmts}, and of an unordered associative container\iref{unord.req}. -It provides the operations described in the preceding requirements table for unique keys; that is, an \tcode{unordered_map} supports the \tcode{a_uniq} operations in that table, not the \tcode{a_eq} operations. For an \tcode{unordered_map} the \tcode{key_type} is \tcode{Key}, the \tcode{mapped_type} is \tcode{T}, and the \tcode{value_type} is \tcode{pair}. +It provides the operations described in the preceding requirements table for unique keys; +that is, an \tcode{unordered_map} supports the \tcode{a_uniq} operations in that table, +not the \tcode{a_eq} operations. +For an \tcode{unordered_map} the \tcode{key_type} is \tcode{Key}, +the \tcode{mapped_type} is \tcode{T}, +and the \tcode{value_type} is \tcode{pair}. \pnum Subclause~\ref{unord.map} only describes operations on \tcode{unordered_map} that From a421a3029418651b9734ae786c9b89b72b08b42d Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Mon, 22 Aug 2022 22:09:00 +0100 Subject: [PATCH 359/430] [unord.multimap.overview] Fix presentation of member types As already done in de6b0e70ffe2da0a0f91ce434863202f78c9e029 for unordered_map. --- source/containers.tex | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index 2fcf21ad17..545811a559 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -11916,8 +11916,9 @@ It provides the operations described in the preceding requirements table for equivalent keys; that is, an \tcode{unordered_multimap} supports the \tcode{a_eq} operations in that table, not the \tcode{a_uniq} operations. -For an \tcode{unordered_multimap} the \tcode{key type} is \tcode{Key}, the -mapped type is \tcode{T}, and the value type is \tcode{pair}. +For an \tcode{unordered_multimap} the \tcode{key_type} is \tcode{Key}, +the \tcode{mapped_type} is \tcode{T}, +and the \tcode{value_type} is \tcode{pair}. \pnum Subclause~\ref{unord.multimap} only describes operations on \tcode{unordered_multimap} From 1356fa2324bc8609b5b0c365cbf981c1c56d32e9 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Mon, 22 Aug 2022 22:10:01 +0100 Subject: [PATCH 360/430] [unord.set.overview] Add line breaks in excessively long line --- source/containers.tex | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/source/containers.tex b/source/containers.tex index 545811a559..629e67b3d3 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -12336,7 +12336,13 @@ of a container\iref{container.reqmts}, of an allocator-aware container\iref{container.alloc.reqmts}, of an unordered associative container\iref{unord.req}. -It provides the operations described in the preceding requirements table for unique keys; that is, an \tcode{unordered_set} supports the \tcode{a_uniq} operations in that table, not the \tcode{a_eq} operations. For an \tcode{unordered_set} the \tcode{key_type} and the \tcode{value_type} are both \tcode{Key}. The \tcode{iterator} and \tcode{const_iterator} types are both constant iterator types. It is unspecified whether they are the same type. +It provides the operations described in the preceding requirements table for unique keys; +that is, an \tcode{unordered_set} supports the \tcode{a_uniq} operations in that table, +not the \tcode{a_eq} operations. +For an \tcode{unordered_set} the \tcode{key_type} +and the \tcode{value_type} are both \tcode{Key}. +The \tcode{iterator} and \tcode{const_iterator} types are both constant iterator types. +It is unspecified whether they are the same type. \pnum Subclause~\ref{unord.set} only describes operations on \tcode{unordered_set} that From 5fcc2a922de40ca99a63cbf2f9e300e62458c34c Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Mon, 22 Aug 2022 22:14:21 +0100 Subject: [PATCH 361/430] [stack.ops] fix indentation --- source/containers.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/containers.tex b/source/containers.tex index 629e67b3d3..e3ba5047f8 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -14499,7 +14499,7 @@ \indexlibrarymember{operator>=}{stack}% \begin{itemdecl} template - bool operator>=(const stack& x, const stack& y); + bool operator>=(const stack& x, const stack& y); \end{itemdecl} \begin{itemdescr} From 90bc316752f2b89dd02acfcdf91c5e4b744ce2f7 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Mon, 22 Aug 2022 22:18:39 +0100 Subject: [PATCH 362/430] [counted.iter.nav] fix indentation --- source/iterators.tex | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/source/iterators.tex b/source/iterators.tex index e4849c4ad3..128132075b 100644 --- a/source/iterators.tex +++ b/source/iterators.tex @@ -6135,8 +6135,8 @@ \indexlibrarymember{operator--}{counted_iterator}% \begin{itemdecl} - constexpr counted_iterator& operator--() - requires @\libconcept{bidirectional_iterator}@; +constexpr counted_iterator& operator--() + requires @\libconcept{bidirectional_iterator}@; \end{itemdecl} \begin{itemdescr} @@ -6152,8 +6152,8 @@ \indexlibrarymember{operator--}{counted_iterator}% \begin{itemdecl} - constexpr counted_iterator operator--(int) - requires @\libconcept{bidirectional_iterator}@; +constexpr counted_iterator operator--(int) + requires @\libconcept{bidirectional_iterator}@; \end{itemdecl} \begin{itemdescr} @@ -6169,8 +6169,8 @@ \indexlibrarymember{operator+}{counted_iterator}% \begin{itemdecl} - constexpr counted_iterator operator+(iter_difference_t n) const - requires @\libconcept{random_access_iterator}@; +constexpr counted_iterator operator+(iter_difference_t n) const + requires @\libconcept{random_access_iterator}@; \end{itemdecl} \begin{itemdescr} @@ -6194,8 +6194,8 @@ \indexlibrarymember{operator+=}{counted_iterator}% \begin{itemdecl} - constexpr counted_iterator& operator+=(iter_difference_t n) - requires @\libconcept{random_access_iterator}@; +constexpr counted_iterator& operator+=(iter_difference_t n) + requires @\libconcept{random_access_iterator}@; \end{itemdecl} \begin{itemdescr} @@ -6215,8 +6215,8 @@ \indexlibrarymember{operator-}{counted_iterator}% \begin{itemdecl} - constexpr counted_iterator operator-(iter_difference_t n) const - requires @\libconcept{random_access_iterator}@; +constexpr counted_iterator operator-(iter_difference_t n) const + requires @\libconcept{random_access_iterator}@; \end{itemdecl} \begin{itemdescr} From a758844278a818fd8ccbd33a6ca0460b31616d74 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Mon, 22 Aug 2022 22:33:04 +0100 Subject: [PATCH 363/430] [range.elements.view] fix class-key for iterator and sentinel --- source/ranges.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index bac1bce583..19186a9658 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -8815,10 +8815,10 @@ private: // \ref{range.elements.iterator}, class template \tcode{elements_view::\exposid{iterator}} - template struct @\exposid{iterator}@; // \expos + template class @\exposid{iterator}@; // \expos // \ref{range.elements.sentinel}, class template \tcode{elements_view::\exposid{sentinel}} - template struct @\exposid{sentinel}@; // \expos + template class @\exposid{sentinel}@; // \expos V @\exposid{base_}@ = V(); // \expos }; From 44b146eda750e453ee3d52587c2accab4be6c74d Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Mon, 22 Aug 2022 22:35:18 +0100 Subject: [PATCH 364/430] [range.elements.iterator] remove stray semi-colon --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index 19186a9658..53663b1ba3 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -9085,7 +9085,7 @@ \indexlibrarymember{operator+=}{elements_view::iterator}% \begin{itemdecl} -constexpr @\exposid{iterator}@& operator+=(difference_type n); +constexpr @\exposid{iterator}@& operator+=(difference_type n) requires @\libconcept{random_access_range}@<@\exposid{Base}@>; \end{itemdecl} From 3a51f3e858e14abc0623f8823e0d2c883c27a4e4 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Mon, 22 Aug 2022 22:45:30 +0100 Subject: [PATCH 365/430] [complex.ops] use character literal for single character --- source/numerics.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/numerics.tex b/source/numerics.tex index 7c848a2faf..938d0ca797 100644 --- a/source/numerics.tex +++ b/source/numerics.tex @@ -728,7 +728,7 @@ s.flags(o.flags()); s.imbue(o.getloc()); s.precision(o.precision()); -s << '(' << x.real() << "," << x.imag() << ')'; +s << '(' << x.real() << ',' << x.imag() << ')'; return o << s.str(); \end{codeblock} From 678907e6d8af62cab9429b7065be69c36ffa2592 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Mon, 22 Aug 2022 22:46:43 +0100 Subject: [PATCH 366/430] [rand.req.dist] fix grammar typo --- source/numerics.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/numerics.tex b/source/numerics.tex index 938d0ca797..069294b03b 100644 --- a/source/numerics.tex +++ b/source/numerics.tex @@ -2355,7 +2355,7 @@ \tcode{os << d} or of any \keyword{const} member function of \tcode{D} -between any of the invocations \tcode{d(g)}. +between any of the invocations of \tcode{d(g)}. \pnum If a textual representation is written using \tcode{os << x} From 698be9d6b09517dc1323ca99fc4bb84ec62fae9e Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Mon, 22 Aug 2022 22:56:42 +0100 Subject: [PATCH 367/430] [cons.slice], [gslice.cons] remove undeclared/undocumented copy constructor signatures --- source/numerics.tex | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/numerics.tex b/source/numerics.tex index 069294b03b..123b0c6977 100644 --- a/source/numerics.tex +++ b/source/numerics.tex @@ -7929,7 +7929,6 @@ \begin{itemdecl} slice(); slice(size_t start, size_t length, size_t stride); -slice(const slice&); \end{itemdecl} \begin{itemdescr} @@ -8230,7 +8229,6 @@ gslice(); gslice(size_t start, const valarray& lengths, const valarray& strides); -gslice(const gslice&); \end{itemdecl} \begin{itemdescr} From 1cda1f9d2ac5d8caa81e793ce3f95364aba1fb6b Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Mon, 22 Aug 2022 23:01:23 +0100 Subject: [PATCH 368/430] [template.mask.array.overview], [template.indirect.array.overview] fix itemdecl typos --- source/numerics.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/numerics.tex b/source/numerics.tex index 123b0c6977..514319824d 100644 --- a/source/numerics.tex +++ b/source/numerics.tex @@ -8431,7 +8431,7 @@ \indexlibrarymember{operator[]}{mask_array}% \begin{itemdecl} -mask_array valarray::operator[](const valarray&). +mask_array valarray::operator[](const valarray&); \end{itemdecl} \pnum @@ -8548,7 +8548,7 @@ \indexlibrarymember{operator[]}{indirect_array}% \begin{itemdecl} -indirect_array valarray::operator[](const valarray&). +indirect_array valarray::operator[](const valarray&); \end{itemdecl} \pnum From f3ddcf79a971f488b3acf0e52ca6ea9689af7fd7 Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Tue, 23 Aug 2022 19:58:08 +0800 Subject: [PATCH 369/430] [ranges.cartesian.iterator] Fix typo "reference_t" => "range_reference_t" (#5777) --- source/ranges.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index 53663b1ba3..fd03fffd9e 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -14472,8 +14472,8 @@ using iterator_concept = @\seebelow@; using value_type = tuple>, range_value_t<@\exposid{maybe-const}@>...>; - using reference = tuple>, - reference_t<@\exposid{maybe-const}@>...>; + using reference = tuple>, + range_reference_t<@\exposid{maybe-const}@>...>; using difference_type = @\seebelow@; @\exposid{iterator}@() requires @\libconcept{forward_range}@<@\exposid{maybe-const}@> = default; From 227c3b249f0f52484920400b861717649895e6cc Mon Sep 17 00:00:00 2001 From: cor3ntin Date: Tue, 23 Aug 2022 14:00:44 +0200 Subject: [PATCH 370/430] [range.adjacent.overview] Use tuple in example, not pair (#5779) adjacent_view always yields tuples, but the example was written as if it yielded a std::pair. --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index fd03fffd9e..2f36f952b0 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -10548,7 +10548,7 @@ vector v = {1, 2, 3, 4}; for (auto i : v | views::adjacent<2>) { - cout << "(" << i.first << ", " << i.second << ") "; // prints \tcode{(1, 2) (2, 3) (3, 4)} + cout << "(" << std::get<0>(i) << ", " << std::get<1>(i) << ") "; // prints \tcode{(1, 2) (2, 3) (3, 4)} } \end{codeblock} \end{example} From c0c0d75402b1dc33f0cba971c898dc2ac7bfaa06 Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Tue, 23 Aug 2022 20:00:49 +0800 Subject: [PATCH 371/430] [range.cartesian.view] Add missing angle brackets for cartesian-is-sized-sentinel --- source/ranges.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index 2f36f952b0..78cec1bf66 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -14299,8 +14299,8 @@ template class FirstSent, class First, class... Vs> concept @\defexposconcept{cartesian-is-sized-sentinel}@ = // \expos - (@\libconcept{sized_sentinel_for}@, - iterator_t<@\exposid{maybe-const}@> && ... + (@\libconcept{sized_sentinel_for}@>, + iterator_t<@\exposid{maybe-const}@>> && ... && (@\libconcept{sized_range}@<@\exposid{maybe-const}@> && @\libconcept{sized_sentinel_for}@>, iterator_t<@\exposid{maybe-const}@>>)); From c777f930668fe23ab287ff765463d3b3731696eb Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Tue, 23 Aug 2022 21:45:23 +0800 Subject: [PATCH 372/430] [range.zip, ranges.cartesian.iterator] Simplify `maybe-const` to `const Views` (#5778) The type `maybe-const` only appears after `Const &&` in these cases, so that only the case where `Const` is `true` matters. --- source/ranges.tex | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index 78cec1bf66..97d2b6ac46 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -9519,8 +9519,7 @@ @\exposid{iterator}@() = default; constexpr @\exposid{iterator}@(@\exposid{iterator}@ i) - requires Const && (@\libconcept{convertible_to}@, - iterator_t<@\exposid{maybe-const}@>> && ...); + requires Const && (@\libconcept{convertible_to}@, iterator_t> && ...); constexpr auto operator*() const; constexpr @\exposid{iterator}@& operator++(); @@ -9601,8 +9600,7 @@ \begin{itemdecl} constexpr @\exposid{iterator}@(@\exposid{iterator}@ i) - requires Const && - (@\libconcept{convertible_to}@, iterator_t<@\exposid{maybe-const}@>> && ...); + requires Const && (@\libconcept{convertible_to}@, iterator_t> && ...); \end{itemdecl} \begin{itemdescr} @@ -9887,8 +9885,7 @@ public: @\exposid{sentinel}@() = default; constexpr @\exposid{sentinel}@(@\exposid{sentinel}@ i) - requires Const && - (@\libconcept{convertible_to}@, sentinel_t<@\exposid{maybe-const}@>> && ...); + requires Const && (@\libconcept{convertible_to}@, sentinel_t> && ...); template requires (@\libconcept{sentinel_for}@>, @@ -9922,8 +9919,7 @@ \begin{itemdecl} constexpr @\exposid{sentinel}@(@\exposid{sentinel}@ i) - requires Const && - (@\libconcept{convertible_to}@, sentinel_t<@\exposid{maybe-const}@>> && ...); + requires Const && (@\libconcept{convertible_to}@, sentinel_t> && ...); \end{itemdecl} \begin{itemdescr} @@ -14479,8 +14475,8 @@ @\exposid{iterator}@() requires @\libconcept{forward_range}@<@\exposid{maybe-const}@> = default; constexpr @\exposid{iterator}@(@\exposid{iterator}@ i) requires Const && - (@\libconcept{convertible_to}@, iterator_t<@\exposid{maybe-const}@>> && - ... && @\libconcept{convertible_to}@, iterator_t<@\exposid{maybe-const}@>>); + (@\libconcept{convertible_to}@, iterator_t> && + ... && @\libconcept{convertible_to}@, iterator_t>); constexpr auto operator*() const; constexpr @\exposid{iterator}@& operator++(); @@ -14668,8 +14664,8 @@ \begin{itemdecl} constexpr @\exposid{iterator}@(@\exposid{iterator}@ i) requires Const && - (@\libconcept{convertible_to}@, iterator_t<@\exposid{maybe-const}@>> && - ... && @\libconcept{convertible_to}@, iterator_t<@\exposid{maybe-const}@>>); + (@\libconcept{convertible_to}@, iterator_t> && + ... && @\libconcept{convertible_to}@, iterator_t>); \end{itemdecl} \begin{itemdescr} From eca39f43798d7a58fdd482232c60b6db428b656f Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Wed, 24 Aug 2022 01:57:58 +0800 Subject: [PATCH 373/430] [tuple.syn, tuple.like] Fix template head formatting (#5784) --- source/utilities.tex | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/utilities.tex b/source/utilities.tex index d6ad0b1ec4..b93248dd1e 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -1484,9 +1484,9 @@ class tuple; // \ref{tuple.like}, concept \exposconcept{tuple-like} - template + template concept @\exposconcept{tuple-like}@ = @\seebelownc@; // \expos - template + template concept @\defexposconcept{pair-like}@ = // \expos @\exposconcept{tuple-like}@ && tuple_size_v> == 2; @@ -1582,7 +1582,7 @@ \rSec2[tuple.like]{Concept \ecname{tuple-like}} \begin{itemdecl} -template +template concept @\defexposconcept{tuple-like}@ = @\seebelownc@; // \expos \end{itemdecl} From 356fb7ff88b63d956b1109c72c5e3bf424f6ba29 Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Wed, 24 Aug 2022 01:58:17 +0800 Subject: [PATCH 374/430] [algorithm.syn] Fix template head formatting (#5786) --- source/algorithms.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/algorithms.tex b/source/algorithms.tex index 39d344bdf2..1a4d627698 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -1274,7 +1274,7 @@ @\exposconcept{indirectly-binary-right-foldable}@> F> constexpr auto fold_right(R&& r, T init, F f); - template <@\libconcept{bidirectional_iterator}@ I, @\libconcept{sentinel_for}@ S, + template<@\libconcept{bidirectional_iterator}@ I, @\libconcept{sentinel_for}@ S, @\exposconcept{indirectly-binary-right-foldable}@, I> F> requires @\libconcept{constructible_from}@, iter_reference_t> constexpr auto fold_right_last(I first, S last, F f); From 6ccb959c7a8c10fc5fa7dd469c64f3c992e7e7ee Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Tue, 23 Aug 2022 20:10:44 +0800 Subject: [PATCH 375/430] [range.zip.overview] Use tuple in example, not pair --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index 97d2b6ac46..7afbde3bf7 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -9379,7 +9379,7 @@ list l = {'a', 'b', 'c'}; auto z = views::zip(v, l); -range_reference_t f = z.front(); // \tcode{f} is a \tcode{pair} +range_reference_t f = z.front(); // \tcode{f} is a \tcode{tuple} // that refers to the first element of \tcode{v} and \tcode{l} for (auto&& [x, y] : z) { From 8404284d8b7ac6ff2725a33d5e33410d1ea3b470 Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Tue, 23 Aug 2022 23:10:39 +0800 Subject: [PATCH 376/430] [range.drop.overview, range.take.overview] Fixed unformatted (void)F, decay-copy(E) --- source/ranges.tex | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index 7afbde3bf7..182ee7b5d4 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -5651,7 +5651,7 @@ \item If \tcode{T} is a specialization of \tcode{ranges::empty_view}\iref{range.empty.view}, -then \tcode{((void) F, \placeholdernc{decay-copy}(E))}, +then \tcode{((void)F, \placeholdernc{decay-copy}(E))}, except that the evaluations of \tcode{E} and \tcode{F} are indeterminately sequenced. @@ -6101,7 +6101,7 @@ \item If \tcode{T} is a specialization of \tcode{ranges::empty_view}\iref{range.empty.view}, -then \tcode{((void) F, \placeholdernc{decay-copy}(E))}, +then \tcode{((void)F, \placeholdernc{decay-copy}(E))}, except that the evaluations of \tcode{E} and \tcode{F} are indeterminately sequenced. @@ -6144,7 +6144,7 @@ \end{codeblock} except that \tcode{E} is evaluated only once; \item -otherwise, ((void) F, \placeholdernc{decay-copy}(E)), +otherwise, \tcode{((void)F, \placeholdernc{decay-copy}(E))}, except that the evaluations of \tcode{E} and \tcode{F} are indeterminately sequenced. \end{itemize} From 6e2b23594abd64c9ba50934654c68bd174c7ab91 Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Wed, 24 Aug 2022 18:49:21 +0800 Subject: [PATCH 377/430] [format.range.fmtstr] Add ranges namespace qualifier (#5788) The range concept is named outside of the `ranges` namespace. --- source/utilities.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/utilities.tex b/source/utilities.tex index b93248dd1e..9f8b790a2b 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -16244,7 +16244,7 @@ \begin{itemdescr} \pnum The type of \tcode{r} is \tcode{const R\&} -if \tcode{\libconcept{input_range}} is \tcode{true} and +if \tcode{ranges::\libconcept{input_range}} is \tcode{true} and \tcode{R\&} otherwise. \pnum From 301f0cdcb547f54b1d39163550a5869a0c6b073f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Thu, 25 Aug 2022 02:28:09 +0100 Subject: [PATCH 378/430] [coroutine.syn] Move "all freestanding" comment to the top --- source/support.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/support.tex b/source/support.tex index 558a999947..3ea8ec79c5 100644 --- a/source/support.tex +++ b/source/support.tex @@ -5141,9 +5141,9 @@ \indexheader{coroutine}% \indexlibraryglobal{noop_coroutine_handle}% \begin{codeblock} +// all freestanding #include // see \ref{compare.syn} -// all freestanding namespace std { // \ref{coroutine.traits}, coroutine traits template From e38650de03741a87d6c625ce93974946f46f5caa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Thu, 25 Aug 2022 02:41:49 +0100 Subject: [PATCH 379/430] [tuple.like] Remove extraneous "std::" qualification. --- source/utilities.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/utilities.tex b/source/utilities.tex index 9f8b790a2b..64c7b11e5e 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -1590,7 +1590,7 @@ \pnum A type \tcode{T} models and satisfies the exposition-only concept \exposconcept{tuple-like} -if \tcode{std::remove_cvref_t} is a specialization of +if \tcode{remove_cvref_t} is a specialization of \tcode{array}, \tcode{pair}, \tcode{tuple}, or \tcode{ranges::subrange}. \end{itemdescr} From 3da6b0e8798681144b676b3b4180301f8f7c8f2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Thu, 25 Aug 2022 10:55:25 +0100 Subject: [PATCH 380/430] [const.iterators.{alias,iterators}] Add "exposition only" comments Suggested by CD review feedback. --- source/iterators.tex | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/iterators.tex b/source/iterators.tex index 128132075b..ba88203f18 100644 --- a/source/iterators.tex +++ b/source/iterators.tex @@ -4175,12 +4175,12 @@ \begin{itemdecl} template<@\libconcept{indirectly_readable}@ It> - using iter_const_reference_t = common_reference_t&&, - iter_reference_t>; + using iter_const_reference_t = + common_reference_t&&, iter_reference_t>; template - concept @\defexposconcept{constant-iterator}@ = @\libconcept{input_iterator}@ && - @\libconcept{same_as}@, iter_reference_t>; + concept @\defexposconcept{constant-iterator}@ = // \expos + @\libconcept{input_iterator}@ && @\libconcept{same_as}@, iter_reference_t>; template<@\libconcept{input_iterator}@ I> using @\libglobal{const_iterator}@ = @\seebelow@; @@ -4214,8 +4214,8 @@ template<@\libconcept{input_iterator}@ Iterator> class @\libglobal{basic_const_iterator}@ { - Iterator @\exposid{current_}@ = Iterator(); - using @\exposid{reference}@ = iter_const_reference_t; // \expos + Iterator @\exposidnc{current_}@ = Iterator(); // \expos + using @\exposidnc{reference}@ = iter_const_reference_t; // \expos public: using iterator_concept = @\seebelow@; From 5dd0216a477391fbce339e22f169136420472979 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Thu, 25 Aug 2022 11:12:24 +0100 Subject: [PATCH 381/430] [range.refinements] Fix template argument name ("T", not "R") --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index 182ee7b5d4..b4a55303cb 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -1624,7 +1624,7 @@ \begin{itemdecl} template concept @\deflibconcept{constant_range}@ = - @\libconcept{input_range}@ && @\exposconcept{constant-iterator}@>; + @\libconcept{input_range}@ && @\exposconcept{constant-iterator}@>; \end{itemdecl} \rSec1[range.utility]{Range utilities} From 347ded018d09d2a226e3ab42665d1a13b25d489a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Thu, 25 Aug 2022 11:27:38 +0100 Subject: [PATCH 382/430] [vector.bool.pspc] Reinstate redundant "inline", as per paper The "inline" was removed editorially in 2141dab25c7f6d186d662e0ebe916efcd56843ae, but CD review has requested we retain it. --- source/containers.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/containers.tex b/source/containers.tex index e3ba5047f8..1ab406a376 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -6110,7 +6110,7 @@ class vector; template - constexpr bool @\exposid{is-vector-bool-reference}@ = @\seebelow@; // \expos + inline constexpr bool @\exposid{is-vector-bool-reference}@ = @\seebelow@; // \expos // hash support template struct hash; From 79ab62930d2538e1ef668c6a1b50e8d7027ebedc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Thu, 25 Aug 2022 11:34:57 +0100 Subject: [PATCH 383/430] [format.string.escaped] Fix typos in "APOSTROPHE" --- source/utilities.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/utilities.tex b/source/utilities.tex index 64c7b11e5e..6d998c2bc3 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -15353,10 +15353,10 @@ \begin{itemize} \item -the result starts and ends with \unicode{0027}{apostrope} (\tcode{'}) +the result starts and ends with \unicode{0027}{apostrophe} (\tcode{'}) instead of \unicode{0022}{quotation mark} (\tcode{"}), and \item -if \placeholder{C} is \unicode{0027}{apostrope}, +if \placeholder{C} is \unicode{0027}{apostrophe}, the two characters \tcode{\textbackslash '} are appended to \placeholder{E}, and \item if \placeholder{C} is \unicode{0022}{quotation mark}, From 82481dc11cbb8bed32c4043c6a485d072a953542 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Thu, 25 Aug 2022 11:48:22 +0100 Subject: [PATCH 384/430] [range.cartesian.view] Add missing \exposid --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index b4a55303cb..157bae557e 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -14410,7 +14410,7 @@ \effects Equivalent to: \begin{codeblock} -@\exposid{iterator}@ it(@\exposid{tuple-transform}@( +@\exposid{iterator}@<@\exposid{is-const}@> it(@\exposid{tuple-transform}@( [](auto& rng){ return @\exposid{begin-or-first-end}@(rng); }, @\exposid{bases_}@)); return it; \end{codeblock} From b8707d9f61cf5632b61363efe73cd420ce74daca Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Tue, 23 Aug 2022 22:09:26 +0200 Subject: [PATCH 385/430] [check] Flag any space between 'template' and '<' Previously, the pattern required 'class' after '<' to fire. --- tools/check-source.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/check-source.sh b/tools/check-source.sh index de9403a933..716c235b05 100755 --- a/tools/check-source.sh +++ b/tools/check-source.sh @@ -108,9 +108,9 @@ grep -Hne '^\\\(change\|rationale\|effect\|difficulty\|howwide\)\s.\+$' compatib fail "change marker in [diff] followed by stuff" || failed=1 # Fixup: sed 's/^\\\(change\|rationale\|effect\|difficulty\|howwide\)\s\(.\)/\\\1\n\2/'q -# "template Date: Thu, 25 Aug 2022 19:31:57 +0800 Subject: [PATCH 386/430] [ranges] Tweak some examples (#5791) Removes redundant `std::` qualifications and uses `views::meow` instead of `meow_view`. --- source/ranges.tex | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index 157bae557e..efdb38f57a 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -2201,11 +2201,11 @@ \begin{example} \begin{codeblock} template -std::generator f(std::ranges::@\libconcept{input_range}@ auto&& r) { +generator f(ranges::@\libconcept{input_range}@ auto&& r) { if constexpr (YieldElements) - co_yield std::ranges::elements_of(r); // yield each element of \tcode{r} + co_yield ranges::elements_of(r); // yield each element of \tcode{r} else - co_yield r; // yield \tcode{r} as a single value + co_yield r; // yield \tcode{r} as a single value } \end{codeblock} \end{example} @@ -3825,7 +3825,7 @@ \begin{example} \begin{codeblock} auto ints = istringstream{"0 1 2 3 4"}; -ranges::copy(ranges::istream_view(ints), ostream_iterator{cout, "-"}); +ranges::copy(views::istream(ints), ostream_iterator{cout, "-"}); // prints \tcode{0-1-2-3-4-} \end{codeblock} \end{example} @@ -5919,7 +5919,7 @@ \begin{codeblock} auto input = istringstream{"0 1 2 3 4 5 6 7 8 9"}; auto small = [](const auto x) noexcept { return x < 5; }; -auto small_ints = istream_view(input) | views::take_while(small); +auto small_ints = views::istream(input) | views::take_while(small); for (const auto i : small_ints) { cout << i << ' '; // prints \tcode{0 1 2 3 4} } @@ -14251,9 +14251,9 @@ \pnum \begin{example} \begin{codeblock} -std::vector v { 0, 1, 2 }; +vector v { 0, 1, 2 }; for (auto&& [a, b, c] : views::cartesian_product(v, v, v)) { - std::cout << a << ' ' << b << ' ' << c << '\n'; + cout << a << ' ' << b << ' ' << c << '\n'; } // The above prints // \tcode{0 0 0} @@ -15003,14 +15003,14 @@ is successively produced as an element of the sequence. \begin{example} \begin{codeblock} -std::generator ints(int start = 0) { +generator ints(int start = 0) { while (true) co_yield start++; } void f() { - for (auto i : ints() | std::views::take(3)) - std::cout << i << ' '; // prints \tcode{0 1 2} + for (auto i : ints() | views::take(3)) + cout << i << ' '; // prints \tcode{0 1 2} } \end{codeblock} \end{example} From 4ed7fcf6b725207ac307a6d1411ad2aa4ed55c8f Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Fri, 26 Aug 2022 04:36:08 +0800 Subject: [PATCH 387/430] [containers] Add `std::` for `forward`/`move` (#5793) --- source/containers.tex | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index 1ab406a376..8631af1a87 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -9877,7 +9877,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{return try_emplace(move(x)).first->second;} +Equivalent to: \tcode{return try_emplace(std::move(x)).first->second;} \end{itemdescr} \indexlibrarymember{at}{map}% @@ -10015,7 +10015,7 @@ \pnum \expects \tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{map} -from \tcode{k}, \tcode{forward(obj)}. +from \tcode{k}, \tcode{std::forward(obj)}. \pnum \effects @@ -10055,7 +10055,7 @@ \pnum \expects \tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{map} -from \tcode{move(k)}, \tcode{forward(obj)}. +from \tcode{std::move(k)}, \tcode{std::for\-ward(obj)}. \pnum \effects @@ -11655,7 +11655,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{return try_emplace(move(k)).first->second;} +Equivalent to: \tcode{return try_emplace(std::move(k)).first->second;} \end{itemdescr} \indexlibrarymember{unordered_map}{at}% From aec46d1970a8869db0d178c436545b0e40968425 Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Fri, 26 Aug 2022 04:43:03 +0800 Subject: [PATCH 388/430] [move.sentinel] Remove extraneous "std" qualification in example (#5792) --- source/iterators.tex | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/iterators.tex b/source/iterators.tex index ba88203f18..cf6b9b8374 100644 --- a/source/iterators.tex +++ b/source/iterators.tex @@ -5253,13 +5253,12 @@ \begin{example} A \tcode{move_if} algorithm is easily implemented with \tcode{copy_if} using \tcode{move_iterator} and \tcode{move_sentinel}: - \begin{codeblock} template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, @\libconcept{weakly_incrementable}@ O, @\libconcept{indirect_unary_predicate}@ Pred> requires @\libconcept{indirectly_movable}@ void move_if(I first, S last, O out, Pred pred) { - std::ranges::copy_if(move_iterator{first}, move_sentinel{last}, out, pred); + ranges::copy_if(move_iterator{first}, move_sentinel{last}, out, pred); } \end{codeblock} \end{example} From ed18148b1d514c0aea12d99b1ec3a56d4a834266 Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Fri, 26 Aug 2022 15:00:12 +0800 Subject: [PATCH 389/430] [util.smartptr.shared.create] Add std:: qualification for forward --- source/memory.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/memory.tex b/source/memory.tex index 3fd0b8c0f5..89f807faf9 100644 --- a/source/memory.tex +++ b/source/memory.tex @@ -3922,7 +3922,7 @@ \pnum \returns A \tcode{shared_ptr} to an object of type \tcode{T} -with an initial value \tcode{T(forward(args)...)}. +with an initial value \tcode{T(std::forward(args)...)}. \pnum \remarks From eb703517cd6c79f56df12c5dca359121efbef4ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Fri, 26 Aug 2022 14:39:39 +0100 Subject: [PATCH 390/430] [range.move.wrap] Fix constraint (move, not copy-constructible) This was accidentally omitted from previous changes requested by P2494R2. --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index efdb38f57a..6acc896511 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -4124,7 +4124,7 @@ \begin{itemize} \item \tcode{\exposid{movable-box}} constrains its type parameter \tcode{T} with -\tcode{\libconcept{copy_constructible} \&\& is_object_v}. +\tcode{\libconcept{move_constructible} \&\& is_object_v}. \item The default constructor of \tcode{\exposid{movable-box}} is equivalent to: From 21dae43da09c599c588723e743b6f362279f4899 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Fri, 26 Aug 2022 14:42:00 +0100 Subject: [PATCH 391/430] [ranges] Formatting fixes (\exposid, \tcode, whitespace) --- source/ranges.tex | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index 6acc896511..391531acd7 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -3411,10 +3411,10 @@ class @\libglobal{repeat_view}@ : public view_interface> { private: // \ref{range.repeat.iterator}, class \tcode{repeat_view::\exposid{iterator}} - struct @\exposid{iterator}@; // \expos + struct @\exposidnc{iterator}@; // \expos - @\exposid{movable-box}@ @\exposid{value_}@ = W(); // \expos, see \ref{range.move.wrap} - Bound @\exposid{bound_}@ = Bound(); // \expos + @\exposidnc{movable-box}@ @\exposid{value_}@ = W(); // \expos, see \ref{range.move.wrap} + Bound @\exposid{bound_}@ = Bound(); // \expos public: repeat_view() requires @\libconcept{default_initializable}@ = default; @@ -3502,7 +3502,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{return \exposid{iterator}(addressof(*value_));} +Equivalent to: \tcode{return \exposid{iterator}(addressof(*\exposid{value_}));} \end{itemdescr} \indexlibrarymember{end}{repeat_view}% @@ -3547,12 +3547,12 @@ (@\exposid{is-integer-like}@ || @\libconcept{same_as}@)) class repeat_view::@\exposid{iterator}@ { private: - using @\exposid{index-type}@ = // \expos + using @\exposidnc{index-type}@ = // \expos conditional_t<@\libconcept{same_as}@, ptrdiff_t, Bound>; - const W* @\exposid{value_}@ = nullptr; // \expos - @\exposid{index-type}@ @\exposid{current_}@ = @\exposid{index-type}@(); // \expos + const W* @\exposidnc{value_}@ = nullptr; // \expos + @\exposidnc{index-type}@ @\exposidnc{current_}@ = @\exposidnc{index-type}@(); // \expos - constexpr explicit @\exposid{iterator}@(const W* value, @\exposid{index-type}@ b = @\exposid{index-type}@()); // \expos + constexpr explicit @\exposid{iterator}@(const W* value, @\exposid{index-type}@ b = @\exposidnc{index-type}@()); // \expos public: using iterator_concept = random_access_iterator_tag; @@ -4167,7 +4167,7 @@ \begin{itemize} \item If \tcode{\libconcept{copy_constructible}} is \tcode{true}, -\tcode{\exposid{movable-box}} should store only a \exposid{T} +\tcode{\exposid{movable-box}} should store only a \tcode{T} if either \tcode{T} models \libconcept{copyable}, or \tcode{is_nothrow_move_constructible_v \&\& is_nothrow_copy_constructible_v} is \tcode{true}. From 2a8e2eb4e687c83025ffeda3824818dce37097a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Fri, 26 Aug 2022 14:47:48 +0100 Subject: [PATCH 392/430] [coro.generator.promise] Fix indentation of declarations --- source/ranges.tex | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index 391531acd7..95082564b5 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -15236,11 +15236,11 @@ template requires @\libconcept{same_as}@::yielded, yielded> - auto yield_value(ranges::elements_of&&, Unused> g) noexcept; + auto yield_value(ranges::elements_of&&, Unused> g) noexcept; template requires @\libconcept{convertible_to}@, yielded> - auto yield_value(ranges::elements_of r) noexcept; + auto yield_value(ranges::elements_of r) noexcept; void await_transform() = delete; @@ -15252,12 +15252,12 @@ template requires @\libconcept{same_as}@ || @\libconcept{convertible_to}@ - void* operator new(size_t size, allocator_arg_t, const Alloc& alloc, const Args&...); + void* operator new(size_t size, allocator_arg_t, const Alloc& alloc, const Args&...); template requires @\libconcept{same_as}@ || @\libconcept{convertible_to}@ - void* operator new(size_t size, const This&, allocator_arg_t, const Alloc& alloc, - const Args&...); + void* operator new(size_t size, const This&, allocator_arg_t, const Alloc& alloc, + const Args&...); void operator delete(void* pointer, size_t size) noexcept; From 2a600822d08332a8350e3a093212bdc7f8a82e2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Fri, 26 Aug 2022 15:06:06 +0100 Subject: [PATCH 393/430] [format.range.fmtdef] Add "exposition only" comments --- source/utilities.tex | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/utilities.tex b/source/utilities.tex index 6d998c2bc3..7842eb1f76 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -15971,11 +15971,11 @@ \begin{codeblock} namespace std { template - struct @\exposid{range-default-formatter}@ { + struct @\exposidnc{range-default-formatter}@ { // \expos private: - using @\exposid{maybe-const-r}@ = @\exposid{fmt-maybe-const}@; + using @\exposidnc{maybe-const-r}@ = @\exposidnc{fmt-maybe-const}@; // \expos range_formatter>, - charT> @\exposid{underlying_}@; // \expos + charT> @\exposid{underlying_}@; // \expos public: constexpr void set_separator(basic_string_view sep); From 681b6ea7d6a88b073a5b4dbf6bcca8004a9aa63a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Fri, 26 Aug 2022 15:21:21 +0100 Subject: [PATCH 394/430] [format.range.fmt*] Fix missing \exposid, align comments --- source/utilities.tex | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/source/utilities.tex b/source/utilities.tex index 7842eb1f76..a391ae02af 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -16049,10 +16049,10 @@ template struct @\exposid{range-default-formatter}@ { private: - using @\exposid{maybe-const-map}@ = @\exposid{fmt-maybe-const}@; // \expos - using @\exposid{element-type}@ = // \expos + using @\exposidnc{maybe-const-map}@ = @\exposidnc{fmt-maybe-const}@; // \expos + using @\exposidnc{element-type}@ = // \expos remove_cvref_t>; - range_formatter<@\exposid{element-type}@, charT> @\exposid{underlying_}@; // \expos + range_formatter<@\exposidnc{element-type}@, charT> @\exposid{underlying_}@; // \expos public: constexpr @\exposid{range-default-formatter}@(); @@ -16128,9 +16128,9 @@ template struct @\exposid{range-default-formatter}@ { private: - using @\exposid{maybe-const-set}@ = @\exposid{fmt-maybe-const}@; // \expos - range_formatter>, - charT> @\exposid{underlying_}@; // \expos + using @\exposidnc{maybe-const-set}@ = @\exposidnc{fmt-maybe-const}@; // \expos + range_formatter>, + charT> @\exposid{underlying_}@; // \expos public: constexpr @\exposid{range-default-formatter}@(); @@ -16195,7 +16195,7 @@ requires (K == range_format::string || K == range_format::debug_string) struct @\exposid{range-default-formatter}@ { private: - formatter, charT> @\exposid{underlying_}@; // \expos + formatter, charT> @\exposid{underlying_}@; // \expos public: template From 9d71b7d3b0aac1f179fc3973b0ff1624b00b07ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Fri, 26 Aug 2022 15:26:39 +0100 Subject: [PATCH 395/430] [obj.lifetime] Add cross-reference pointing at basic.types.general Suggested by CD review feedback. --- source/memory.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/memory.tex b/source/memory.tex index 89f807faf9..9dc24f3078 100644 --- a/source/memory.tex +++ b/source/memory.tex @@ -846,7 +846,7 @@ \begin{itemdescr} \pnum \mandates -\tcode{T} is an implicit-lifetime type. +\tcode{T} is an implicit-lifetime type\iref{basic.types.general}. \pnum \expects From d4a97a72b682c3c371c3739ea67c5f6199eaad9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Fri, 26 Aug 2022 17:04:49 +0100 Subject: [PATCH 396/430] [coro.generator.promise] Prevent erroneous hyphenation with \mbox --- source/ranges.tex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index 95082564b5..7dac2ebf53 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -15383,7 +15383,8 @@ into which \tcode{g.range} is moved, whose member \tcode{await_ready} returns \tcode{false}, whose member \tcode{await_suspend} -pushes \tcode{g.range.\exposid{coroutine_}} +% FIXME: The mbox prevents TeX from adding a bizarre hyphen after coroutine_. +pushes \tcode{g.range.}\mbox{\exposid{coroutine_}} into \tcode{*x.\exposid{active_}} and resumes execution of the coroutine referred to by \tcode{g.range.\brk{}\exposid{coroutine_}}, and From d153a0fb2f7576c7312eda62264ae81b715dff98 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sat, 27 Aug 2022 14:36:30 +0200 Subject: [PATCH 397/430] [check] Flag concepts missing a definition --- tools/check-output.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tools/check-output.sh b/tools/check-output.sh index 257ec2fd63..1bfc1221a8 100755 --- a/tools/check-output.sh +++ b/tools/check-output.sh @@ -48,6 +48,13 @@ cat std-grammarindex.ind | sed 's/^\(.*\)$/grammar non-terminal \1 has no definition/' | fail || failed=1 +# Find concept index entries missing a definition +cat std-conceptindex.ind | + sed 's/.hyperindexformat/\nhyperindexformat/' | + awk 'BEGIN { def=1 } /^ .item/ { if (def==0) { gsub("[{},]", "", item); print item } item=$NF; def=0; next } /hyperindexformat/ { def=1 }' | + sed 's/^\(.*\)$/concept \1 has no definition/' | + fail || failed=1 + # Cross references since the previous standard. function indexentries() { sed 's,\\glossaryentry{\(.*\)@.*,\1,' "$1" | LANG=C sort; } function removals() { diff -u "$1" "$2" | grep '^-' | grep -v '^---' | sed 's/^-//'; } From 7f4e3ba4441db219b341341e4bedf4cb71773bbd Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sat, 27 Aug 2022 16:14:24 +0200 Subject: [PATCH 398/430] [mdspan.layout.stride.expo] Add missing \libconcept --- source/containers.tex | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index 8631af1a87..8de82c8d26 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -19633,9 +19633,9 @@ template concept @\defexposconcept{layout-mapping-alike}@ = requires { // \expos requires @\exposid{is-extents}@; - { M::is_always_strided() } -> same_as; - { M::is_always_exhaustive() } -> same_as; - { M::is_always_unique() } -> same_as; + { M::is_always_strided() } -> @\libconcept{same_as}@; + { M::is_always_exhaustive() } -> @\libconcept{same_as}@; + { M::is_always_unique() } -> @\libconcept{same_as}@; bool_constant::value; bool_constant::value; bool_constant::value; From 4b2d4db659afab41d6ba5bcee9fd884c6292e705 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sat, 27 Aug 2022 16:15:08 +0200 Subject: [PATCH 399/430] [range.subrange.access] Add missing \libconcept --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index 7dac2ebf53..c03916d3ec 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -2097,7 +2097,7 @@ \effects Equivalent to: \begin{codeblock} -if constexpr (bidirectional_iterator) { +if constexpr (@\libconcept{bidirectional_iterator}@) { if (n < 0) { ranges::advance(@\exposid{begin_}@, n); if constexpr (@\exposid{StoreSize}@) From 37189f807e7642d9bbc4b2c09b13c196e13811f6 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sat, 27 Aug 2022 16:15:38 +0200 Subject: [PATCH 400/430] [range.as.rvalue.view] Add missing \libconcept --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index c03916d3ec..60fc640a98 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -4477,7 +4477,7 @@ as_rvalue_view() requires @\libconcept{default_initializable}@ = default; constexpr explicit as_rvalue_view(V base); - constexpr V base() const & requires copy_constructible { return @\exposid{base_}@; } + constexpr V base() const & requires @\libconcept{copy_constructible}@ { return @\exposid{base_}@; } constexpr V base() && { return std::move(@\exposid{base_}@); } constexpr auto begin() requires (!@\exposconcept{simple-view}@) From bc6d64c6745821c8e28d097aa381493e316fe4e0 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sat, 27 Aug 2022 16:10:50 +0200 Subject: [PATCH 401/430] [check] Flag undecorated concept names --- tools/check-output.sh | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/tools/check-output.sh b/tools/check-output.sh index 1bfc1221a8..206e2b4f98 100755 --- a/tools/check-output.sh +++ b/tools/check-output.sh @@ -50,11 +50,28 @@ cat std-grammarindex.ind | # Find concept index entries missing a definition cat std-conceptindex.ind | - sed 's/.hyperindexformat/\nhyperindexformat/' | + sed 's/.hyperindexformat/\nhyperindexformat/;s/.hyperpage/hyperpage/' | awk 'BEGIN { def=1 } /^ .item/ { if (def==0) { gsub("[{},]", "", item); print item } item=$NF; def=0; next } /hyperindexformat/ { def=1 }' | sed 's/^\(.*\)$/concept \1 has no definition/' | fail || failed=1 +# Find undecorated concept names in code blocks +patt="`cat std-conceptindex.ind | + sed 's/.hyperindexformat/\nhyperindexformat/;s/.hyperpage/\nhyperpage/' | + sed -n 's/^ .item.*{\([-a-z_]*\)}.*$/\1/p'`" + +patt="`echo $patt | sed 's/ /\\\\|/g'`" +# $patt contains all concept names, separated by \| to use as a sed regex + +for f in *.tex; do + sed -n 's,//.*$,,;s/%.*$//;s/"[^"]*"/""/;/begin{codeblock\(tu\)\?}/,/end{codeblock\(tu\)\?}/{/[^-_{a-z\]\('"$patt"'\)[^-_}a-z();]/{=;p;};}' $f | + # prefix output with filename and line + sed '/^[0-9]\+$/{N;s/\n/:/;}' | sed "s/.*/$f:&/" | + grep -v "@.seebelow" | + sed "s/\$/ -- concept name without markup/" | + fail || failed=1 +done + # Cross references since the previous standard. function indexentries() { sed 's,\\glossaryentry{\(.*\)@.*,\1,' "$1" | LANG=C sort; } function removals() { diff -u "$1" "$2" | grep '^-' | grep -v '^---' | sed 's/^-//'; } From 47d38466d52e0061e85bb46bfb15de4f2a3b6c2c Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Tue, 30 Aug 2022 04:59:46 +0800 Subject: [PATCH 402/430] [range.repeat.view] Use \tcode (not \exposid) for WArgs (#5801) --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index 60fc640a98..0d9545baff 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -3486,7 +3486,7 @@ \begin{itemdescr} \pnum \effects -Initializes \exposid{value_} with arguments of types \exposid{WArgs...} +Initializes \exposid{value_} with arguments of types \tcode{WArgs...} obtained by forwarding the elements of \tcode{value_args} and initializes \exposid{bound_} with arguments of types \tcode{BoundArgs...} obtained by forwarding the elements of \tcode{bound_args}. From 9eb92bf36b19381a534273ad98e296dfeb7a0fc9 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Mon, 29 Aug 2022 22:45:41 +0200 Subject: [PATCH 403/430] [flat.set.modifiers] Remove stray 'return' in Effects clause --- source/containers.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/containers.tex b/source/containers.tex index 8de82c8d26..2b9c79c9a3 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -16683,7 +16683,7 @@ If the set already contains an element equivalent to \tcode{x}, \tcode{*this} and \tcode{x} are unchanged. Otherwise, -inserts a new element as if by: \tcode{return emplace(std::forward(x));}. +inserts a new element as if by \tcode{emplace(std::forward(x))}. \pnum \returns From 69177109f387d3958ffea237c9b0419e4d2aa49c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Fri, 2 Sep 2022 23:44:14 +0100 Subject: [PATCH 404/430] [expr.ass] Fix typo, "~" should be "^". This was a misapplication of P2327R1 in 0aebf5cacded1b64cf089dbc7a0504fbb9f50aa6. --- source/expressions.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/expressions.tex b/source/expressions.tex index 3f9124022f..391c4c4d06 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -7168,7 +7168,7 @@ Such expressions are deprecated if \tcode{E1} has volatile-qualified type and \placeholder{op} is not one of the bitwise operators -\tcode{|}, \tcode{\&}, \tcode{\~}; see~\ref{depr.volatile.type}. +\tcode{|}, \tcode{\&}, \tcode{\^}; see~\ref{depr.volatile.type}. For \tcode{+=} and \tcode{-=}, \tcode{E1} shall either have arithmetic type or be a pointer to a possibly cv-qualified completely-defined object type. In all other From ebb4a11b865b8146a172679cdb3045f5d0cd352d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Sat, 3 Sep 2022 02:06:04 +0100 Subject: [PATCH 405/430] [cpp.predefined] Fix index entries --- source/preprocessor.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/preprocessor.tex b/source/preprocessor.tex index 378ea30c81..af42cac023 100644 --- a/source/preprocessor.tex +++ b/source/preprocessor.tex @@ -1753,7 +1753,7 @@ as an extended floating-point type. \item -\indextext{__stdcpp_float16_t__@\mname{STDCPP_FLOAT128_T}}% +\indextext{__stdcpp_float128_t__@\mname{STDCPP_FLOAT128_T}}% \mname{STDCPP_FLOAT128_T}\\ Defined as the integer literal \tcode{1} if and only if the implementation supports @@ -1761,7 +1761,7 @@ as an extended floating-point type. \item -\indextext{__stdcpp_float16_t__@\mname{STDCPP_BFLOAT16_T}}% +\indextext{__stdcpp_bfloat16_t__@\mname{STDCPP_BFLOAT16_T}}% \mname{STDCPP_BFLOAT16_T}\\ Defined as the integer literal \tcode{1} if and only if the implementation supports an extended floating-point type From e6e17d5e136934f113d6e0a8bde4c227459a9d47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Sat, 3 Sep 2022 02:10:27 +0100 Subject: [PATCH 406/430] [diff.cpp20.{dcl,expr}] Fix subclause order to match main document --- source/compatibility.tex | 60 ++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/source/compatibility.tex b/source/compatibility.tex index ae154dead4..35f2e70fe5 100644 --- a/source/compatibility.tex +++ b/source/compatibility.tex @@ -39,36 +39,6 @@ auto c = L"a" U"b"; // was conditionally-supported; now ill-formed \end{codeblock} -\rSec2[diff.cpp20.dcl]{\ref{dcl.dcl}: declarations} - -\diffref{dcl.init.string} -\change -UTF-8 string literals may initialize arrays of \keyword{char} or -\tcode{\keyword{unsigned} \keyword{char}}. -\rationale -Compatibility with previously written code that conformed to previous versions of this document. -\effect -Arrays of \keyword{char} or \tcode{\keyword{unsigned} \keyword{char}} -may now be initialized with a UTF-8 string literal. -This can affect initialization that includes arrays -that are directly initialized within class types, typically aggregates. -For example: -\begin{codeblock} -struct A { - char8_t s[10]; -}; -struct B { - char s[10]; -}; - -void f(A); -void f(B); - -int main() { - f({u8""}); // ambiguous -} -\end{codeblock} - \rSec2[diff.cpp20.expr]{\ref{expr}: expressions} \diffref{expr.prim.id.unqual} @@ -99,6 +69,36 @@ // now equivalent to \tcode{arr.operator[](1, 2)} or ill-formed \end{codeblock} +\rSec2[diff.cpp20.dcl]{\ref{dcl.dcl}: declarations} + +\diffref{dcl.init.string} +\change +UTF-8 string literals may initialize arrays of \keyword{char} or +\tcode{\keyword{unsigned} \keyword{char}}. +\rationale +Compatibility with previously written code that conformed to previous versions of this document. +\effect +Arrays of \keyword{char} or \tcode{\keyword{unsigned} \keyword{char}} +may now be initialized with a UTF-8 string literal. +This can affect initialization that includes arrays +that are directly initialized within class types, typically aggregates. +For example: +\begin{codeblock} +struct A { + char8_t s[10]; +}; +struct B { + char s[10]; +}; + +void f(A); +void f(B); + +int main() { + f({u8""}); // ambiguous +} +\end{codeblock} + \rSec2[diff.cpp20.temp]{\ref{temp}: templates} \diffref{temp.deduct.type} From 853747c5d8130880b96a39ab940c343aa7530d71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Sat, 3 Sep 2022 15:02:00 +0100 Subject: [PATCH 407/430] [basic.fundamental] Use correct number; "are", not "is". --- source/basic.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/basic.tex b/source/basic.tex index d2ff0bce92..0495cca45f 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -5016,7 +5016,7 @@ \end{note} Except as specified in \ref{basic.extended.fp}, the object and value representations and accuracy of operations -of floating-point types is \impldef{representation of floating-point types}. +of floating-point types are \impldef{representation of floating-point types}. \pnum Integral and floating-point types are collectively From 84786ac1fb37c84151f8ff1514b0b52032a4db18 Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Sun, 4 Sep 2022 01:34:17 +0800 Subject: [PATCH 408/430] [functional.syn] Add missing \tcode (#5806) --- source/utilities.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/utilities.tex b/source/utilities.tex index a391ae02af..76dc63e329 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -9923,7 +9923,7 @@ class BinaryPredicate = equal_to<>> class boyer_moore_horspool_searcher; - // \ref{unord.hash}, class template hash + // \ref{unord.hash}, class template \tcode{hash} template struct hash; // freestanding From 91e8500ac6927761a11bfd13fac6969950605423 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Mon, 29 Aug 2022 23:00:31 +0200 Subject: [PATCH 409/430] [std] Redefine \logop to small caps and fix all uses --- source/basic.tex | 4 ++-- source/expressions.tex | 6 +++--- source/iostreams.tex | 4 ++-- source/macros.tex | 2 +- source/ranges.tex | 4 ++-- source/regex.tex | 4 ++-- source/templates.tex | 6 +++--- source/utilities.tex | 6 +++--- tools/check-source.sh | 4 ++++ 9 files changed, 22 insertions(+), 18 deletions(-) diff --git a/source/basic.tex b/source/basic.tex index 0495cca45f..4c96330a23 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -5964,8 +5964,8 @@ $B$ is an invocation of any specialization of \tcode{std::kill_dependency}\iref{atomics.order}, or \item -$A$ is the left operand of a built-in logical \logop{AND} (\tcode{\&\&}, -see~\ref{expr.log.and}) or logical \logop{OR} (\tcode{||}, see~\ref{expr.log.or}) +$A$ is the left operand of a built-in logical \logop{and} (\tcode{\&\&}, +see~\ref{expr.log.and}) or logical \logop{or} (\tcode{||}, see~\ref{expr.log.or}) operator, or \item $A$ is the left operand of a conditional (\tcode{?:}, see~\ref{expr.cond}) diff --git a/source/expressions.tex b/source/expressions.tex index 391c4c4d06..ec05f026da 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -6705,7 +6705,7 @@ of the base-2 representation of the result \tcode{r} is 1 if both $\tcode{x}_i$ and $\tcode{y}_i$ are 1, and 0 otherwise. \begin{note} -The result is the bitwise \logop{AND} function of the operands. +The result is the bitwise \logop{and} function of the operands. \end{note} \rSec2[expr.xor]{Bitwise exclusive OR operator}% @@ -6731,7 +6731,7 @@ is 1 if either (but not both) of $\tcode{x}_i$ and $\tcode{y}_i$ is 1, and 0 otherwise. \begin{note} -The result is the bitwise exclusive \logop{OR} function of the operands. +The result is the bitwise exclusive \logop{or} function of the operands. \end{note} \rSec2[expr.or]{Bitwise inclusive OR operator}% @@ -6756,7 +6756,7 @@ of the base-2 representation of the result \tcode{r} is 1 if at least one of $\tcode{x}_i$ and $\tcode{y}_i$ is 1, and 0 otherwise. \begin{note} -The result is the bitwise inclusive \logop{OR} function of the operands. +The result is the bitwise inclusive \logop{or} function of the operands. \end{note} \rSec2[expr.log.and]{Logical AND operator}% diff --git a/source/iostreams.tex b/source/iostreams.tex index 7c31b348b3..9128226c17 100644 --- a/source/iostreams.tex +++ b/source/iostreams.tex @@ -15365,10 +15365,10 @@ \tcode{permissions} shall replace the file's permission bits with \tcode{perm} \\ \rowsep \tcode{add} & \tcode{permissions} shall replace the file's permission bits with - the bitwise \logop{OR} of \tcode{perm} and the file's current permission bits. \\ \rowsep + the bitwise \logop{or} of \tcode{perm} and the file's current permission bits. \\ \rowsep \tcode{remove} & \tcode{permissions} shall replace the file's permission bits with - the bitwise \logop{AND} of the complement of \tcode{perm} and the file's current permission bits. \\ \rowsep + the bitwise \logop{and} of the complement of \tcode{perm} and the file's current permission bits. \\ \rowsep \tcode{nofollow} & \tcode{permissions} shall change the permissions of a symbolic link itself rather than the permissions of the file the link resolves to. \\ diff --git a/source/macros.tex b/source/macros.tex index 9f29cdd9ea..295267bf98 100644 --- a/source/macros.tex +++ b/source/macros.tex @@ -518,7 +518,7 @@ \newcommand{\cvqual}[1]{\textit{#1}} \newcommand{\cv}{\ifmmode\mathit{cv}\else\cvqual{cv}\fi} \newcommand{\numconst}[1]{\textsl{#1}} -\newcommand{\logop}[1]{{\footnotesize #1}} +\newcommand{\logop}[1]{\textsc{#1}} %%-------------------------------------------------- %% Environments for code listings. diff --git a/source/ranges.tex b/source/ranges.tex index 0d9545baff..1ddf2f9990 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -3994,7 +3994,7 @@ Range adaptors are declared in namespace \tcode{std::ranges::views}. \pnum -The bitwise \logop{OR} operator is overloaded for the purpose of creating adaptor chain +The bitwise \logop{or} operator is overloaded for the purpose of creating adaptor chain pipelines. The adaptors also support function call syntax with equivalent semantics. @@ -9863,7 +9863,7 @@ \pnum \remarks The exception specification is equivalent to -the logical \logop{AND} of the following expressions: +the logical \logop{and} of the following expressions: \begin{codeblock} noexcept(ranges::iter_swap(std::get<@$i$@>(l.@\exposid{current_}@), std::get<@$i$@>(r.@\exposid{current_}@))) \end{codeblock} diff --git a/source/regex.tex b/source/regex.tex index 6aec80405f..1503118992 100644 --- a/source/regex.tex +++ b/source/regex.tex @@ -264,7 +264,7 @@ Converts the character sequence designated by the iterator range \range{F1}{F2} into a value of a bitmask type that can subsequently be passed to \tcode{isctype}. -Values returned from \tcode{lookup_classname} can be bitwise \logop{OR}'ed together; +Values returned from \tcode{lookup_classname} can be bitwise \logop{or}'ed together; the resulting value represents membership in either of the corresponding character classes. If \tcode{b} is \tcode{true}, the returned bitmask is suitable for @@ -3850,7 +3850,7 @@ \indexlibrary{regular expression traits!\idxcode{lookup_classname}}% \indexlibrary{\idxcode{lookup_classname}!regular expression traits}% The results from multiple calls -to \tcode{traits_inst.lookup_classname} can be bitwise \logop{OR}'ed +to \tcode{traits_inst.lookup_classname} can be bitwise \logop{or}'ed together and subsequently passed to \tcode{traits_inst.isctype}. \pnum diff --git a/source/templates.tex b/source/templates.tex index e166e10446..873ad16891 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -1589,8 +1589,8 @@ called the \defn{parameter mapping}\iref{temp.constr.decl}. \begin{note} Atomic constraints are formed by constraint normalization\iref{temp.constr.normal}. -\tcode{E} is never a logical \logop{AND} expression\iref{expr.log.and} -nor a logical \logop{OR} expression\iref{expr.log.or}. +\tcode{E} is never a logical \logop{and} expression\iref{expr.log.and} +nor a logical \logop{or} expression\iref{expr.log.or}. \end{note} \pnum @@ -1728,7 +1728,7 @@ of that expression. \item Otherwise, the associated constraints are the normal form of a logical -\logop{AND} expression\iref{expr.log.and} whose operands are in the +\logop{and} expression\iref{expr.log.and} whose operands are in the following order: \begin{itemize} \item diff --git a/source/utilities.tex b/source/utilities.tex index 76dc63e329..7e276bbfd9 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -2151,7 +2151,7 @@ \pnum \remarks -The exception specification is equivalent to the logical \logop{AND} of the +The exception specification is equivalent to the logical \logop{and} of the following expressions: \begin{codeblock} @@ -5116,7 +5116,7 @@ \pnum \remarks -The exception specification is equivalent to the logical \logop{AND} of +The exception specification is equivalent to the logical \logop{and} of \tcode{is_nothrow_move_con\-structible_v<$\tcode{T}_i$>} for all $i$. If \tcode{is_trivially_move_constructible_v<$\tcode{T}_i$>} is \tcode{true} for all $i$, this constructor is trivial. @@ -5729,7 +5729,7 @@ If an exception is thrown during the exchange of the values of \tcode{*this} and \tcode{rhs}, the states of the values of \tcode{*this} and of \tcode{rhs} are determined by the exception safety guarantee of \tcode{variant}'s move constructor. -The exception specification is equivalent to the logical \logop{AND} of +The exception specification is equivalent to the logical \logop{and} of \tcode{is_nothrow_move_constructible_v<$\tcode{T}_i$> \&\& is_nothrow_swappable_v<$\tcode{T}_i$>} for all $i$. \end{itemdescr} diff --git a/tools/check-source.sh b/tools/check-source.sh index 716c235b05..db5291587d 100755 --- a/tools/check-source.sh +++ b/tools/check-source.sh @@ -177,6 +177,10 @@ for f in $texfiles; do done | fail '"shall", "should", or "may" inside a note' || failed=1 +# \logop should use lowercase arguments +grep -n '\\logop{[^}]*[^andor}][^}]*}' $texfiles | + fail 'bad argument for \\logop' || failed=1 + # Hanging paragraphs for f in $texfiles; do sed -n '/^\\rSec/{=;p;};/^\\pnum/{s/^.*$/x/;=;p;}' $f | From 67ebb43f971b99a9d575d23f43884395873a53ea Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Mon, 29 Aug 2022 23:05:09 +0200 Subject: [PATCH 410/430] [ranges] Use \logop for names of logical operators --- source/ranges.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index 1ddf2f9990..3c92c3b121 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -14949,7 +14949,7 @@ \pnum \remarks The exception specification is equivalent to -the logical AND of the following expressions: +the logical \logop{and} of the following expressions: \begin{itemize} \item \tcode{noexcept(ranges::iter_move(std::get<$N$>(i.\exposid{current_})))} @@ -14976,7 +14976,7 @@ \pnum \remarks -The exception specification is equivalent to the logical AND of the following expressions: +The exception specification is equivalent to the logical \logop{and} of the following expressions: \begin{itemize} \item \tcode{noexcept(ranges::iter_swap(std::get<$i$>(l.\exposid{current_}), std::get<$i$>(r.\exposid{current_})))} From 07e02a80fe890dcb6e84182a5697046f1bd4c630 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Mon, 29 Aug 2022 22:23:54 +0200 Subject: [PATCH 411/430] [expected.object.assign] Add missing 'Returns: *this' --- source/utilities.tex | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source/utilities.tex b/source/utilities.tex index 7e276bbfd9..df39cb6a9b 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -7760,6 +7760,10 @@ Then, if no exception was thrown, equivalent to: \tcode{\exposid{has_val} = rhs.has_value(); return *this;} +\pnum +\returns +\tcode{*this}. + \pnum \remarks This operator is defined as deleted unless: @@ -7822,6 +7826,10 @@ Then, if no exception was thrown, equivalent to: \tcode{has_val = rhs.has_value(); return *this;} +\pnum +\returns +\tcode{*this}. + \pnum \remarks The exception specification is equivalent to: From 83ae42855cefb10b1852361ebae55bdc39d01ce5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Sun, 4 Sep 2022 12:42:21 +0100 Subject: [PATCH 412/430] [mdspan.extents.ctor] Improve hyphenation/line breaking --- source/containers.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/containers.tex b/source/containers.tex index 2b9c79c9a3..7ce22c67ac 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -18586,7 +18586,7 @@ with \tcode{as_const(exts[$d$])}. \item Otherwise, for all $d$ in the range $[0, \tcode{rank_dynamic()})$, -direct-non-list-initializes \tcode{\exposidnc{dynamic-extent}\brk{}[$d$]} +direct-non-list-initializes \exposidnc{dynamic-ex\-tent}\tcode{[$d$]} with \tcode{as_const(exts[\exposidnc{dynamic-index-inv}($d$)])}. \end{itemize} \end{itemdescr} From 06dcf0556631382ecdc420c22c66366168c226b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Sun, 4 Sep 2022 13:01:12 +0100 Subject: [PATCH 413/430] [mdspan.layout.left.overview] Reorder "explicit" and "constexpr" The standard ordering is "constexpr explicit", not the other way round. The paper P0009R18 contains a non-standard style, and other instances had already been fixed. Only this one seems to have been missed previously. --- source/containers.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index 7ce22c67ac..d8c18b6cdd 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -19043,8 +19043,8 @@ constexpr explicit(@\seebelow@) mapping(const layout_right::mapping&) noexcept; template - explicit(extents_type::rank() > 0) - constexpr mapping(const layout_stride::mapping&); + constexpr explicit(extents_type::rank() > 0) + mapping(const layout_stride::mapping&); constexpr mapping& operator=(const mapping&) noexcept = default; From e651f145df7c587ea810aca754e680bb27ea8481 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Sun, 4 Sep 2022 13:08:42 +0100 Subject: [PATCH 414/430] [mdspan.layout.{left,right}.overview] Replace "see below" with condition The condition is spelled out in the item descriptions already, and the class synopses seem to simply have been inconsistent with that in the incoming paper P0009R18. Since the "see below"s are never referenced explicitly, we just replace them with the actual conditions, which is also how the surrounding members are presented. --- source/containers.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index d8c18b6cdd..dd96349f57 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -19040,7 +19040,7 @@ constexpr explicit(!is_convertible_v) mapping(const mapping&) noexcept; template - constexpr explicit(@\seebelow@) + constexpr explicit(!is_convertible_v) mapping(const layout_right::mapping&) noexcept; template constexpr explicit(extents_type::rank() > 0) @@ -19292,7 +19292,7 @@ constexpr explicit(!is_convertible_v) mapping(const mapping&) noexcept; template - constexpr explicit(@\seebelow@) + constexpr explicit(!is_convertible_v) mapping(const layout_left::mapping&) noexcept; template constexpr explicit(extents_type::rank() > 0) From 1765844a9382e1f3415bbbdcd12eaa09a6b1f827 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Sun, 4 Sep 2022 13:25:52 +0100 Subject: [PATCH 415/430] [mdspan.layout.stride.expo] Move "otherwise" from trailing to leading We have a mild preference for the leading position. --- source/containers.tex | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index dd96349f57..9bde55ea65 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -19595,11 +19595,11 @@ Let \tcode{\exposid{REQUIRED-SPAN-SIZE}(e, strides)} be: \begin{itemize} \item -\tcode{1}, if \tcode{e.rank() == 0} is \tcode{true}, otherwise +\tcode{1}, if \tcode{e.rank() == 0} is \tcode{true}, \item -\tcode{0}, if the size of the multidimensional index space \tcode{e} is 0, otherwise +otherwise \tcode{0}, if the size of the multidimensional index space \tcode{e} is 0, \item -\tcode{1} plus the sum of products of \tcode{(e.extent($r$) - 1)} and \tcode{strides[$r$]} +otherwise \tcode{1} plus the sum of products of \tcode{(e.extent($r$) - 1)} and \tcode{strides[$r$]} for all $r$ in the range $[0, \tcode{e.rank()})$. \end{itemize} @@ -19607,11 +19607,11 @@ Let \tcode{\exposid{OFFSET}(m)} be: \begin{itemize} \item -\tcode{m()}, if \tcode{e.rank() == 0} is \tcode{true}, otherwise +\tcode{m()}, if \tcode{e.rank() == 0} is \tcode{true}, \item -\tcode{0}, if the size of the multidimensional index space \tcode{e} is 0, otherwise +otherwise \tcode{0}, if the size of the multidimensional index space \tcode{e} is 0, \item -\tcode{m(z...)} for a pack of integers \tcode{z} +otherwise \tcode{m(z...)} for a pack of integers \tcode{z} that is a multidimensional index in \tcode{m.extents()} and each element of \tcode{z} equals 0. \end{itemize} From c02512ecf3f15fb0f29dc602eb153bc7dabd643d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Sun, 4 Sep 2022 13:53:01 +0100 Subject: [PATCH 416/430] [mdspan.layout.stride.obs] Add missing parentheses --- source/containers.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/containers.tex b/source/containers.tex index 9bde55ea65..98c5103623 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -19852,7 +19852,7 @@ \tcode{true} if \tcode{x.extents() == y.extents()} is \tcode{true}, \tcode{\exposid{OFFSET}(y) == 0} is \tcode{true}, and each of \tcode{x.stride($r$) == y.stride($r$)} is \tcode{true} -for $r$ in the range $[0, \tcode{x.extents.rank()})$. +for $r$ in the range $[0, \tcode{x.extents().rank()})$. Otherwise, \tcode{false}. \end{itemdescr} From 9897c566ec3ecd6f25078a3dd10ce34c17e812e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Sun, 4 Sep 2022 13:54:19 +0100 Subject: [PATCH 417/430] [mdspan.accessor.default.members] Fix typo in "equivalent" --- source/containers.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/containers.tex b/source/containers.tex index 98c5103623..04ac7ea46b 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -20090,7 +20090,7 @@ \begin{itemdescr} \pnum \effects -Euivalent to: \tcode{return p + i;} +Equivalent to: \tcode{return p + i;} \end{itemdescr} \rSec2[mdspan.mdspan]{Class template \tcode{mdspan}} From 3b6163d1a3b1f5cc2be49d6ff0eb6b3889b552df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Sun, 4 Sep 2022 13:58:09 +0100 Subject: [PATCH 418/430] [flat.map.syn] Add missing "namespace std {" --- source/containers.tex | 1 + 1 file changed, 1 insertion(+) diff --git a/source/containers.tex b/source/containers.tex index 04ac7ea46b..44172319f7 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -13240,6 +13240,7 @@ #include // see \ref{compare.syn} #include // see \ref{initializer.list.syn} +namespace std { // \ref{flat.map}, class template \tcode{flat_map} template, class KeyContainer = vector, class MappedContainer = vector> From c164add6cdac73cae85649ba2172de43c3d8ed5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Sun, 4 Sep 2022 14:02:11 +0100 Subject: [PATCH 419/430] [flat.map.modifiers] Typo: "range" should be "rg" --- source/containers.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/containers.tex b/source/containers.tex index 44172319f7..e9909817d6 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -15359,7 +15359,7 @@ \effects Adds elements to \tcode{c} as if by: \begin{codeblock} -for (const auto& e : range) { +for (const auto& e : rg) { c.keys.insert(c.keys.end(), e.first); c.values.insert(c.values.end(), e.second); } From 1b427b20fecbc95b98d2380e0ddae71b71c1f657 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Sun, 4 Sep 2022 14:06:53 +0100 Subject: [PATCH 420/430] [flat.{,multi}set.ctor] Add missing "explicit" in itemdecls --- source/containers.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index e9909817d6..d180548039 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -16555,7 +16555,7 @@ \indexlibraryctor{flat_set}% \begin{itemdecl} -flat_set(container_type cont); +explicit flat_set(container_type cont); \end{itemdecl} \begin{itemdescr} @@ -17156,7 +17156,7 @@ \indexlibraryctor{flat_multiset}% \begin{itemdecl} -flat_multiset(container_type cont); +explicit flat_multiset(container_type cont); \end{itemdecl} \begin{itemdescr} From ae7c0119093f3a2d6e2d8fcb113b0897be3d9ba5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Sun, 4 Sep 2022 15:40:25 +0100 Subject: [PATCH 421/430] [flat.{,multi}set] Change stable label from "ctor" to "cons" --- source/containers.tex | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index d180548039..cbc9f67615 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -16345,7 +16345,7 @@ using const_reverse_iterator = std::reverse_iterator; using container_type = KeyContainer; - // \ref{flat.set.ctor}, constructors + // \ref{flat.set.cons}, constructors flat_set() : flat_set(key_compare()) { } explicit flat_set(container_type cont); @@ -16551,7 +16551,7 @@ } \end{codeblock} -\rSec3[flat.set.ctor]{Constructors} +\rSec3[flat.set.cons]{Constructors} \indexlibraryctor{flat_set}% \begin{itemdecl} @@ -16945,7 +16945,7 @@ using const_reverse_iterator = std::reverse_iterator; using container_type = KeyContainer; - // \ref{flat.multiset.ctor}, constructors + // \ref{flat.multiset.cons}, constructors flat_multiset() : flat_multiset(key_compare()) { } explicit flat_multiset(container_type cont); @@ -17152,7 +17152,7 @@ } \end{codeblock} -\rSec3[flat.multiset.ctor]{Constructors} +\rSec3[flat.multiset.cons]{Constructors} \indexlibraryctor{flat_multiset}% \begin{itemdecl} From 8c4981c5e9ddbfe6f5bcbb6c3e103b7787721232 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Sun, 4 Sep 2022 14:06:53 +0100 Subject: [PATCH 422/430] [mdspan] Change stable label from "ctor" to "cons" --- source/containers.tex | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index cbc9f67615..7d02506cbe 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -18286,7 +18286,7 @@ static constexpr size_t static_extent(rank_type) noexcept; constexpr index_type extent(rank_type) const noexcept; - // \ref{mdspan.extents.ctor}, constructors + // \ref{mdspan.extents.cons}, constructors constexpr extents() noexcept = default; template @@ -18438,7 +18438,7 @@ \end{note} \end{itemdescr} -\rSec3[mdspan.extents.ctor]{Constructors} +\rSec3[mdspan.extents.cons]{Constructors} \indexlibraryctor{extents}% \begin{itemdecl} @@ -19033,7 +19033,7 @@ using rank_type = typename extents_type::rank_type; using layout_type = layout_left; - // \ref{mdspan.layout.left.ctor}, constructors + // \ref{mdspan.layout.left.cons}, constructors constexpr mapping() noexcept = default; constexpr mapping(const mapping&) noexcept = default; constexpr mapping(const extents_type&) noexcept; @@ -19084,7 +19084,7 @@ \tcode{layout_left::mapping} is a trivially copyable type that models \libconcept{regular} for each \tcode{E}. -\rSec4[mdspan.layout.left.ctor]{Constructors} +\rSec4[mdspan.layout.left.cons]{Constructors} \indexlibraryctor{layout_left::mapping}% \begin{itemdecl} @@ -19285,7 +19285,7 @@ using rank_type = typename extents_type::rank_type; using layout_type = layout_right; - // \ref{mdspan.layout.right.ctor}, constructors + // \ref{mdspan.layout.right.cons}, constructors constexpr mapping() noexcept = default; constexpr mapping(const mapping&) noexcept = default; constexpr mapping(const extents_type&) noexcept; @@ -19336,7 +19336,7 @@ \tcode{layout_right::mapping} is a trivially copyable type that models \libconcept{regular} for each \tcode{E}. -\rSec4[mdspan.layout.right.ctor]{Constructors} +\rSec4[mdspan.layout.right.cons]{Constructors} \indexlibraryctor{layout_right::mapping}% \begin{itemdecl} @@ -19540,7 +19540,7 @@ static constexpr rank_type @\exposid{rank_}@ = extents_type::rank(); // \expos public: - // \ref{mdspan.layout.stride.ctor}, constructors + // \ref{mdspan.layout.stride.cons}, constructors constexpr mapping() noexcept = default; constexpr mapping(const mapping&) noexcept = default; template @@ -19651,7 +19651,7 @@ have a return type of \tcode{bool}. \end{note} -\rSec4[mdspan.layout.stride.ctor]{Constructors} +\rSec4[mdspan.layout.stride.cons]{Constructors} \indexlibraryctor{layout_stride::mapping}% \begin{itemdecl} @@ -20124,7 +20124,7 @@ { return extents_type::static_extent(r); } constexpr index_type extent(rank_type r) const noexcept { return extents().extent(r); } - // \ref{mdspan.mdspan.ctor}, constructors + // \ref{mdspan.mdspan.cons}, constructors constexpr mdspan(); constexpr mdspan(const mdspan& rhs) = default; constexpr mdspan(mdspan&& rhs) = default; @@ -20265,7 +20265,7 @@ its \tcode{accessor_type}, \tcode{mapping_type}, and \tcode{data_handle_type} are trivially copyable types. -\rSec3[mdspan.mdspan.ctor]{Constructors} +\rSec3[mdspan.mdspan.cons]{Constructors} \indexlibraryctor{mdspan}% \begin{itemdecl} From 48ac7b13b4e0dd64ccb5b9e84bd5af6036dd5c81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Sun, 4 Sep 2022 15:53:56 +0100 Subject: [PATCH 423/430] [stacktrace] Change stable label from "ctor" to "cons" --- source/diagnostics.tex | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/diagnostics.tex b/source/diagnostics.tex index 9c8268c703..bb70eb8ff3 100644 --- a/source/diagnostics.tex +++ b/source/diagnostics.tex @@ -1759,7 +1759,7 @@ public: using native_handle_type = @\impdefx{\tcode{stacktrace_entry::native_handle_type}}@; - // \ref{stacktrace.entry.ctor}, constructors + // \ref{stacktrace.entry.cons}, constructors constexpr stacktrace_entry() noexcept; constexpr stacktrace_entry(const stacktrace_entry& other) noexcept; constexpr stacktrace_entry& operator=(const stacktrace_entry& other) noexcept; @@ -1792,7 +1792,7 @@ \libconcept{regular}\iref{concepts.object} and \tcode{\libconcept{three_way_comparable}}\iref{cmp.concept}. -\rSec3[stacktrace.entry.ctor]{Constructors} +\rSec3[stacktrace.entry.cons]{Constructors} \indexlibraryctor{stacktrace_entry}% \begin{itemdecl} @@ -1933,7 +1933,7 @@ using size_type = @\impdefx{type of \tcode{basic_stacktrace::size_type}}@; using allocator_type = Allocator; - // \ref{stacktrace.basic.ctor}, creation and assignment + // \ref{stacktrace.basic.cons}, creation and assignment static basic_stacktrace current(const allocator_type& alloc = allocator_type()) noexcept; static basic_stacktrace current(size_type skip, const allocator_type& alloc = allocator_type()) noexcept; @@ -2009,7 +2009,7 @@ are different from those required for a container. \end{itemize} -\rSec3[stacktrace.basic.ctor]{Creation and assignment} +\rSec3[stacktrace.basic.cons]{Creation and assignment} \indexlibrarymember{current}{basic_stacktrace}% \begin{itemdecl} From 8481edfe3ada083ab03f20d2b79f2631d9d40839 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Sun, 4 Sep 2022 15:58:27 +0100 Subject: [PATCH 424/430] [spanstream etc.] Change stable label from "ctor" to "cons" --- source/iostreams.tex | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/source/iostreams.tex b/source/iostreams.tex index 9128226c17..851476a378 100644 --- a/source/iostreams.tex +++ b/source/iostreams.tex @@ -9778,7 +9778,7 @@ using off_type = typename traits::off_type; using traits_type = traits; - // \ref{spanbuf.ctor}, constructors + // \ref{spanbuf.cons}, constructors basic_spanbuf() : basic_spanbuf(ios_base::in | ios_base::out) {} explicit basic_spanbuf(ios_base::openmode which) : basic_spanbuf(std::span(), which) {} @@ -9828,7 +9828,7 @@ the underlying character sequence. \end{itemize} -\rSec3[spanbuf.ctor]{Constructors} +\rSec3[spanbuf.cons]{Constructors} \indexlibraryctor{basic_spanbuf}% \begin{itemdecl} @@ -10104,7 +10104,7 @@ using off_type = typename traits::off_type; using traits_type = traits; - // \ref{ispanstream.ctor}, constructors + // \ref{ispanstream.cons}, constructors explicit basic_ispanstream(std::span s, ios_base::openmode which = ios_base::in); basic_ispanstream(const basic_ispanstream&) = delete; @@ -10137,7 +10137,7 @@ in the underlying \tcode{spanbuf}. \end{note} -\rSec3[ispanstream.ctor]{Constructors} +\rSec3[ispanstream.cons]{Constructors} \indexlibraryctor{basic_ispanstream}% \begin{itemdecl} @@ -10150,7 +10150,7 @@ Initializes the base class with \tcode{basic_istream(addressof(sb))} and \tcode{sb} with -\tcode{basic_spanbuf(s, which | ios_base::in)}\iref{spanbuf.ctor}. +\tcode{basic_spanbuf(s, which | ios_base::in)}\iref{spanbuf.cons}. \end{itemdescr} \indexlibraryctor{basic_ispanstream}% @@ -10292,7 +10292,7 @@ using off_type = typename traits::off_type; using traits_type = traits; - // \ref{ospanstream.ctor}, constructors + // \ref{ospanstream.cons}, constructors explicit basic_ospanstream(std::span s, ios_base::openmode which = ios_base::out); basic_ospanstream(const basic_ospanstream&) = delete; @@ -10315,7 +10315,7 @@ } \end{codeblock} -\rSec3[ospanstream.ctor]{Constructors} +\rSec3[ospanstream.cons]{Constructors} \indexlibraryctor{basic_ospanstream}% \begin{itemdecl} @@ -10329,7 +10329,7 @@ Initializes the base class with \tcode{basic_ostream(addressof(sb))} and \tcode{sb} with -\tcode{basic_spanbuf(s, which | ios_base::out)}\iref{spanbuf.ctor}. +\tcode{basic_spanbuf(s, which | ios_base::out)}\iref{spanbuf.cons}. \end{itemdescr} \indexlibraryctor{basic_ospanstream}% @@ -10430,7 +10430,7 @@ using off_type = typename traits::off_type; using traits_type = traits; - // \ref{spanstream.ctor}, constructors + // \ref{spanstream.cons}, constructors explicit basic_spanstream(std::span s, ios_base::openmode which = ios_base::out | ios_base::in); basic_spanstream(const basic_spanstream&) = delete; @@ -10453,7 +10453,7 @@ } \end{codeblock} -\rSec3[spanstream.ctor]{Constructors} +\rSec3[spanstream.cons]{Constructors} \indexlibraryctor{basic_spanstream}% \begin{itemdecl} @@ -10467,7 +10467,7 @@ Initializes the base class with \tcode{basic_iostream(addressof(sb))} and \tcode{sb} with -\tcode{basic_spanbuf(s, which)}\iref{spanbuf.ctor}. +\tcode{basic_spanbuf(s, which)}\iref{spanbuf.cons}. \end{itemdescr} \indexlibraryctor{basic_spanstream}% From d5ba45dc4b29c4dbcbfbaf3b1dd392d7b0e40ddb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Sun, 4 Sep 2022 16:04:53 +0100 Subject: [PATCH 425/430] [range.stride.iterator] Add missing \exposid --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index 3c92c3b121..00e6d42218 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -13760,7 +13760,7 @@ using iterator_concept = @\seebelow@; using iterator_category = @\seebelow@; // not always present - iterator() requires @\libconcept{default_initializable}@> = default; + @\exposid{iterator}@() requires @\libconcept{default_initializable}@> = default; constexpr @\exposid{iterator}@(@\exposid{iterator}@ other) requires Const && @\libconcept{convertible_to}@, iterator_t<@\exposid{Base}@>> From a23caf77541ae173feaccfdcb2cf1406305ebb9c Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Mon, 5 Sep 2022 07:14:24 +0800 Subject: [PATCH 426/430] [range.iota.sentinel] Add missing \exposid (#5797) --- source/ranges.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ranges.tex b/source/ranges.tex index 00e6d42218..9f3743436e 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -3354,7 +3354,7 @@ \end{itemdescr} \begin{itemdecl} -friend constexpr iter_difference_t operator-(const @\exposid{iterator}@& x, const sentinel& y) +friend constexpr iter_difference_t operator-(const @\exposid{iterator}@& x, const @\exposid{sentinel}@& y) requires @\libconcept{sized_sentinel_for}@; \end{itemdecl} From 4b9953f998c1ea3359338697899447926648fe8c Mon Sep 17 00:00:00 2001 From: Hewill Kang <67143766+hewillk@users.noreply.github.com> Date: Mon, 5 Sep 2022 07:16:58 +0800 Subject: [PATCH 427/430] [ranges] Add missing \exposid (#5796) --- source/ranges.tex | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/ranges.tex b/source/ranges.tex index 9f3743436e..82e0257ed3 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -7216,7 +7216,7 @@ \end{itemdescr} \begin{itemdecl} -constexpr iterator(@\exposid{Parent}@& parent, iterator_t<@\exposid{Base}@> outer); +constexpr @\exposid{iterator}@(@\exposid{Parent}@& parent, iterator_t<@\exposid{Base}@> outer); \end{itemdecl} \begin{itemdescr} @@ -12285,9 +12285,9 @@ requires @\libconcept{random_access_range}@<@\exposid{Base}@> && @\libconcept{three_way_comparable}@>; - friend constexpr iterator operator+(const @\exposid{iterator}@& i, difference_type n) + friend constexpr @\exposid{iterator}@ operator+(const @\exposid{iterator}@& i, difference_type n) requires @\libconcept{random_access_range}@<@\exposid{Base}@>; - friend constexpr iterator operator+(difference_type n, const @\exposid{iterator}@& i) + friend constexpr @\exposid{iterator}@ operator+(difference_type n, const @\exposid{iterator}@& i) requires @\libconcept{random_access_range}@<@\exposid{Base}@>; friend constexpr @\exposid{iterator}@ operator-(const @\exposid{iterator}@& i, difference_type n) requires @\libconcept{random_access_range}@<@\exposid{Base}@>; @@ -13036,7 +13036,7 @@ \end{itemdescr} \begin{itemdecl} -constexpr iterator& operator+=(difference_type x) +constexpr @\exposid{iterator}@& operator+=(difference_type x) requires @\libconcept{random_access_range}@<@\exposid{Base}@>; \end{itemdecl} From 8f153df9c66c33f100ec7a4d7998dfaf6a7aa8da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Thu, 26 Nov 2020 02:43:37 +0000 Subject: [PATCH 428/430] [basic, except, diff] Rewordings to avoid "might" and "could" --- source/basic.tex | 4 ++-- source/compatibility.tex | 36 +++++++++++++++++------------------- source/exceptions.tex | 4 +--- 3 files changed, 20 insertions(+), 24 deletions(-) diff --git a/source/basic.tex b/source/basic.tex index 4c96330a23..f32e82975f 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -2870,7 +2870,7 @@ or defines a constexpr variable initialized to a TU-local value (defined below). \begin{note} An inline function template can be an exposure even though -explicit specializations of it might be usable in other translation units. +certain explicit specializations of it would be usable in other translation units. \end{note} \pnum @@ -2965,7 +2965,7 @@ } void adl(double); -inline void h(auto x) { adl(x); } // OK, but a specialization might be an exposure +inline void h(auto x) { adl(x); } // OK, but certain specializations are exposures \end{codeblocktu} \begin{codeblocktu}{Translation unit \#2} module A; diff --git a/source/compatibility.tex b/source/compatibility.tex index 35f2e70fe5..21cd9c51eb 100644 --- a/source/compatibility.tex +++ b/source/compatibility.tex @@ -631,11 +631,11 @@ Improve consistency of equality with three-way comparison and make it easier to write the full complement of equality operations. \effect -Equality and inequality expressions between two objects of different types, -where one is convertible to the other, -could invoke a different operator. -Equality and inequality expressions between two objects of the same type -could become ambiguous. +For certain pairs of types where one is convertible to the other, +equality or inequality expressions between an object of one type +and an object of the other type invoke a different operator. +Also, for certain types, equality or inequality expressions +between two objects of that type become ambiguous. For example: \begin{codeblock} struct A { @@ -921,9 +921,9 @@ \change Remove \tcode{raw_storage_iterator}. \rationale -The iterator encouraged use of algorithms that might throw exceptions, but did -not return the number of elements successfully constructed that might need to -be destroyed in order to avoid leaks. +The iterator encouraged use of potentially-throwing algorithms, but did +not return the number of elements successfully constructed, +as would be necessary to destroy them. \effect A valid \CppXVII{} program that uses this iterator class may fail to compile. @@ -958,8 +958,8 @@ The traits had unreliable or awkward interfaces. The \tcode{is_literal_type} trait provided no way to detect which subset of constructors and member functions of a type were declared \keyword{constexpr}. The \tcode{result_of} -trait had a surprising syntax that could not report the result of a regular -function type. It has been superseded by the \tcode{invoke_result} trait. +trait had a surprising syntax that did not directly support function types. +It has been superseded by the \tcode{invoke_result} trait. \effect A valid \CppXVII{} program that relies on the \tcode{is_literal_type} or \tcode{result_of} type traits, on the \tcode{is_literal_type_v} variable template, @@ -1019,8 +1019,6 @@ \effect A valid \CppXIV{} expression utilizing the increment operator on a \tcode{bool} lvalue is ill-formed in this revision of \Cpp{}. -Note that this might occur when the lvalue has a type given by a template -parameter. \diffref{expr.new,expr.delete} \change @@ -1694,7 +1692,7 @@ \rationale Overly constrained, simplify overload resolution rules. \effect -A valid \CppIII{} program could get a different result than in this +A valid \CppIII{} program can get a different result in this revision of \Cpp{}. \rSec2[diff.cpp03.library]{\ref{library}: library introduction} @@ -2354,8 +2352,8 @@ block. Allowing jump past initializers would require complicated runtime determination of allocation. -Furthermore, any use of the uninitialized object could be a -disaster. +Furthermore, many operations on such an uninitialized object +have undefined behavior. With this simple compile-time rule, \Cpp{} assures that if an initialized variable is in scope, then it has assuredly been initialized. @@ -2411,8 +2409,8 @@ with a type. In \Cpp{}, class members can be declared with the \keyword{static} storage class specifier. -Allowing storage class specifiers on type -declarations could render the code confusing for users. +Storage class specifiers on type +declarations can be confusing for users. \effect Deletion of semantically well-defined feature. \difficulty @@ -2786,8 +2784,8 @@ \indextext{bit-field!implementation-defined sign of}% Bit-fields of type plain \keyword{int} are signed. \rationale -Leaving the choice of signedness to implementations could lead to -inconsistent definitions of template specializations. For consistency, +The signedness needs to be consistent among template specializations. +For consistency, the implementation freedom was eliminated for non-dependent types, too. \effect diff --git a/source/exceptions.tex b/source/exceptions.tex index a4c30a2b45..15b2896a22 100644 --- a/source/exceptions.tex +++ b/source/exceptions.tex @@ -799,9 +799,7 @@ \end{codeblock} The call to \tcode{f} -is well-formed even though, when called, -\tcode{f} -might throw an exception. +is well-formed despite the possibility for it to throw an exception. \end{example} \pnum From 08c053a61cb60e976a2d930c8a07afd497d49362 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Tue, 6 Sep 2022 22:26:04 +0100 Subject: [PATCH 429/430] [tools/makereport] Tweak vertical whitespace styling, add end tags --- tools/makereport | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/tools/makereport b/tools/makereport index 0fb2e2ec33..2cccd3cad7 100755 --- a/tools/makereport +++ b/tools/makereport @@ -2,9 +2,11 @@ readonly paper="${1%.md}" -(cat < - + + + \n$(echo -n "${paper}" | tr prn PRN)\n\n" markdown "${1}" + +echo -e "\n" ) > "${paper}.html" From dea00c73010f88b7afed9f3543dbdd4b49b89a9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Fri, 26 Aug 2022 17:37:02 +0100 Subject: [PATCH 430/430] Update configuration for new working draft N4917 and add corresponding Editors' Report N4918 --- papers/n4918.html | 2007 ++++++++++++++++++++++++++++++++++++++++++++ papers/n4918.md | 1874 +++++++++++++++++++++++++++++++++++++++++ papers/wd-index.md | 1 + source/config.tex | 2 +- 4 files changed, 3883 insertions(+), 1 deletion(-) create mode 100644 papers/n4918.html create mode 100644 papers/n4918.md diff --git a/papers/n4918.html b/papers/n4918.html new file mode 100644 index 0000000000..a21471cc39 --- /dev/null +++ b/papers/n4918.html @@ -0,0 +1,2007 @@ + + + + + +N4918 + + +

N4918 Editors’ Report:
Programming Languages — C++

+ +

Date: 2022-09-06

+ +

Thomas Köppe (editor, Google DeepMind)
+Jens Maurer (co-editor)
+Dawn Perchik (co-editor, Bright Side Computing, LLC)
+Richard Smith (co-editor, Google Inc)

+ +

Email: cxxeditor@gmail.com

+ +

Acknowledgements

+ +

Thanks to all those who have submitted editorial +issues +and to those who have provided pull requests with fixes, and special thanks to +Johel Ernesto Guerrero Peña for providing in-depth review of most of the draft +motion applications, and to Hewill Kang for spotting and sending corrections for +many editorial issues.

+ +

New papers

+ +
    +
  • N4917 is the +current working draft for C++23. It replaces +N4910.
  • +
  • N4918 is this Editors' Report.
  • +
  • N4919 is the C++23 Committee Draft.
  • +
+ +

Motions incorporated into working draft

+ +

Core working group polls

+ +

CWG poll 1: Accept as Defect Reports all issues except 2507 and 2586 in +P2622R0 +(Core Language Working Group "ready" Issues for the July, 2022 meeting) and +apply their proposed resolutions to the C++ Working Paper.

+ +

CWG poll 2: Apply the proposed resolution of issues 2507 and 2586 in +P2622R0 +(Core Language Working Group "ready" Issues for the July, 2022 meeting) to the +C++ Working Paper.

+ +

CWG poll 3: Accept as a Defect Report and apply the changes in +P2468R2 +(The Equality Operator You Are Looking For) to the C++ Working Paper.

+ +

CWG poll 4: Accept as a Defect Report and apply the changes in +P2327R1 +(De-deprecating volatile compound operations) to the C++ Working Paper.

+ +

CWG poll 5: Apply the changes in +P2437R1 +(Support for #warning) to the C++ Working Paper.

+ +

CWG poll 6: Apply the changes in +P2362R3 +(Remove non-encodable wide character literals and multicharacter wide character +literals) to the C++ Working Paper.

+ +

CWG poll 7: Apply the changes in +P2324R2 +(Labels at the end of compound statements (C compatibility)) to the C++ Working +Paper.

+ +

CWG poll 8: Apply the changes in +P2290R3 +(Delimited escape sequences) to the C++ Working Paper.

+ +

CWG poll 9: Apply the changes in +P2448R2 +(Relaxing some constexpr restrictions) to the C++ Working Paper.

+ +

CWG poll 10: Apply the changes in +P2266R3 +(Simpler implicit move) to the C++ Working Paper.

+ +

CWG poll 11: Apply the changes in +P2071R2 +(Named universal character escapes) to the C++ Working Paper.

+ +

CWG poll 12: Apply the changes in +P1169R4 +(static operator()) to the C++ Working Paper.

+ +

CWG poll 13: Accept as a Defect Report and apply the changes in +P2280R4 +(Using unknown pointers and references in constant expressions) to the C++ +Working Paper.

+ +

CWG poll 14: Apply the changes in +P1467R9 +(Extended floating-point types and standard names) to the C++ Working Paper.

+ +

CWG poll 15: Accept as a Defect Report +P2493R0 +(Missing feature test macros for C++20 core papers). (The paper was already +adopted at the February, 2022 meeting, and no changes to the Working Paper +result from it now.)

+ +

CWG poll 16: Apply the changes in +P2582R1 +(Wording for class template argument deduction from inherited constructors) to +the C++ Working Paper.

+ +

CWG poll 17: Apply the changes in +P1774R8 +(Portable assumptions) to the C++ Working Paper.

+ +

CWG poll 18: Apply the changes in +P2295R6 +(Support for UTF-8 as a portable source file encoding) to the C++ Working Paper.

+ +

CWG poll 19: Accept as a Defect Report and apply the changes in +P2513R3 +(char8_t Compatibility and Portability Fix) to the C++ Working Paper.

+ +

CWG poll 20: Accept as a Defect Report and apply the changes in +P2460R2 +(Relax requirements on wchar_t to match existing practices) to the C++ Working +Paper.

+ +

CWG poll 21: Accept as a Defect Report and apply the changes in +P2579R0 +(Mitigation strategies for P2036 "Changing scope for lambda +trailing-return-type") to the C++ Working Paper.

+ +

Library working group polls

+ +

LWG poll 1: Apply the changes for all Ready issues in +P2618R0 (C++ +Standard Library Issues to be moved in Virtual Plenary, Jul. 2022) to the C++ +working paper.

+ +

LWG poll 2: Apply the changes in +P0009R18 +(MDSPAN) to the C++ working paper.

+ +

LWG poll 3: Apply the changes in +P2599R2 +(index_type & size_type in mdspan) to the C++ working paper.

+ +

LWG poll 4: Apply the changes in +P2604R0 +(mdspan: rename pointer and contiguous) to the C++ working paper.

+ +

LWG poll 5: Apply the changes in +P2613R1 (Add +the missing empty to mdspan) to the C++ working paper.

+ +

LWG poll 6: Apply the changes in +P0429R9 (A +Standard flat_map) to the C++ working paper.

+ +

LWG poll 7: Apply the changes in +P1222R4 (A +Standard flat_set) to the C++ working paper.

+ +

LWG poll 8: Apply the changes in +P1223R5 +(find_last) to the C++ working paper.

+ +

LWG poll 9: Apply the changes in +P1642R11 +(Freestanding Library: Easy [utilities], [ranges], and [iterators]) to the C++ +working paper.

+ +

LWG poll 10: Apply the changes in +P1899R3 +(stride_view) to the C++ working paper.

+ +

LWG poll 11: Apply the changes in +P2093R14 +(Formatted output) to the C++ working paper.

+ +

LWG poll 12: Apply the changes in +P2165R4 +(Compatibility between tuple, pair and tuple-like objects) to the C++ +working paper.

+ +

LWG poll 13: Apply the changes in +P2278R4 +(cbegin should always return a constant iterator) to the C++ working paper.

+ +

LWG poll 14: Apply the changes in +P2286R8 +(Formatting Ranges) to the C++ working paper.

+ +

LWG poll 15: Apply the changes in +P2291R3 (Add +Constexpr Modifiers to Functions to_chars and from_chars for Integral Types +in <charconv> Header) to the C++ working paper.

+ +

LWG poll 16: Apply the changes in +P2302R4 +(std::ranges::contains) to the C++ working paper.

+ +

LWG poll 17: Apply the changes in +P2322R6 +(ranges::fold) to the C++ working paper.

+ +

LWG poll 18: Apply the changes in +P2374R4 +(views::cartesian_product) to the C++ working paper.

+ +

LWG poll 19: Apply the changes in +P2540R1 +(Empty Product for certain Views) to the C++ working paper.

+ +

LWG poll 20: Apply the changes in +P2404R3 +(Move-only types for equality_comparable_with, totally_ordered_with, and +three_way_comparable_with) to the C++ working paper.

+ +

LWG poll 21: Apply the changes in +P2408R5 +(Ranges iterators as inputs to non-Ranges algorithms) to the C++ working paper.

+ +

LWG poll 22: Apply the changes in +P2417R2 (A +more constexpr bitset) to the C++ working paper.

+ +

LWG poll 23: Apply the changes in +P2419R2 +(Clarify handling of encodings in localized formatting of chrono types) to the +C++ working paper.

+ +

LWG poll 24: Apply the changes in +P2438R2 +(std::string::substr() &&) to the C++ working paper.

+ +

LWG poll 25: Apply the changes in +P2446R2 +(views::as_rvalue) to the C++ working paper.

+ +

LWG poll 26: Apply the changes in +P2465R3 +(Standard Library Modules std and std.compat) to the C++ working paper.

+ +

LWG poll 27: Apply the changes in +P2445R1 +(std::forward_like) to the C++ working paper.

+ +

LWG poll 28: Apply the changes in +P2467R1 +(Support exclusive mode for fstreams) to the C++ working paper.

+ +

LWG poll 29: Apply the changes in +P2474R2 +(views::repeat) to the C++ working paper.

+ +

LWG poll 30: Apply the changes in +P2494R2 +(Relaxing range adaptors to allow for move only types) to the C++ working paper.

+ +

LWG poll 31: Apply the changes in +P2499R0 +(string_view range constructor should be explicit) to the C++ working paper.

+ +

LWG poll 32: Apply the changes in +P2502R2 +(std::generator: Synchronous Coroutine Generator for Ranges) to the C++ working +paper.

+ +

LWG poll 33: Apply the changes in +P2508R1 +(Exposing std::basic-format-string<charT, Args...>) +to the C++ working paper.

+ +

LWG poll 34: Apply the changes in +P2517R1 (Add +a conditional noexcept specification to std::apply) to the C++ working paper.

+ +

LWG poll 35: Apply the changes in +P2520R0 +(move_iterator<T*> should be a random access iterator) to the C++ working +paper.

+ +

LWG poll 36: Apply the changes in +P2549R1 +(std::unexpected<E> should have error() as member accessor) to the C++ +working paper.

+ +

LWG poll 37: Apply the changes in +P2585R1 +(Improving default container formatting) to the C++ working paper.

+ +

LWG poll 38: Apply the changes in +P2590R2 +(Explicit lifetime management) to the C++ working paper.

+ +

Editorial changes

+ +

Notes on motions

+ +
    +
  • Poll CWG-9: The wording was based on an old draft, and has been adjusted +to integrate with the current draft: an additional example that was added by +P2242R3 +has also been deleted.

  • +
  • Polls CWG-12 and LWG-1: The wording from issue +LWG-3617 +has been integrated with the wording of, and guided by advice from, +P1169R4.

  • +
  • Poll LWG-2: Several minor changes were made to this long paper +P0009R18, +"mdspan": The expression sizeof...(OtherSizeTypes) was given the name N +in a few places to simplify the presentation; the phrase "for all rank index +r" was changed to "for every rank index r", notes have been reworded to +avoid the modal verb "may".

  • +
  • Polls LWG-8 and LWG-1: The macro ATOMIC_FLAG_INIT from +LWG-3659 +has also been marked "freestanding".

  • +
  • Poll LWG-14: Range formatting is also specified for the new "flat" +container adaptors, as requested by +P2286R8.

  • +
  • Poll LWG-29: Minor errors in +P2474R2 +("views::repeat") have been corrected.

  • +
  • Poll LWG-33: The changes have also been applied to new wording from +LWG-11.

  • +
  • Poll LWG-34: The changes have been integrated with the earlier changes +from LWG-12 +(P2165R4, +"Compatibility between tuple and tuple-like objects").

  • +
  • Polls LWG-14, -23, -33, -37: All four papers ask to update the +__cpp_lib_format feature test macro. This has since been discussed and found +unsatisfactory, but a resolution will only be applied editorially in the next +working draft.

  • +
+ +

Noteworthy editorial changes

+ +
    +
  • We introduced the new term "control-flow-limited statement" in [stmt.label] +to refer to a statement into which one cannot jump from the outside, which is +used for constexpr if, consteval if, and try and catch blocks.

  • +
  • Additional subclauses have been introduced where needed to ensure that there +is only one class synopsis along with its member specifications per subclause, +so as to not be ambiguous. Apart from modifying the current motions, this +affects [vector.bool].

  • +
  • Extraneous subclauses were removed, and their contents flattened, from the +erstwhile [expected.un.object].

  • +
  • Old wording for container adapters that used to say "other kinds of sequence +containers that the user defines" has been replaced with "other program-defined +sequence containers", since we now need this phrase in two places, and the term +"program-defined" was only introduced recently.

  • +
  • Further rewordings have been made to avoid the use of the "might" and "could" +modal verbs in notes.

  • +
+ +

Minor editorial changes

+ +

A log of editorial fixes made to the working draft since N4910 is below. This +list excludes changes that do not affect the body text or only affect whitespace +or typeface. For a complete list including such changes (or for the actual +deltas applied by these changes), consult the draft sources on +github.

+ +
commit fb8135e5ec22acd26cb0dcb1bface21eee118895
+Author: hewillk <67143766+hewillk@users.noreply.github.com>
+Date:   Sun Mar 6 20:22:18 2022 +0800
+
+    [range.utility.conv.general] Add missing template parameter to container-inserter
+
+commit b7c1f9a77eac8dfeb4cb2e92bd3b2a57d05c298a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Mar 25 09:37:42 2022 +0100
+
+    [spanbuf] Fix template name in subclause heading (#5365)
+
+commit cdca862605ae315e2d7a1ca7c7c1b011651944d2
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Mar 25 10:44:58 2022 +0100
+
+    [span.streams] Move non-member swaps to header synopsis (#5366)
+
+commit 478b8f8807e5b4561874842aa24a132558682f00
+Author: A. Jiang <de34@live.cn>
+Date:   Thu Mar 31 19:34:03 2022 +0800
+
+    [alg.min.max] Consistently specify ranges::minmax_element with minmax_element_result (#5376)
+
+    LWG3180 was incompletely applied with commit e33be08f8ca49a9a139aa81b7a1ba9787d85f4fc.
+
+commit c92196bc67e252f06907c6de44173ce7157d71df
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Apr 1 13:38:03 2022 +0200
+
+    [memory.syn] Add missing closing bracket for attribute
+
+commit 1d2d223ab9fee202b67b31b32b85f44e3f9dc187
+Author: hewillk <67143766+hewillk@users.noreply.github.com>
+Date:   Thu Mar 24 02:13:51 2022 +0800
+
+    [range.adjacent.transform.iterator] Fix wrong template parameter in adjacent_transform_view::iterator
+
+commit 4813f202b3e2f6d0062967b9fd96ca54b91c7b65
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Mar 30 08:29:55 2022 +0200
+
+    [stacktrace.syn] Add '#include <compare>'
+
+    LWG3330 added #include <compare> to all header files
+    where a three-way comparison operator was declared,
+    but missed this one.
+
+commit d9040a775aa528f0576453532f3cb5058a6e6f24
+Author: A. Jiang <de34@live.cn>
+Date:   Wed Apr 6 20:03:39 2022 +0800
+
+    [allocator.requirements.general] Specify all member types with typename (#5386)
+
+commit 2bfa7c4cc96203e03763816cf310e54e5b8940bb
+Author: Daniel Krügler <daniel.kruegler@gmail.com>
+Date:   Fri Apr 15 21:26:27 2022 +0200
+
+    [temp.constr.normal] Add missing semicolon in example (#5395)
+
+commit a8dbfc63227bf596dcf72a31c9fef4af8af9e592
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Apr 20 14:41:22 2022 +0100
+
+    [depr.tuple,depr.variant] Use struct class-key consistently (#5402)
+
+commit 4fc805d949bfc99ee6cfcf666123eb982fc4c465
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Apr 21 09:27:57 2022 +0200
+
+    [expr.prim.lambda.general] Clarify deduced lambda return type
+
+commit 5fb0fd092782f57e8395841470c92176412a10a3
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Mar 24 09:29:07 2022 +0000
+
+    [expected.un.object.general] Reorder constructors in synopsis
+
+    This matches the order in [expected.un.ctor].
+
+commit 8e7a9b9fbf2f7a7dfa913a77068b6a6d3488e521
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Mar 24 09:36:55 2022 +0000
+
+    [expected.un.object] Remove unnecessary subclause nesting
+
+    All the other class templates in <expected> are at the rSec3 level, but
+    std::unexpected is below a mostly useless rSec3 [expected.unexpected].
+    This subclause has two children, [expected.un.general] which is a single
+    sentence, and [expected.un.object] which defines the class template and
+    its members. If we merge the single sentence from [expected.un.general]
+    into the same subclause as the class synopsis then we can get remove the
+    unnecessary nesting. As a nice side effect, this also gets rid of
+    "object" in the [expected.un.object] stable name, which doesn't really
+    make sense in context.
+
+commit 3372ed0572fd8aa59ed9e59432cd8f593868be49
+Author: Casey Carter <Casey@Carter.net>
+Date:   Mon Apr 25 13:24:24 2022 -0700
+
+    [range.utility.conv.general] Strike extraneous semicolon (#5414)
+
+commit 4b7deb009c4dfbbe8f2c879f764be446f94957b2
+Author: xmh0511 <970252187@qq.com>
+Date:   Tue Apr 26 04:26:19 2022 +0800
+
+    [lex.ccon] Fix typo in character name for U+0027 (#5412)
+
+commit 93de6031da2ef99b402e18ee8941fd6c7b554ce4
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Apr 26 14:14:02 2022 +0200
+
+    [string.view.deduct] Move to immediately after [string.view.cons] (#5397)
+
+commit 41bc0c2ab38c32638685ef9a5068e06abbfc07f3
+Author: hewillk <67143766+hewillk@users.noreply.github.com>
+Date:   Tue Apr 26 20:16:26 2022 +0800
+
+    [expected] Add missing noexcept for expected::error() (#5381)
+
+commit b075835f134e4956fe27eaa5323655137aff3d45
+Author: Hui <65944694+huixie90@users.noreply.github.com>
+Date:   Tue Apr 26 18:56:30 2022 +0100
+
+    [iterator.concept.readable] Remove obsolete note (#5408)
+
+    The note was obsoleted by P1878R1.
+
+commit eed51157b2011478eb40254fbf191f2dd5fca7ca
+Author: hewillk <67143766+hewillk@users.noreply.github.com>
+Date:   Tue May 3 15:26:39 2022 +0800
+
+    [expected.object.general] Remove explicit keyword for copy/move constructors (#5380)
+
+commit d23b318949c0a74c6f93f50afb1375ba9eb7aefd
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed May 4 00:50:55 2022 +0100
+
+    [stringbuf.virtuals] add "override" to setbuf
+
+commit fbe06e9076db0116e395e969f4cb921e45ae964a
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed May 4 00:51:45 2022 +0100
+
+    [adjacent.difference] fix grammar typo
+
+commit bb8729f3cba593b963031bb25a1a4f12e12ad4fb
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed May 4 00:52:40 2022 +0100
+
+    [streambuf.virt.get] fix grammar typo
+
+commit 6fa045bf939eeff4dcea56e1a84ab7e1aac69f78
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed May 4 01:12:12 2022 +0100
+
+    [thread.lock.unique.cons] Use nullptr for null pointer constant
+
+commit f6791f7f9346c007921fec0b406a9edcbf667951
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed May 4 11:55:03 2022 +0200
+
+    [syncstream.osyncstream.cons] Fix use of parameter name (#5445)
+
+commit 74ad79739e2a13022bc6a33ff2e32efe59a47578
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed May 4 11:55:45 2022 +0200
+
+    [thread.sema.cnt] Add missing parentheses on function call expression (#5443)
+
+commit 8147026d04fe8fb44ed439cea950b5dab136c04c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed May 4 11:56:14 2022 +0200
+
+    [cons.slice] Add copy constructor for 'slice' to synopsis (#5444)
+
+commit fb379c19180d1e26b2b8146d547bcc84c59a0da5
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed May 4 11:56:50 2022 +0200
+
+    [over.match.best.general] Fix typo in example (#5446)
+
+commit 81e506da21960bc70c271f775673a311ec957f6b
+Author: Casey Carter <Casey@Carter.net>
+Date:   Wed May 4 02:59:27 2022 -0700
+
+    [ranges.syn] remove trailing `-> see below` return type from three `to` overloads (#5419)
+
+    Since there is actually no return type specification to see below in [range.utility.conv].
+
+commit 11d886b5c6062ec7291469514eb07424811e4f65
+Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com>
+Date:   Tue Apr 26 17:39:39 2022 +0300
+
+    [class.access] Remove dangling Note
+
+    Invalidated by P1847R4
+
+commit 5032e88247bafb5c44dcd4d8ac2ffe3f8bff1bd9
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Apr 23 22:15:46 2022 +0200
+
+    [associative] Add "i.e." in front of explanation
+
+commit 445d18255713e183df2819e565aa5faa7f85bb1d
+Author: hewillk <67143766+hewillk@users.noreply.github.com>
+Date:   Fri Apr 1 22:46:44 2022 +0800
+
+    [range.utility.conv.general] Add missing constexpr for container-inserter
+
+commit 64969e2057ef55b7ac3db8e23c37547edff5c8cf
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu May 5 13:14:25 2022 +0200
+
+    [intro.memory] Fix missing semicolon in example
+
+commit dcf0f144f72e8116c59c188c5057a6ca8a7615d3
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu May 5 13:35:33 2022 +0200
+
+    [intro.progress] Fix grammar typo
+
+commit 8c743eacc4b8609650d690b774f855507bd0846f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu May 5 13:41:54 2022 +0200
+
+    [expr.prim.lambda.general] Fix missing capture-default in example
+
+commit 359b8f41027c970bbbc63f1319a890adaa338f6f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu May 5 16:59:35 2022 +0200
+
+    [expr.await] Fix English grammar in string-literal in example
+
+commit 117b352d584cac601c22c63328355658271a6f17
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu May 5 17:05:50 2022 +0200
+
+    [expr.xor] Fix grammar typo
+
+commit 980aded4060cb408c053b0ee4620a71f3b6b73c6
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu May 5 17:06:01 2022 +0200
+
+    [expr.or] Fix grammar typo
+
+commit edb43d00ec4f5e98d45c03408b5d0be6b0484c27
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu May 5 17:09:06 2022 +0200
+
+    [expr.yield] Fix typos in examples
+
+commit 451d8b95bd4c04bf89a5915eb973f837873c432b
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu May 5 17:20:11 2022 +0200
+
+    [dcl.fct.default] Fix grammar typo in comment in example
+
+commit cd2690e9ace12f901acce1c1e9157f5cbbf06b24
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu May 5 17:21:32 2022 +0200
+
+    [dcl.init.aggr] Fix grammar typo in example
+
+commit cbc1a36376f32e9d31d5276ba44d8237d0632c37
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu May 5 17:24:29 2022 +0200
+
+    [dcl.fct.def.coroutine] Fix grammar typo
+
+commit d7be2ebee9dd3df849cf87bed768f9bb9f8684f8
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu May 5 17:27:11 2022 +0200
+
+    [class.copy.ctor] Fix grammar typo
+
+commit 4284e8c31673912ae92bc210bb39aa4b05f0ed86
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu May 5 17:31:25 2022 +0200
+
+    [class.expl.init] Fix grammar typo
+
+commit 6c0d1411779d9e2c3e9a59d10b09605b6e5f1482
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu May 5 17:35:00 2022 +0200
+
+    [class.base.init] Fix grammar typo in note
+
+commit 40483ba8cff2165cd81dd75718559037af3ecaa8
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu May 5 22:43:03 2022 +0200
+
+    [over.match.class.deduct] Fix syntax error in example
+
+commit 04cb8da6485b09592008c82eb330125fbf1034cd
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu May 5 23:15:42 2022 +0200
+
+    [temp.decls.general] Fix missing comma
+
+commit e6633adbb2f3a6590cd75a000b377c8736c65094
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri May 6 00:17:50 2022 +0200
+
+    [temp.deduct.type] Fix grammar typo
+
+commit 1386c5b2cf41b713a12f526077eb578b68bacb9b
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri May 6 00:19:23 2022 +0200
+
+    [temp.over] Fix grammar typos
+
+commit 21dc6d863a5acb0c3e5ec008bddb1c02b3dcd29a
+Author: hewillk <67143766+hewillk@users.noreply.github.com>
+Date:   Thu May 19 11:23:47 2022 +0800
+
+    [range.join.view] Simplify range_reference_t<V> to InnerRng
+
+    I think this is a reasonable simplification and also makes it consistent with join_with_view.
+
+commit 2101d81b42bfcb7ab2227617a5ebe86e0b5733e8
+Author: Casey Carter <Casey@Carter.net>
+Date:   Mon May 23 04:39:15 2022 -0700
+
+    [expected.object.ctor] Use the injected-class-name to refer to the current instantiation (#5485)
+
+    ... as is conventional in library wording.
+
+commit 31be778d39b144fe867e24d80481786ad012661e
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Sun May 29 04:51:06 2022 +0800
+
+    [ranges] Remove redundant "exposition only" comments in \itemdecl (#5499)
+
+commit aff22aca63d0fb4b183cf073de8abfd4b9bb22bd
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Fri Jun 10 00:24:11 2022 +0800
+
+    [range.istream.view] Add reference for basic_istream_view::iterator (#5514)
+
+commit 10a20b22491f1ff39a47847a68c9e4a648754d10
+Author: Mathias Stearn <redbeard0531@gmail.com>
+Date:   Thu Jun 9 18:52:42 2022 +0200
+
+    [res.on.functions] Use regular "behavior is undefined" words of power (#5513)
+
+commit 4bfa5ddf04586b6df76e0f44e4cde8b59f4a0401
+Author: Casey Carter <Casey@Carter.net>
+Date:   Thu Jun 9 09:56:29 2022 -0700
+
+    [range.istream.iterator] basic_istream_view::iterator is not a class template (#5515)
+
+commit f73087971183d1daa992ad5165946609a77d39ff
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jun 12 16:18:19 2022 +0200
+
+    [func.wrap.move.ctor] Fix typo naming template parameter packs (#5517)
+
+commit 8d3f43888013437a2870877f00f017860b083df4
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Sat Jun 11 17:34:09 2022 -0400
+
+    [range.adjacent.iterator] Use correct descriptive element
+
+commit d86e1ef9ef8514e570fdbbc5038f71e272dbb008
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Sun Jun 12 03:11:07 2022 +0800
+
+    [ranges.syn] Fix the constraints order of slide_view
+
+commit c4a46fb7343c591f8844c2615ec25cfe8021656a
+Author: hewillk <67143766+hewillk@users.noreply.github.com>
+Date:   Sat May 21 20:39:59 2022 +0800
+
+    [move.iter.cons] Add missing Returns
+
+commit 45498df90fa8fa6ffb4de7341c65a2924de9879c
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Thu Jun 16 04:57:27 2022 +0800
+
+    [range.join.with.sentinel] Add missing curly brace (#5530)
+
+commit d78d53f96d076f66a8af4ca7e71ae48e1d0596be
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jun 16 13:52:29 2022 +0200
+
+    [allocator.adaptor.syn] Fix typo in comment in header synopsis
+
+commit 01f16bc99a6a89e69b7a6ec5ae8bfe307ec5299a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jun 16 17:33:52 2022 +0200
+
+    [functional.syn,func.search.default] Fix name of template parameter
+
+commit 0678f9986b2c1f75e55d596f63876979433522d4
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jun 16 17:43:07 2022 +0200
+
+    [meta.rel] Add parentheses for consistency
+
+    Parentheses are used for is_pointer_interconvertible_base_of.
+
+commit c8a496c62d973305cd6eb5a23d80f169062335fc
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jun 16 17:51:57 2022 +0200
+
+    [string.view.general] Add missing template-argument-list
+
+commit 70d07925ad874144f2dae4359f5a17c6cada1cdb
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jun 16 17:55:30 2022 +0200
+
+    [forward.list.modifiers] Fix misspelled parameter name
+
+commit 66fd28de5c730a271bcf631f8452048c0e709232
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jun 16 17:56:48 2022 +0200
+
+    [set.cons] Fix grammar typo
+
+commit de6b0e70ffe2da0a0f91ce434863202f78c9e029
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jun 16 18:00:21 2022 +0200
+
+    [unord.map.overview] Fix presentation of member types
+
+commit 5be153e248d9e741c841ff3ab6c2e3714ecba24b
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 17 08:14:19 2022 +0200
+
+    [unord.set.overview] Fix presentation of member types
+
+commit 633178f3fd48a784a96a6610f6b12c10700603c0
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 17 08:15:22 2022 +0200
+
+    [unord.multiset.overview] Fix presentation of member types
+
+commit 5ae534c0c522cf661d3e94c58f54c7d37cf7905a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 17 08:18:34 2022 +0200
+
+    [random.access.iterators] Add semicolon at end of statement
+
+commit f60caf420b5210f0ad284999a1e471d50c424856
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 17 08:21:11 2022 +0200
+
+    [range.req.general] Fix grammar typo
+
+commit 75436ee3dd005cf13153ee05c9174a3a3df0054d
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 17 08:32:31 2022 +0200
+
+    [range.take.view] Replace 'struct' with 'class' for consistency
+
+commit 8738cac27de2d66addf735f4fc2b370b73bb9ecc
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 17 08:33:59 2022 +0200
+
+    [range.take.while.overview] Highlight use of ranges::begin
+
+commit 51cad172464c89cc14fff19d87d6bba6bc68f61d
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 17 08:38:54 2022 +0200
+
+    [algorithms.requirements] Add commas for readability
+
+commit 5096e87c6c882ae2aff40c3558db7c2ec95ff4a8
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 17 08:39:08 2022 +0200
+
+    [algorithms.requirements] Add hyphen for non-copied
+
+commit 63f3e4030497e43f39ff89ec0171f89a11dfc0a7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 17 08:41:53 2022 +0200
+
+    [alg.equal] Add missing period
+
+commit 736c755c70be70d5fb75e71f2c212c3c633ddc34
+Author: Casey Carter <Casey@Carter.net>
+Date:   Thu Jun 23 14:26:40 2022 -0700
+
+    [priqueue.overview] Add misssing `>` to deduction guide (#5535)
+
+commit 3bf6ac52ddd619ae925d32ebb68a90a5bec0c115
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 24 15:50:30 2022 +0200
+
+    [class.prop] Clarify definition of implicit-lifetime class (#5319)
+
+commit 314fa9e2c16bcdaba33febddf2992b3e26c02212
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Wed Jul 13 01:54:20 2022 +0800
+
+    [sequence.reqmts] Add ranges namespace qualifier for range concepts (#5563)
+
+commit 433b7af41ef02b8656c3153ab6ebb1c1c616f5b3
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Wed Jul 13 23:40:21 2022 +0800
+
+    [range.take.overview] Fix punctuation (#5564)
+
+commit f6cb84439e8094ec7c67c708d1cc0ddef59262ec
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Tue Jul 26 23:09:38 2022 +0800
+
+    [ranges.syn] Add \ref for `ref_view` (#5652)
+
+commit c816ae797e36daa466c287f3eff445aa87d8bfeb
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Fri Jul 29 03:11:43 2022 +0800
+
+    [istreambuf.iterator.general] Add \ref for proxy (#5669)
+
+commit d59a4f3392fd1cf87af4ba128518fb4c00cbf77c
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Fri Jul 29 03:13:33 2022 +0800
+
+    [algorithm.syn,bitset.syn,rand.synopsis,valarray.syn] Add \ref for header (#5666)
+
+commit 78b91e849b270423ec3296f7f95666078531e032
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Sat Jul 30 05:13:40 2022 +0800
+
+    [range.join.with.overview,range.split.overview] use qualified name in examples (#5683)
+
+commit e24445344d26e3d9a3ad92b939b8c034daa47eb4
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Aug 14 20:53:03 2022 +0100
+
+    [mdspan.*] Replace remaining "pointer"s with "data_handle_type".
+
+    These edits are part of LWG Motion 4 (P2604R0) but were accidentally omitted.
+
+commit 762480c9317759ffd6db76f7fef27744776e081d
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Aug 17 11:41:51 2022 +0100
+
+    [ranges] Remove now-unused exposition-only "tuple-or-pair".
+
+    Also fix one missed replacement of "tuple-or-pair" with "tuple" as
+    instructed by LWG-Motion 12 (P2165R4, "tuple-like objects").
+
+commit b832e2702df41ebe79ddd9d159ac71e68e9b772a
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Aug 14 22:26:15 2022 +0100
+
+    [container.reqmnts] Remove stray `{}`
+
+commit f09e7c5164d6dbc43e4a160aa4676725a83f488d
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Aug 17 15:03:41 2022 +0100
+
+    [expr.spaceship, fs.path.generic, temp.inst] Use em-dash for parentheticals, not en-dash.
+
+    We are using em-dashes elsewhere already.
+
+commit 5dd17bf20e46a2964131ec208b6ed31cc659c400
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Aug 17 23:18:35 2022 +0100
+
+    [ranges] Add missing requirement on itemdecl, and fix spacing
+
+commit bb1145f751e2de491873aac5a42faf0a6931c218
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Aug 12 12:03:55 2022 +0100
+
+    [mdspan.{overview,extents.ctor}] Increase reuse of definitions
+
+commit e97f917d3fd39d7fb2421105d8e45cb73bd24a1e
+Author: Eelis van der Weegen <eelis@eelis.net>
+Date:   Thu Aug 18 18:42:15 2022 +0200
+
+    [range.zip.transform.view] Fix typo: mmove_constructible.
+
+commit f440cfa4e3ebf139b5acec3735e90d4acf5785e6
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Aug 18 15:25:55 2022 +0100
+
+    [ranges.syn] Add missing "freestanding" comment for as_rvalue.
+
+commit 999005ab72ca0078b3361979584007dd9d991fac
+Author: Yihe Li <winmikedows@hotmail.com>
+Date:   Fri Aug 5 08:49:10 2022 +0800
+
+    [strings.general] Add <string> header to "String classes" row
+
+commit 1fbf5f8b683802849cfc8bb57fef3f48a61bd242
+Author: Yihe Li <winmikedows@hotmail.com>
+Date:   Fri Aug 5 08:49:40 2022 +0800
+
+    [thread.general] Remove non-existent header
+
+commit 0d7d1d70641a773f67b08f4de44e53f00e3b352d
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 24 15:40:43 2022 +0200
+
+    [temp.inst] Clarify referent of 'declaration'
+
+commit 99bc532e3c9440defd761985d2329da064b7f9f9
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jun 23 23:17:13 2022 +0200
+
+    [module.private.frag] Remove misleading example and broaden note
+
+commit 596137c054407d4d5f2ccf327bd5d3e2a8b4fef5
+Author: A. Jiang <de34@live.cn>
+Date:   Tue May 17 09:49:27 2022 +0800
+
+    [mem.poly.allocator.class.general] Clarify polymorphic_allocator<void> etc.
+
+commit 193cfc17cbb73e7e6c65d1e596ef9c1a035c7811
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Nov 5 19:58:41 2021 +0100
+
+    [diff.dcl] Discuss 'alignas' placement restrictions
+
+commit 8b2d70502c379b96ddb9d6eb97d5aafcc1d4765c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Nov 5 20:00:00 2021 +0100
+
+    [diff.dcl] Remove 'implicit int' discussion
+
+    C99 has removed implicit int.
+
+commit f91c425a8fe6f0dd826bd399a5bc82796aec8180
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Mar 4 21:20:21 2022 +0100
+
+    [diff.expr] Remove 'implicit function declaration' discussion
+
+    C99 has removed implicit function declarations.
+
+commit b208eb4da5a97cf800f2822318fd487f332d82ad
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Feb 22 06:22:04 2019 +0000
+
+    [meta.trans.other] Use "denotes" in decay, enable_if and conditional
+
+commit 769e15bd0559a8ff572d2c508f2cce0227229a39
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Feb 22 07:04:02 2019 +0000
+
+    [meta.unary.prop.query] Use "is an array type" not "names an array type"
+
+commit 3d010460fc4159b6f99d430a3cf0eb0ff30d0053
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Feb 22 07:05:09 2019 +0000
+
+    [meta.trans.ref] Use "is a referenceable type" and "denotes the type"
+
+commit 66cb97967adb501ff352b6e69815b4db10e095bf
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Feb 22 07:06:14 2019 +0000
+
+    [meta.trans.sign] Use "is a ... type" and "denotes the type"
+
+commit 485192fb3872c1da42d6cc0ff89230ecb7760c9c
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Feb 22 07:06:46 2019 +0000
+
+    [meta.trans.arr] Use "is a type" not "names a type"
+
+    Also use "denotes" instead of "names" for member typedefs.
+
+commit e2d032255ad0f346144659ba43d3eb184163c8bb
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Feb 22 07:07:15 2019 +0000
+
+    [meta.trans.ptr] Use "is a referenceable type" not "names ..."
+
+commit 2c9482a15375291528e8742dc7972450c9597d96
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Feb 22 07:09:00 2019 +0000
+
+    [meta.trans.other] Use "denotes"
+
+commit c51087e82583b589481f03d4dad2190a569ce857
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Feb 22 07:16:14 2019 +0000
+
+    [meta.trans.cv] use "denotes" in specification of member typedefs
+
+commit 935ec9e8f13d41bc09f8a27a917008ddf2724a29
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue Apr 23 10:33:16 2019 +0100
+
+    [refwrap.unwrapref] Use "denotes" for member typedef
+
+commit e412ba9b687e4cdd8ed7546b3ec44122b6baabc5
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Apr 22 18:20:59 2022 +0100
+
+    [depr.meta.types] use "denotes" for member typedefs
+
+commit 887c0330bdd2e4b504854a5c9d34621e5d10a3d2
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Nov 27 21:27:28 2018 +0100
+
+    [cmp.categories] Replace 'operator admits' phrasing.
+
+commit 1e3e4180ee26e06abe6eeb648537b36baa92c5b7
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Fri Aug 19 01:33:25 2022 +0800
+
+    [range.as.const.view] Add missing angle bracket (#5745)
+
+commit d732538953bab8ccdbe4388cfb39b8542a01dc65
+Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
+Date:   Thu Jul 21 10:09:09 2022 -0400
+
+    [map.cons,multimap.cons,multiset.cons,set.cons,associative.reqmts.general] "sorted with respect to `comp`"
+
+    https://cplusplus.github.io/LWG/issue3713
+    LWG3713 points out that we temporarily lost the term of art
+    "sorted with respect to `comp`," and brings back a definition
+    for it. However, several places in the existing draft never
+    actually used that term of art in the first place. Fix them
+    up so that they do.
+
+commit 4db1d62426ef9a9cd8689585d43da38dd3731696
+Author: A. Jiang <de34@live.cn>
+Date:   Fri Aug 19 01:36:40 2022 +0800
+
+    [allocator.requirements.general] Use newer style for SimpleAllocator
+
+commit a458849089b29e3dfc5f9736799c1c6403223f8f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jun 12 16:11:08 2022 +0200
+
+    [thread.lock.unique.locking] Fix function call expressions
+
+commit dd4ecf3d19bf8a04899324fc72c690880a328a64
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri May 13 21:51:13 2022 +0200
+
+    [stacktrace.basic.nonmem] Add missing \pnum before \recommended
+
+    Also augment check script
+
+commit fe24762404f5ac7bbd6f139a44dbfa42663ec796
+Author: Barry Revzin <barry.revzin@gmail.com>
+Date:   Thu Aug 18 16:03:10 2022 -0500
+
+    [stmt.pre] List "compound-statement" explicitly as part of a selection statement
+
+    This clarifies the substatements of `if consteval` (which has a compound-statement).
+
+commit 2940703c7ee125ce8194f668683ff5b0bbd7791b
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jan 2 21:46:02 2022 +0100
+
+    [core] Replace 'enumerated type' with 'enumeration'
+
+    The term "enumerated type" is defined in [enumerated.types]
+    for use in the standard library, and is not synonymous with
+    "enumeration type".
+
+commit a27e5a6ac3a0fc9cb8474b87b92734a923d495c0
+Author: Hubert Tong <hubert-reinterpretcast@users.noreply.github.com>
+Date:   Fri Aug 19 10:36:20 2022 -0400
+
+    [stmt.label, except.pre] Use new wording "control-flow-limited" statement (#5413)
+
+    A new term of art (control-flow-limited statement) is introduced in [stmt.label]
+    to express the restrictions on control flow into a statement (namely jumping to labels).
+    Both [stmt.if] and [except.pre] are updated to use the new term.
+
+    This rewords "shall not be used to" avoiding question of actual "use": the "shall not be
+    used to" phrasing may be taken to refer only in cases where the actual use occurs
+    or is the primary intent. Instead, the intended restriction can be written in terms
+    of static properties of the constructs so restricted in the style of [stmt.if].
+
+commit 5aa000973bba1ce10ce0f4ca6a3bec61bcea2061
+Author: Jason Merrill <jason@redhat.com>
+Date:   Fri Aug 19 10:47:42 2022 -0400
+
+    [lex.charset] Add missing hyphens
+
+    In P2071R2 and NameAliases.txt, 0+008E is named SINGLE-SHIFT-2, but it went
+    into the draft as "single shift-2", losing the hyphen between the words.
+
+commit 8275c19b3fa9e7cb09f84049ebd6207aceb7ca80
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Aug 19 17:29:40 2022 +0100
+
+    [range.cartesian.view] Fix definition of cartesian-product-is-common
+
+    The original wording seems to have been a copy-paste error.
+
+commit 4117a1fc1aeb307d6b15c8aba8a54925fb1b4faf
+Author: Mark de Wever <koraq@xs4all.nl>
+Date:   Fri Aug 19 18:37:58 2022 +0200
+
+    [format.string.escaped] Fix invalid examples
+
+    While implementing new features introduced by P2286R8 Formatting Ranges
+    I noticed some issues in the examples. These issues are in the paper
+    too.
+
+    For s3 the alternative would be to adjust the output instead of the
+    input.
+
+commit 2d548b2ec835510685cf2fcb175f7645aa798d72
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Aug 19 09:35:25 2022 +0100
+
+    [dcl.fct.def.default] Elaborate on the difference of two declarations
+
+    This makes it clear that T_1 and T_2 may differ because of the present
+    rule for the purposes of the blanket statement "other than as allowed
+    by the preceding rules" futher below.
+
+commit d2ad0017c5584825fce1cbf741c160e4bd6108b3
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Sun Aug 21 01:22:25 2022 +0800
+
+    [range.chunk.overview,range.slide.overview] Use maths, not code style for N/M (#5500)
+
+commit 1277923e3ac7a35a3713823b5782b57b86f956ed
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Sun Aug 21 01:35:35 2022 +0800
+
+    [range.chunk] Fix subclause headings (#5516)
+
+commit 2f228c5cad223a5c8d686d91b054ee3bd2d2a123
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Sun Aug 21 05:01:17 2022 +0800
+
+    [range.as.rvalue.view] Fix accidentally swapped concepts in template head
+
+    Also fixes the whitespace style around the opening brace.
+
+commit 22133b42b1a20d542a8f4d18cc425e8c875e567b
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Aug 20 22:04:26 2022 +0100
+
+    [complex.members] Remove stray "template<class T>" from constructor
+
+    This peculiar presentation had previously worked in conjuction with
+    a subclause on "explicit specializations", but since those explicit
+    specializations have been removed by P1467R9, the template head does
+    not serve any useful purpose any longer.
+
+commit fee56834fb55355d617a88fe764f9fb20d92c329
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Aug 20 22:35:28 2022 +0100
+
+    [expr.prim.lambda.capture] Add cross reference to [basic.scope.lambda]
+
+    Suggested by CD review feedback.
+
+commit 6f70f82eead9ddc10830aedb99286d0db54725ad
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Mon Aug 22 02:11:57 2022 +0800
+
+    [range.repeat.view] Fix typo (#5765)
+
+commit 89df45a30a48f30d2ab367490b47c2c0a87f4aa6
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Mon Aug 22 01:51:41 2022 +0800
+
+    [ranges.cartesian.iterator] Fix typo
+
+commit 35aa22acdf080fc5886d715a965aadd36de28c27
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Aug 21 01:55:27 2022 +0100
+
+    [expr.prim.id.unqual] Fix parameter name in example ("y", not "z")
+
+    The misspelling was a misapplication of the motion paper P2579R0.
+
+    Also harmonize the local use of whitespace.
+
+commit 2841712fc15f831481d7bd39e084c213596ccfec
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Aug 20 23:49:21 2022 +0100
+
+    [vector.syn, vector.bool] Add subclause structure.
+
+    After the addition of the formatting-related specialization, the
+    original subclause contained several class template synopses without
+    any intervening separation. The header synopsis is rearranged to
+    follow the document order.
+
+commit 259b8d5d1beeaccf793783679ff4956e84774ea4
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Aug 22 00:03:46 2022 +0100
+
+    [alg.sorting.general] Make "comp" part of the defined term
+
+    Suggested by CD review feedback.
+
+commit c2aee77b6413fe8ce09bf816d1e239fa2b93f4a9
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Aug 22 00:14:49 2022 +0100
+
+    [mdspan.overview] Extend the definition to "size of a MD index space"
+
+    Previously, only "size" was the defined term, but P0009R18 asks for
+    the entire phrase to be the defined term.
+
+    Suggested by CD review feedback.
+
+commit ac27094ee2f367faf32a37008f476d57b19fd999
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Aug 22 00:29:15 2022 +0100
+
+    [mdspan.extents.expo] Add "exposition-only" comments to itemdecls
+
+    Suggested by CD review feedback.
+
+commit cce4e845272506ad2e0d732d78bce1dcfd02b7c7
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Aug 22 00:34:32 2022 +0100
+
+    [mdspan.extents.ctor] Consistently use "r" as a maths variable, not code.
+
+    Suggested by CD review feedback.
+
+commit a284ab6c16f387f95adb85e02ad9c07cf36b08a3
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Aug 22 00:43:14 2022 +0100
+
+    [mdspan.layout.{reqmts,right.ctor}] Consistently use maths, not code
+
+    Suggested by CD review feedback.
+
+commit 62d024620d93fc08611ce9e931fef95c9e064d03
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Aug 22 00:52:22 2022 +0100
+
+    [mdspan.accessor.reqmts] Replace "pointer" with "data_handle_type".
+
+    This edit was part of LWG Motion 4 (P2604R0) but was accidentally omitted.
+
+commit 9369f4c7f116244193c7c2ed12ecc4a625790776
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Aug 22 00:56:57 2022 +0100
+
+    [mdspan.layout.stride.expo] Replace "SizeType" with "IndexType".
+
+    This edit was part of LWG Motion 3 (P2599R2) but was accidentally omitted.
+
+commit fd7c919c681630425a48fd01b4c36c631c910303
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Aug 22 01:01:14 2022 +0100
+
+    [mdspan.layout.stride.{ctor,obs}] Add cross references to [mdspan.layout.policy.reqmts]
+
+    Suggested by CD review feedback.
+
+commit d0c287b45c5b7ec1d5cfffed2eeeed2e2682ed3b
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Aug 22 09:59:57 2022 +0100
+
+    [flat.multi*] Fix typo ("mutli" => "multi")
+
+commit 06cbf011ea876313132b51f3699b23f942f91123
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Aug 22 10:13:01 2022 +0100
+
+    [containers] Add cross references to "erasure" subclauses
+
+    In associative containers, the comment in the synopsis is augmented
+    with the name of the class template, since each header contains two
+    class templates (unique and multi).
+
+    Also fixes some index entry spellings.
+
+commit 3b1461021cb81fbbccd27494ecd60de7daf958b8
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Mon Aug 22 17:56:54 2022 +0800
+
+    [range.adaptor.tuple] Fix tuple helper parameter name clash (#5769)
+
+    The code as presented originally was ill-formed.
+
+commit 90c2cfb1fb8e5cb4781a2d8affdc8856279ca09a
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Mon Aug 22 09:32:17 2022 +0800
+
+    [range.repeat.iterator] repeat_view::iterator is not a class template
+
+commit 4762e1b6fa3bcaf4fdc080e2160ab4e9e96f77b6
+Author: A. Jiang <de34@live.cn>
+Date:   Mon Aug 22 15:32:10 2022 +0800
+
+    Fix preconditions for start_lifetime_as_array(p, n)
+
+    "n > 0 is true" can't be in "Mandates:", and it's in "Preconditions:" according to P2590R2.
+
+commit 28f49c965a394c573fa927792f082a182d422029
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Mon Aug 22 19:29:40 2022 +0800
+
+    [range.as.const.view] Fix order of constraints in class synopsis (#5760)
+
+    The header and the class synopses used different orderings in P2446R0,
+    and the ordering from the header synopsis is the desired one.
+
+commit 03d73772246ec6e9fa0becb983be6dc08189d8b1
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Aug 22 12:23:51 2022 +0100
+
+    [flat.*] Harmonize wording "supports the ... operations but not ..."
+
+commit 9934675dd673bfa8e073bd3c2187575b47e6ea44
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Aug 22 13:48:45 2022 +0100
+
+    [flat.set.defn] Fix name of function parameter ("rg", not "range")
+
+commit faa173c296bfc3547e6f20af63329ac0e1a024be
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Aug 22 14:06:39 2022 +0100
+
+    [flat.multiset.ctor] Add missing parameter name "cont"
+
+commit 96fce7b5259e1bfe1688cc60df2d6b2ecf3e7cd1
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Aug 22 11:49:41 2022 +0100
+
+    [flat.*.{syn,erasure}] Change return type of erase_if to member size_type
+
+    All other containers and container adapters use the member size_type,
+    and the flat maps already did so in the item specification, but not in
+    the synopsis.
+
+    The current wording follows the approved proposals, but this change
+    seems like an improvement.
+
+    Suggested by CD review feedback.
+
+commit 7f11031bf6e41515a8779bdbfe741f4f9bbdfccc
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Aug 20 21:14:55 2022 +0100
+
+    [diff] Uniform style for examples
+
+    For C++ differences, examples are always preceded by the phrase "For
+    example:", do not use the usual [Example n: ... -- end example] style,
+    and always appear in the "Effects on original feature" paragraph.
+
+    For differences with C, a different set of styles is used (examples
+    being part of paragraphs such as "Change" and "Rationale"), and that
+    subclause remains unchanged by this commit.
+
+commit d4280f38ddd489aecd8fb0da17a41f577db42e2a
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Aug 20 23:11:39 2022 +0100
+
+    [memory.syn] Add missing "// freestanding" comment to "destroy"
+
+    The comment was supposed to be added by P1642R11, but was accidentally
+    omitted.
+
+commit 47b0e73cc1e8d2ea344afedf60e07ec80df118f4
+Author: mordante <koraq@xs4all.nl>
+Date:   Mon Aug 22 17:48:36 2022 +0200
+
+    [format.string.std] Reorder std-format-spec field descriptions. (#5246)
+
+    Moves the wording describing the zero-padding before the description of
+    the width; matching the order of the fields in the std-format-spec.
+
+    The original order was introduced in the initial <format> paper P0645R10 "Text Formatting".
+    Since both fields had one paragraph of description, it wasn't too noticeable. P1868R2 "🦄 width:
+    clarifying units of width and precision in std::format" expanded the wording of the width.
+    Now it's not so easy to find the description of the zero-padding field.
+
+commit 517290b26fa8391d3b77d43ca8c271bb92695db7
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Aug 22 17:06:34 2022 +0100
+
+    [range.cartesian.view] Further fixing of cartesian-product-is-common
+
+    The first fix in 8275c19b3fa9e7cb09f84049ebd6207aceb7ca80 was
+    incorrect. Only Const needs to be dropped (which was an error
+    in the paper), but ignoring Vs... is intentional.
+
+commit 101e7205882495cec1a944c7f6190b08bd131543
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Aug 22 17:23:46 2022 +0100
+
+    [ranges] Add missing closing delimiters
+
+commit 17be256d2431f66842479bf7ab2e92f30fff3060
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Jun 18 21:39:06 2022 +0200
+
+    [alg.partitions] Indicate base of logarithm outside big-oh notation
+
+commit c6e83c4dba380b235be59b21db6c54bdffcb997d
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Jun 18 21:39:59 2022 +0200
+
+    [set.difference] Fix grammar typo
+
+commit 68e365415c707038f8af6c76f0f6f4cd3a4ce407
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Jun 18 21:44:05 2022 +0200
+
+    [uninitialized.move] Fix typos in parameter names
+
+commit c3c6761111cff26e0e742e4d14b5d9e0bd28c4aa
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Jun 18 22:53:51 2022 +0200
+
+    [rand.adapt.disc] Remove superfluous trailing semicolon
+
+commit 65c9e5bcb3068a1172a66a7507d26a93adae7981
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Jun 18 22:55:17 2022 +0200
+
+    [rand.adapt.ibits] Remove superfluous trailing semicolon
+
+commit 6ede23707505a18cdbb558108d635a0b21a1eeb0
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Jun 18 22:55:47 2022 +0200
+
+    [rand.adapt.shuf] Remove superfluous trailing semicolon
+
+commit 5e44bc70b72b64e03e0d09564b2eaf45938a7752
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Jun 18 22:58:11 2022 +0200
+
+    [valarray.members] Fix bad reference to argument
+
+commit 43b2bce231b04c1ccf7dc4bfd20e13f29c0e9c6c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jun 19 21:29:54 2022 +0200
+
+    [time.duration.io] Fix grammar typo
+
+commit 6e9b678f03a1a4fa8218152596a1952c209d1f27
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jun 19 21:32:40 2022 +0200
+
+    [time.cal.year.members] Fix erroneous qualified-id
+
+commit f0ab64a1dcb5bac1249ff67e838a7f899efeb586
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jun 19 21:39:48 2022 +0200
+
+    [locale.codecvt.general] Remove extra space before template-argument-list
+
+commit bbb7552af35266accf98ae718912579527ee11b8
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jun 19 21:41:58 2022 +0200
+
+    [locale.collate.general] Fix grammar typo
+
+commit 324dfd448ec5b632fc922015414cd206920b5842
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jun 19 21:45:29 2022 +0200
+
+    [ios.base.storage] Fix grammar typo
+
+commit fc53c9ede41d4992dc64f556bc32febb28ad0e1e
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jun 19 21:45:58 2022 +0200
+
+    [fpos] Fix typo in exposition-only member
+
+commit 47273ceb655716f62fc1c9fe00a317b44c221267
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jun 19 21:47:05 2022 +0200
+
+    [fpos.operations] Fix name of type trait
+
+commit 04d7e61e9deaf2481d144e2c0a7d2478cff58764
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jun 19 21:49:00 2022 +0200
+
+    [streambuf.cons] Fix grammar typo
+
+commit f055ba09397bd479317a92c315e5a074f7c2e474
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Apr 17 11:19:04 2022 +0200
+
+    [atomics.syn] Move namespace-scope memory_order_* variables here
+
+commit f400d80927fd580f99f5f2d94c3d07eaa47373d0
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Apr 17 11:23:54 2022 +0200
+
+    [ranges.syn] Move namespace-scope declarations for get(subrange) here
+
+commit e9434db227e8b3113a477dcdd0c6c14ffe2c14b8
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Aug 22 18:56:41 2022 +0100
+
+    [tuple.creation] Add missing semi-colon to example
+
+commit 25bb0a278e8141613f2c813c50a74428e3da7b8b
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Aug 22 18:58:39 2022 +0100
+
+    [util.smartptr.shared.obs], [util.smartptr.shared.create] use nullptr for null pointer constant
+
+commit 7a4324c21e4f66af801bc7e7fc78b94119253301
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Aug 22 21:52:22 2022 +0100
+
+    [char.traits.require] use nullptr for null pointer constant
+
+commit b3b64b35ce456a7e54476b9a00185323b68fcd6d
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Aug 22 22:01:22 2022 +0100
+
+    [unord.req.general] Use "constant" not "const"
+
+commit a421a3029418651b9734ae786c9b89b72b08b42d
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Aug 22 22:09:00 2022 +0100
+
+    [unord.multimap.overview] Fix presentation of member types
+
+    As already done in de6b0e70ffe2da0a0f91ce434863202f78c9e029 for unordered_map.
+
+commit a758844278a818fd8ccbd33a6ca0460b31616d74
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Aug 22 22:33:04 2022 +0100
+
+    [range.elements.view] fix class-key for iterator and sentinel
+
+commit 44b146eda750e453ee3d52587c2accab4be6c74d
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Aug 22 22:35:18 2022 +0100
+
+    [range.elements.iterator] remove stray semi-colon
+
+commit 3a51f3e858e14abc0623f8823e0d2c883c27a4e4
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Aug 22 22:45:30 2022 +0100
+
+    [complex.ops] use character literal for single character
+
+commit 678907e6d8af62cab9429b7065be69c36ffa2592
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Aug 22 22:46:43 2022 +0100
+
+    [rand.req.dist] fix grammar typo
+
+commit 698be9d6b09517dc1323ca99fc4bb84ec62fae9e
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Aug 22 22:56:42 2022 +0100
+
+    [cons.slice], [gslice.cons] remove undeclared/undocumented copy constructor signatures
+
+commit 1cda1f9d2ac5d8caa81e793ce3f95364aba1fb6b
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Aug 22 23:01:23 2022 +0100
+
+    [template.mask.array.overview], [template.indirect.array.overview] fix itemdecl typos
+
+commit f3ddcf79a971f488b3acf0e52ca6ea9689af7fd7
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Tue Aug 23 19:58:08 2022 +0800
+
+    [ranges.cartesian.iterator] Fix typo "reference_t" => "range_reference_t" (#5777)
+
+commit 227c3b249f0f52484920400b861717649895e6cc
+Author: cor3ntin <corentinjabot@gmail.com>
+Date:   Tue Aug 23 14:00:44 2022 +0200
+
+    [range.adjacent.overview] Use tuple in example, not pair (#5779)
+
+    adjacent_view always yields tuples, but the example was written as if it yielded a std::pair.
+
+commit c0c0d75402b1dc33f0cba971c898dc2ac7bfaa06
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Tue Aug 23 20:00:49 2022 +0800
+
+    [range.cartesian.view] Add missing angle brackets for cartesian-is-sized-sentinel
+
+commit c777f930668fe23ab287ff765463d3b3731696eb
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Tue Aug 23 21:45:23 2022 +0800
+
+    [range.zip, ranges.cartesian.iterator] Simplify `maybe-const<true, Views>` to `const Views` (#5778)
+
+    The type `maybe-const<Const, Views>` only appears after `Const &&`
+    in these cases, so that only the case where `Const` is `true` matters.
+
+commit eca39f43798d7a58fdd482232c60b6db428b656f
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Wed Aug 24 01:57:58 2022 +0800
+
+    [tuple.syn, tuple.like] Fix template head formatting (#5784)
+
+commit 356fb7ff88b63d956b1109c72c5e3bf424f6ba29
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Wed Aug 24 01:58:17 2022 +0800
+
+    [algorithm.syn] Fix template head formatting (#5786)
+
+commit 6ccb959c7a8c10fc5fa7dd469c64f3c992e7e7ee
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Tue Aug 23 20:10:44 2022 +0800
+
+    [range.zip.overview] Use tuple in example, not pair
+
+commit 8404284d8b7ac6ff2725a33d5e33410d1ea3b470
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Tue Aug 23 23:10:39 2022 +0800
+
+    [range.drop.overview, range.take.overview] Fixed unformatted (void)F, decay-copy(E)
+
+commit 6e2b23594abd64c9ba50934654c68bd174c7ab91
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Wed Aug 24 18:49:21 2022 +0800
+
+    [format.range.fmtstr] Add ranges namespace qualifier (#5788)
+
+    The range concept is named outside of the `ranges` namespace.
+
+commit 301f0cdcb547f54b1d39163550a5869a0c6b073f
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Aug 25 02:28:09 2022 +0100
+
+    [coroutine.syn] Move "all freestanding" comment to the top
+
+commit e38650de03741a87d6c625ce93974946f46f5caa
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Aug 25 02:41:49 2022 +0100
+
+    [tuple.like] Remove extraneous "std::" qualification.
+
+commit 3da6b0e8798681144b676b3b4180301f8f7c8f2c
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Aug 25 10:55:25 2022 +0100
+
+    [const.iterators.{alias,iterators}] Add "exposition only" comments
+
+    Suggested by CD review feedback.
+
+commit 5dd0216a477391fbce339e22f169136420472979
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Aug 25 11:12:24 2022 +0100
+
+    [range.refinements] Fix template argument name ("T", not "R")
+
+commit 347ded018d09d2a226e3ab42665d1a13b25d489a
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Aug 25 11:27:38 2022 +0100
+
+    [vector.bool.pspc] Reinstate redundant "inline", as per paper
+
+    The "inline" was removed editorially in
+    2141dab25c7f6d186d662e0ebe916efcd56843ae, but CD review has requested
+    we retain it.
+
+commit 79ab62930d2538e1ef668c6a1b50e8d7027ebedc
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Aug 25 11:34:57 2022 +0100
+
+    [format.string.escaped] Fix typos in "APOSTROPHE"
+
+commit 426ce8a7ec2232aebaaf76bf2f5e4a69a500cef6
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Thu Aug 25 19:31:57 2022 +0800
+
+    [ranges] Tweak some examples (#5791)
+
+    Removes redundant `std::` qualifications and uses `views::meow` instead of `meow_view`.
+
+commit 4ed7fcf6b725207ac307a6d1411ad2aa4ed55c8f
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Fri Aug 26 04:36:08 2022 +0800
+
+    [containers] Add `std::` for `forward`/`move` (#5793)
+
+commit aec46d1970a8869db0d178c436545b0e40968425
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Fri Aug 26 04:43:03 2022 +0800
+
+    [move.sentinel] Remove extraneous "std" qualification in example (#5792)
+
+commit ed18148b1d514c0aea12d99b1ec3a56d4a834266
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Fri Aug 26 15:00:12 2022 +0800
+
+    [util.smartptr.shared.create] Add std:: qualification for forward
+
+commit eb703517cd6c79f56df12c5dca359121efbef4ee
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Aug 26 14:39:39 2022 +0100
+
+    [range.move.wrap] Fix constraint (move, not copy-constructible)
+
+    This was accidentally omitted from previous changes requested by P2494R2.
+
+commit 2a600822d08332a8350e3a093212bdc7f8a82e2b
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Aug 26 15:06:06 2022 +0100
+
+    [format.range.fmtdef] Add "exposition only" comments
+
+commit 9d71b7d3b0aac1f179fc3973b0ff1624b00b07ce
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Aug 26 15:26:39 2022 +0100
+
+    [obj.lifetime] Add cross-reference pointing at basic.types.general
+
+    Suggested by CD review feedback.
+
+commit 9eb92bf36b19381a534273ad98e296dfeb7a0fc9
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Aug 29 22:45:41 2022 +0200
+
+    [flat.set.modifiers] Remove stray 'return' in Effects clause
+
+commit 69177109f387d3958ffea237c9b0419e4d2aa49c
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Sep 2 23:44:14 2022 +0100
+
+    [expr.ass] Fix typo, "~" should be "^".
+
+    This was a misapplication of P2327R1 in 0aebf5cacded1b64cf089dbc7a0504fbb9f50aa6.
+
+commit e6e17d5e136934f113d6e0a8bde4c227459a9d47
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Sep 3 02:10:27 2022 +0100
+
+    [diff.cpp20.{dcl,expr}] Fix subclause order to match main document
+
+commit 853747c5d8130880b96a39ab940c343aa7530d71
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Sep 3 15:02:00 2022 +0100
+
+    [basic.fundamental] Use correct number; "are", not "is".
+
+commit 07e02a80fe890dcb6e84182a5697046f1bd4c630
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Aug 29 22:23:54 2022 +0200
+
+    [expected.object.assign] Add missing 'Returns: *this'
+
+commit 06dcf0556631382ecdc420c22c66366168c226b4
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Sep 4 13:01:12 2022 +0100
+
+    [mdspan.layout.left.overview] Reorder "explicit" and "constexpr"
+
+    The standard ordering is "constexpr explicit", not the other way
+    round. The paper P0009R18 contains a non-standard style, and other
+    instances had already been fixed. Only this one seems to have been
+    missed previously.
+
+commit e651f145df7c587ea810aca754e680bb27ea8481
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Sep 4 13:08:42 2022 +0100
+
+    [mdspan.layout.{left,right}.overview] Replace "see below" with condition
+
+    The condition is spelled out in the item descriptions already, and the
+    class synopses seem to simply have been inconsistent with that in the
+    incoming paper P0009R18. Since the "see below"s are never referenced
+    explicitly, we just replace them with the actual conditions, which is
+    also how the surrounding members are presented.
+
+commit 1765844a9382e1f3415bbbdcd12eaa09a6b1f827
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Sep 4 13:25:52 2022 +0100
+
+    [mdspan.layout.stride.expo] Move "otherwise" from trailing to leading
+
+    We have a mild preference for the leading position.
+
+commit c02512ecf3f15fb0f29dc602eb153bc7dabd643d
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Sep 4 13:53:01 2022 +0100
+
+    [mdspan.layout.stride.obs] Add missing parentheses
+
+commit 9897c566ec3ecd6f25078a3dd10ce34c17e812e7
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Sep 4 13:54:19 2022 +0100
+
+    [mdspan.accessor.default.members] Fix typo in "equivalent"
+
+commit 3b6163d1a3b1f5cc2be49d6ff0eb6b3889b552df
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Sep 4 13:58:09 2022 +0100
+
+    [flat.map.syn] Add missing "namespace std {"
+
+commit c164add6cdac73cae85649ba2172de43c3d8ed5b
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Sep 4 14:02:11 2022 +0100
+
+    [flat.map.modifiers] Typo: "range" should be "rg"
+
+commit 1b427b20fecbc95b98d2380e0ddae71b71c1f657
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Sep 4 14:06:53 2022 +0100
+
+    [flat.{,multi}set.ctor] Add missing "explicit" in itemdecls
+
+commit 8f153df9c66c33f100ec7a4d7998dfaf6a7aa8da
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Nov 26 02:43:37 2020 +0000
+
+    [basic, except, diff] Rewordings to avoid "might" and "could"
+
+ + diff --git a/papers/n4918.md b/papers/n4918.md new file mode 100644 index 0000000000..550414f120 --- /dev/null +++ b/papers/n4918.md @@ -0,0 +1,1874 @@ +# N4918 Editors' Report -- Programming Languages -- C++ + +Date: 2022-09-06 + +Thomas Köppe (editor, Google DeepMind) +Jens Maurer (co-editor) +Dawn Perchik (co-editor, Bright Side Computing, LLC) +Richard Smith (co-editor, Google Inc) + +Email: `cxxeditor@gmail.com` + +## Acknowledgements + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and to those who have provided pull requests with fixes, and special thanks to +Johel Ernesto Guerrero Peña for providing in-depth review of most of the draft +motion applications, and to Hewill Kang for spotting and sending corrections for +many editorial issues. + +## New papers + + * [N4917](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/n4917.pdf) is the + current working draft for C++23. It replaces + [N4910](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/n4910.pdf). + * N4918 is this Editors' Report. + * N4919 is the C++23 Committee Draft. + +## Motions incorporated into working draft + +### Core working group polls + +CWG poll 1: Accept as Defect Reports all issues except 2507 and 2586 in +[P2622R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2622r0.html) +(Core Language Working Group "ready" Issues for the July, 2022 meeting) and +apply their proposed resolutions to the C++ Working Paper. + +CWG poll 2: Apply the proposed resolution of issues 2507 and 2586 in +[P2622R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2622r0.html) +(Core Language Working Group "ready" Issues for the July, 2022 meeting) to the +C++ Working Paper. + +CWG poll 3: Accept as a Defect Report and apply the changes in +[P2468R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2468r2.html) +(The Equality Operator You Are Looking For) to the C++ Working Paper. + +CWG poll 4: Accept as a Defect Report and apply the changes in +[P2327R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2327r1.pdf) +(De-deprecating volatile compound operations) to the C++ Working Paper. + +CWG poll 5: Apply the changes in +[P2437R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2437r1.pdf) +(Support for `#warning`) to the C++ Working Paper. + +CWG poll 6: Apply the changes in +[P2362R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2362r3.pdf) +(Remove non-encodable wide character literals and multicharacter wide character +literals) to the C++ Working Paper. + +CWG poll 7: Apply the changes in +[P2324R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2324r2.pdf) +(Labels at the end of compound statements (C compatibility)) to the C++ Working +Paper. + +CWG poll 8: Apply the changes in +[P2290R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2290r3.pdf) +(Delimited escape sequences) to the C++ Working Paper. + +CWG poll 9: Apply the changes in +[P2448R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2448r2.html) +(Relaxing some `constexpr` restrictions) to the C++ Working Paper. + +CWG poll 10: Apply the changes in +[P2266R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2266r3.html) +(Simpler implicit move) to the C++ Working Paper. + +CWG poll 11: Apply the changes in +[P2071R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2071r2.html) +(Named universal character escapes) to the C++ Working Paper. + +CWG poll 12: Apply the changes in +[P1169R4](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1169r4.html) +(static `operator()`) to the C++ Working Paper. + +CWG poll 13: Accept as a Defect Report and apply the changes in +[P2280R4](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2280r4.html) +(Using unknown pointers and references in constant expressions) to the C++ +Working Paper. + +CWG poll 14: Apply the changes in +[P1467R9](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1467r9.html) +(Extended floating-point types and standard names) to the C++ Working Paper. + +CWG poll 15: Accept as a Defect Report +[P2493R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2493r0.html) +(Missing feature test macros for C++20 core papers). (The paper was already +adopted at the February, 2022 meeting, and no changes to the Working Paper +result from it now.) + +CWG poll 16: Apply the changes in +[P2582R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2582r1.pdf) +(Wording for class template argument deduction from inherited constructors) to +the C++ Working Paper. + +CWG poll 17: Apply the changes in +[P1774R8](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1774r8.pdf) +(Portable assumptions) to the C++ Working Paper. + +CWG poll 18: Apply the changes in +[P2295R6](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2295r6.pdf) +(Support for UTF-8 as a portable source file encoding) to the C++ Working Paper. + +CWG poll 19: Accept as a Defect Report and apply the changes in +[P2513R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2513r3.html) +(`char8_t` Compatibility and Portability Fix) to the C++ Working Paper. + +CWG poll 20: Accept as a Defect Report and apply the changes in +[P2460R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2460r2.pdf) +(Relax requirements on `wchar_t` to match existing practices) to the C++ Working +Paper. + +CWG poll 21: Accept as a Defect Report and apply the changes in +[P2579R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2579r0.pdf) +(Mitigation strategies for P2036 "Changing scope for lambda +trailing-return-type") to the C++ Working Paper. + +### Library working group polls + +LWG poll 1: Apply the changes for all Ready issues in +[P2618R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2618r0.html) (C++ +Standard Library Issues to be moved in Virtual Plenary, Jul. 2022) to the C++ +working paper. + +LWG poll 2: Apply the changes in +[P0009R18](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p0009r18.html) +(MDSPAN) to the C++ working paper. + +LWG poll 3: Apply the changes in +[P2599R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2599r2.pdf) +(`index_type` & `size_type` in `mdspan`) to the C++ working paper. + +LWG poll 4: Apply the changes in +[P2604R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2604r0.html) +(`mdspan`: rename `pointer` and `contiguous`) to the C++ working paper. + +LWG poll 5: Apply the changes in +[P2613R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2613r1.html) (Add +the missing `empty` to `mdspan`) to the C++ working paper. + +LWG poll 6: Apply the changes in +[P0429R9](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p0429r9.pdf) (A +Standard `flat_map`) to the C++ working paper. + +LWG poll 7: Apply the changes in +[P1222R4](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1222r4.pdf) (A +Standard `flat_set`) to the C++ working paper. + +LWG poll 8: Apply the changes in +[P1223R5](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1223r5.pdf) +(`find_last`) to the C++ working paper. + +LWG poll 9: Apply the changes in +[P1642R11](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1642r11.html) +(Freestanding Library: Easy [utilities], [ranges], and [iterators]) to the C++ +working paper. + +LWG poll 10: Apply the changes in +[P1899R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1899r3.html) +(`stride_view`) to the C++ working paper. + +LWG poll 11: Apply the changes in +[P2093R14](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2093r14.html) +(Formatted output) to the C++ working paper. + +LWG poll 12: Apply the changes in +[P2165R4](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2165r4.pdf) +(Compatibility between `tuple`, `pair` and _tuple-like_ objects) to the C++ +working paper. + +LWG poll 13: Apply the changes in +[P2278R4](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2278r4.html) +(`cbegin` should always return a constant iterator) to the C++ working paper. + +LWG poll 14: Apply the changes in +[P2286R8](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2286r8.html) +(Formatting Ranges) to the C++ working paper. + +LWG poll 15: Apply the changes in +[P2291R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2291r3.pdf) (Add +Constexpr Modifiers to Functions `to_chars` and `from_chars` for Integral Types +in `` Header) to the C++ working paper. + +LWG poll 16: Apply the changes in +[P2302R4](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2302r4.html) +(`std::ranges::contains`) to the C++ working paper. + +LWG poll 17: Apply the changes in +[P2322R6](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2322r6.html) +(`ranges::fold`) to the C++ working paper. + +LWG poll 18: Apply the changes in +[P2374R4](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2374r4.html) +(`views::cartesian_product`) to the C++ working paper. + +LWG poll 19: Apply the changes in +[P2540R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2540r1.html) +(Empty Product for certain Views) to the C++ working paper. + +LWG poll 20: Apply the changes in +[P2404R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2404r3.pdf) +(Move-only types for `equality_comparable_with`, `totally_ordered_with`, and +`three_way_comparable_with`) to the C++ working paper. + +LWG poll 21: Apply the changes in +[P2408R5](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2408r5.html) +(Ranges iterators as inputs to non-Ranges algorithms) to the C++ working paper. + +LWG poll 22: Apply the changes in +[P2417R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2417r2.pdf) (A +more constexpr bitset) to the C++ working paper. + +LWG poll 23: Apply the changes in +[P2419R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2419r2.html) +(Clarify handling of encodings in localized formatting of chrono types) to the +C++ working paper. + +LWG poll 24: Apply the changes in +[P2438R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2438r2.html) +(`std::string::substr() &&`) to the C++ working paper. + +LWG poll 25: Apply the changes in +[P2446R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2446r2.html) +(`views::as_rvalue`) to the C++ working paper. + +LWG poll 26: Apply the changes in +[P2465R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2465r3.pdf) +(Standard Library Modules `std` and `std.compat`) to the C++ working paper. + +LWG poll 27: Apply the changes in +[P2445R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2445r1.pdf) +(`std::forward_like`) to the C++ working paper. + +LWG poll 28: Apply the changes in +[P2467R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2467r1.html) +(Support exclusive mode for fstreams) to the C++ working paper. + +LWG poll 29: Apply the changes in +[P2474R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2474r2.html) +(`views::repeat`) to the C++ working paper. + +LWG poll 30: Apply the changes in +[P2494R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2494r2.html) +(Relaxing range adaptors to allow for move only types) to the C++ working paper. + +LWG poll 31: Apply the changes in +[P2499R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2499r0.html) +(`string_view` range constructor should be `explicit`) to the C++ working paper. + +LWG poll 32: Apply the changes in +[P2502R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2502r2.pdf) +(`std::generator`: Synchronous Coroutine Generator for Ranges) to the C++ working +paper. + +LWG poll 33: Apply the changes in +[P2508R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2508r1.html) +(Exposing std::basic-format-string<charT, Args...>) +to the C++ working paper. + +LWG poll 34: Apply the changes in +[P2517R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2517r1.html) (Add +a conditional `noexcept` specification to `std::apply`) to the C++ working paper. + +LWG poll 35: Apply the changes in +[P2520R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2520r0.html) +(`move_iterator` should be a random access iterator) to the C++ working +paper. + +LWG poll 36: Apply the changes in +[P2549R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2549r1.html) +(`std::unexpected` should have `error()` as member accessor) to the C++ +working paper. + +LWG poll 37: Apply the changes in +[P2585R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2585r1.html) +(Improving default container formatting) to the C++ working paper. + +LWG poll 38: Apply the changes in +[P2590R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2590r2.pdf) +(Explicit lifetime management) to the C++ working paper. + +## Editorial changes + +### Notes on motions + +* **Poll CWG-9:** The wording was based on an old draft, and has been adjusted + to integrate with the current draft: an additional example that was added by + [P2242R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2242r3.html) + has also been deleted. + +* **Polls CWG-12 and LWG-1:** The wording from issue + [LWG-3617](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2618r0.html#3617) + has been integrated with the wording of, and guided by advice from, + [P1169R4](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1169r4.html). + +* **Poll LWG-2:** Several minor changes were made to this long paper + [P0009R18](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p0009r18.html), + "`mdspan`": The expression `sizeof...(OtherSizeTypes)` was given the name `N` + in a few places to simplify the presentation; the phrase "for all rank index + `r`" was changed to "for every rank index `r`", notes have been reworded to + avoid the modal verb "may". + +* **Polls LWG-8 and LWG-1:** The macro `ATOMIC_FLAG_INIT` from + [LWG-3659](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2618r0.html#3659) + has also been marked "freestanding". + +* **Poll LWG-14:** Range formatting is also specified for the new "flat" + container adaptors, as requested by + [P2286R8](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2286r8.html). + +* **Poll LWG-29:** Minor errors in + [P2474R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2474r2.html) + ("`views::repeat`") have been corrected. + +* **Poll LWG-33:** The changes have also been applied to new wording from + LWG-11. + +* **Poll LWG-34:** The changes have been integrated with the earlier changes + from LWG-12 + ([P2165R4](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2165r4.pdf), + "Compatibility between `tuple` and tuple-like objects"). + +* **Polls LWG-14, -23, -33, -37:** All four papers ask to update the + `__cpp_lib_format` feature test macro. This has since been discussed and found + unsatisfactory, but a resolution will only be applied editorially in the next + working draft. + +### Noteworthy editorial changes + +* We introduced the new term "_control-flow-limited_ statement" in [stmt.label] + to refer to a statement into which one cannot jump from the outside, which is + used for constexpr if, consteval if, and try and catch blocks. + +* Additional subclauses have been introduced where needed to ensure that there + is only one class synopsis along with its member specifications per subclause, + so as to not be ambiguous. Apart from modifying the current motions, this + affects [vector.bool]. + +* Extraneous subclauses were removed, and their contents flattened, from the + erstwhile [expected.un.object]. + +* Old wording for container adapters that used to say "other kinds of sequence + containers that the user defines" has been replaced with "other program-defined + sequence containers", since we now need this phrase in two places, and the term + "program-defined" was only introduced recently. + +* Further rewordings have been made to avoid the use of the "might" and "could" + modal verbs in notes. + +### Minor editorial changes + +A log of editorial fixes made to the working draft since N4910 is below. This +list excludes changes that do not affect the body text or only affect whitespace +or typeface. For a complete list including such changes (or for the actual +deltas applied by these changes), consult the [draft sources on +github](https://github.com/cplusplus/draft/compare/n4910...n4917). + + commit fb8135e5ec22acd26cb0dcb1bface21eee118895 + Author: hewillk <67143766+hewillk@users.noreply.github.com> + Date: Sun Mar 6 20:22:18 2022 +0800 + + [range.utility.conv.general] Add missing template parameter to container-inserter + + commit b7c1f9a77eac8dfeb4cb2e92bd3b2a57d05c298a + Author: Jens Maurer + Date: Fri Mar 25 09:37:42 2022 +0100 + + [spanbuf] Fix template name in subclause heading (#5365) + + commit cdca862605ae315e2d7a1ca7c7c1b011651944d2 + Author: Jens Maurer + Date: Fri Mar 25 10:44:58 2022 +0100 + + [span.streams] Move non-member swaps to header synopsis (#5366) + + commit 478b8f8807e5b4561874842aa24a132558682f00 + Author: A. Jiang + Date: Thu Mar 31 19:34:03 2022 +0800 + + [alg.min.max] Consistently specify ranges::minmax_element with minmax_element_result (#5376) + + LWG3180 was incompletely applied with commit e33be08f8ca49a9a139aa81b7a1ba9787d85f4fc. + + commit c92196bc67e252f06907c6de44173ce7157d71df + Author: Jens Maurer + Date: Fri Apr 1 13:38:03 2022 +0200 + + [memory.syn] Add missing closing bracket for attribute + + commit 1d2d223ab9fee202b67b31b32b85f44e3f9dc187 + Author: hewillk <67143766+hewillk@users.noreply.github.com> + Date: Thu Mar 24 02:13:51 2022 +0800 + + [range.adjacent.transform.iterator] Fix wrong template parameter in adjacent_transform_view::iterator + + commit 4813f202b3e2f6d0062967b9fd96ca54b91c7b65 + Author: Jens Maurer + Date: Wed Mar 30 08:29:55 2022 +0200 + + [stacktrace.syn] Add '#include ' + + LWG3330 added #include to all header files + where a three-way comparison operator was declared, + but missed this one. + + commit d9040a775aa528f0576453532f3cb5058a6e6f24 + Author: A. Jiang + Date: Wed Apr 6 20:03:39 2022 +0800 + + [allocator.requirements.general] Specify all member types with typename (#5386) + + commit 2bfa7c4cc96203e03763816cf310e54e5b8940bb + Author: Daniel Krügler + Date: Fri Apr 15 21:26:27 2022 +0200 + + [temp.constr.normal] Add missing semicolon in example (#5395) + + commit a8dbfc63227bf596dcf72a31c9fef4af8af9e592 + Author: Jonathan Wakely + Date: Wed Apr 20 14:41:22 2022 +0100 + + [depr.tuple,depr.variant] Use struct class-key consistently (#5402) + + commit 4fc805d949bfc99ee6cfcf666123eb982fc4c465 + Author: Jens Maurer + Date: Thu Apr 21 09:27:57 2022 +0200 + + [expr.prim.lambda.general] Clarify deduced lambda return type + + commit 5fb0fd092782f57e8395841470c92176412a10a3 + Author: Jonathan Wakely + Date: Thu Mar 24 09:29:07 2022 +0000 + + [expected.un.object.general] Reorder constructors in synopsis + + This matches the order in [expected.un.ctor]. + + commit 8e7a9b9fbf2f7a7dfa913a77068b6a6d3488e521 + Author: Jonathan Wakely + Date: Thu Mar 24 09:36:55 2022 +0000 + + [expected.un.object] Remove unnecessary subclause nesting + + All the other class templates in are at the rSec3 level, but + std::unexpected is below a mostly useless rSec3 [expected.unexpected]. + This subclause has two children, [expected.un.general] which is a single + sentence, and [expected.un.object] which defines the class template and + its members. If we merge the single sentence from [expected.un.general] + into the same subclause as the class synopsis then we can get remove the + unnecessary nesting. As a nice side effect, this also gets rid of + "object" in the [expected.un.object] stable name, which doesn't really + make sense in context. + + commit 3372ed0572fd8aa59ed9e59432cd8f593868be49 + Author: Casey Carter + Date: Mon Apr 25 13:24:24 2022 -0700 + + [range.utility.conv.general] Strike extraneous semicolon (#5414) + + commit 4b7deb009c4dfbbe8f2c879f764be446f94957b2 + Author: xmh0511 <970252187@qq.com> + Date: Tue Apr 26 04:26:19 2022 +0800 + + [lex.ccon] Fix typo in character name for U+0027 (#5412) + + commit 93de6031da2ef99b402e18ee8941fd6c7b554ce4 + Author: Jens Maurer + Date: Tue Apr 26 14:14:02 2022 +0200 + + [string.view.deduct] Move to immediately after [string.view.cons] (#5397) + + commit 41bc0c2ab38c32638685ef9a5068e06abbfc07f3 + Author: hewillk <67143766+hewillk@users.noreply.github.com> + Date: Tue Apr 26 20:16:26 2022 +0800 + + [expected] Add missing noexcept for expected::error() (#5381) + + commit b075835f134e4956fe27eaa5323655137aff3d45 + Author: Hui <65944694+huixie90@users.noreply.github.com> + Date: Tue Apr 26 18:56:30 2022 +0100 + + [iterator.concept.readable] Remove obsolete note (#5408) + + The note was obsoleted by P1878R1. + + commit eed51157b2011478eb40254fbf191f2dd5fca7ca + Author: hewillk <67143766+hewillk@users.noreply.github.com> + Date: Tue May 3 15:26:39 2022 +0800 + + [expected.object.general] Remove explicit keyword for copy/move constructors (#5380) + + commit d23b318949c0a74c6f93f50afb1375ba9eb7aefd + Author: Jonathan Wakely + Date: Wed May 4 00:50:55 2022 +0100 + + [stringbuf.virtuals] add "override" to setbuf + + commit fbe06e9076db0116e395e969f4cb921e45ae964a + Author: Jonathan Wakely + Date: Wed May 4 00:51:45 2022 +0100 + + [adjacent.difference] fix grammar typo + + commit bb8729f3cba593b963031bb25a1a4f12e12ad4fb + Author: Jonathan Wakely + Date: Wed May 4 00:52:40 2022 +0100 + + [streambuf.virt.get] fix grammar typo + + commit 6fa045bf939eeff4dcea56e1a84ab7e1aac69f78 + Author: Jonathan Wakely + Date: Wed May 4 01:12:12 2022 +0100 + + [thread.lock.unique.cons] Use nullptr for null pointer constant + + commit f6791f7f9346c007921fec0b406a9edcbf667951 + Author: Jens Maurer + Date: Wed May 4 11:55:03 2022 +0200 + + [syncstream.osyncstream.cons] Fix use of parameter name (#5445) + + commit 74ad79739e2a13022bc6a33ff2e32efe59a47578 + Author: Jens Maurer + Date: Wed May 4 11:55:45 2022 +0200 + + [thread.sema.cnt] Add missing parentheses on function call expression (#5443) + + commit 8147026d04fe8fb44ed439cea950b5dab136c04c + Author: Jens Maurer + Date: Wed May 4 11:56:14 2022 +0200 + + [cons.slice] Add copy constructor for 'slice' to synopsis (#5444) + + commit fb379c19180d1e26b2b8146d547bcc84c59a0da5 + Author: Jens Maurer + Date: Wed May 4 11:56:50 2022 +0200 + + [over.match.best.general] Fix typo in example (#5446) + + commit 81e506da21960bc70c271f775673a311ec957f6b + Author: Casey Carter + Date: Wed May 4 02:59:27 2022 -0700 + + [ranges.syn] remove trailing `-> see below` return type from three `to` overloads (#5419) + + Since there is actually no return type specification to see below in [range.utility.conv]. + + commit 11d886b5c6062ec7291469514eb07424811e4f65 + Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com> + Date: Tue Apr 26 17:39:39 2022 +0300 + + [class.access] Remove dangling Note + + Invalidated by P1847R4 + + commit 5032e88247bafb5c44dcd4d8ac2ffe3f8bff1bd9 + Author: Jens Maurer + Date: Sat Apr 23 22:15:46 2022 +0200 + + [associative] Add "i.e." in front of explanation + + commit 445d18255713e183df2819e565aa5faa7f85bb1d + Author: hewillk <67143766+hewillk@users.noreply.github.com> + Date: Fri Apr 1 22:46:44 2022 +0800 + + [range.utility.conv.general] Add missing constexpr for container-inserter + + commit 64969e2057ef55b7ac3db8e23c37547edff5c8cf + Author: Jens Maurer + Date: Thu May 5 13:14:25 2022 +0200 + + [intro.memory] Fix missing semicolon in example + + commit dcf0f144f72e8116c59c188c5057a6ca8a7615d3 + Author: Jens Maurer + Date: Thu May 5 13:35:33 2022 +0200 + + [intro.progress] Fix grammar typo + + commit 8c743eacc4b8609650d690b774f855507bd0846f + Author: Jens Maurer + Date: Thu May 5 13:41:54 2022 +0200 + + [expr.prim.lambda.general] Fix missing capture-default in example + + commit 359b8f41027c970bbbc63f1319a890adaa338f6f + Author: Jens Maurer + Date: Thu May 5 16:59:35 2022 +0200 + + [expr.await] Fix English grammar in string-literal in example + + commit 117b352d584cac601c22c63328355658271a6f17 + Author: Jens Maurer + Date: Thu May 5 17:05:50 2022 +0200 + + [expr.xor] Fix grammar typo + + commit 980aded4060cb408c053b0ee4620a71f3b6b73c6 + Author: Jens Maurer + Date: Thu May 5 17:06:01 2022 +0200 + + [expr.or] Fix grammar typo + + commit edb43d00ec4f5e98d45c03408b5d0be6b0484c27 + Author: Jens Maurer + Date: Thu May 5 17:09:06 2022 +0200 + + [expr.yield] Fix typos in examples + + commit 451d8b95bd4c04bf89a5915eb973f837873c432b + Author: Jens Maurer + Date: Thu May 5 17:20:11 2022 +0200 + + [dcl.fct.default] Fix grammar typo in comment in example + + commit cd2690e9ace12f901acce1c1e9157f5cbbf06b24 + Author: Jens Maurer + Date: Thu May 5 17:21:32 2022 +0200 + + [dcl.init.aggr] Fix grammar typo in example + + commit cbc1a36376f32e9d31d5276ba44d8237d0632c37 + Author: Jens Maurer + Date: Thu May 5 17:24:29 2022 +0200 + + [dcl.fct.def.coroutine] Fix grammar typo + + commit d7be2ebee9dd3df849cf87bed768f9bb9f8684f8 + Author: Jens Maurer + Date: Thu May 5 17:27:11 2022 +0200 + + [class.copy.ctor] Fix grammar typo + + commit 4284e8c31673912ae92bc210bb39aa4b05f0ed86 + Author: Jens Maurer + Date: Thu May 5 17:31:25 2022 +0200 + + [class.expl.init] Fix grammar typo + + commit 6c0d1411779d9e2c3e9a59d10b09605b6e5f1482 + Author: Jens Maurer + Date: Thu May 5 17:35:00 2022 +0200 + + [class.base.init] Fix grammar typo in note + + commit 40483ba8cff2165cd81dd75718559037af3ecaa8 + Author: Jens Maurer + Date: Thu May 5 22:43:03 2022 +0200 + + [over.match.class.deduct] Fix syntax error in example + + commit 04cb8da6485b09592008c82eb330125fbf1034cd + Author: Jens Maurer + Date: Thu May 5 23:15:42 2022 +0200 + + [temp.decls.general] Fix missing comma + + commit e6633adbb2f3a6590cd75a000b377c8736c65094 + Author: Jens Maurer + Date: Fri May 6 00:17:50 2022 +0200 + + [temp.deduct.type] Fix grammar typo + + commit 1386c5b2cf41b713a12f526077eb578b68bacb9b + Author: Jens Maurer + Date: Fri May 6 00:19:23 2022 +0200 + + [temp.over] Fix grammar typos + + commit 21dc6d863a5acb0c3e5ec008bddb1c02b3dcd29a + Author: hewillk <67143766+hewillk@users.noreply.github.com> + Date: Thu May 19 11:23:47 2022 +0800 + + [range.join.view] Simplify range_reference_t to InnerRng + + I think this is a reasonable simplification and also makes it consistent with join_with_view. + + commit 2101d81b42bfcb7ab2227617a5ebe86e0b5733e8 + Author: Casey Carter + Date: Mon May 23 04:39:15 2022 -0700 + + [expected.object.ctor] Use the injected-class-name to refer to the current instantiation (#5485) + + ... as is conventional in library wording. + + commit 31be778d39b144fe867e24d80481786ad012661e + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Sun May 29 04:51:06 2022 +0800 + + [ranges] Remove redundant "exposition only" comments in \itemdecl (#5499) + + commit aff22aca63d0fb4b183cf073de8abfd4b9bb22bd + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Fri Jun 10 00:24:11 2022 +0800 + + [range.istream.view] Add reference for basic_istream_view::iterator (#5514) + + commit 10a20b22491f1ff39a47847a68c9e4a648754d10 + Author: Mathias Stearn + Date: Thu Jun 9 18:52:42 2022 +0200 + + [res.on.functions] Use regular "behavior is undefined" words of power (#5513) + + commit 4bfa5ddf04586b6df76e0f44e4cde8b59f4a0401 + Author: Casey Carter + Date: Thu Jun 9 09:56:29 2022 -0700 + + [range.istream.iterator] basic_istream_view::iterator is not a class template (#5515) + + commit f73087971183d1daa992ad5165946609a77d39ff + Author: Jens Maurer + Date: Sun Jun 12 16:18:19 2022 +0200 + + [func.wrap.move.ctor] Fix typo naming template parameter packs (#5517) + + commit 8d3f43888013437a2870877f00f017860b083df4 + Author: Johel Ernesto Guerrero Peña + Date: Sat Jun 11 17:34:09 2022 -0400 + + [range.adjacent.iterator] Use correct descriptive element + + commit d86e1ef9ef8514e570fdbbc5038f71e272dbb008 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Sun Jun 12 03:11:07 2022 +0800 + + [ranges.syn] Fix the constraints order of slide_view + + commit c4a46fb7343c591f8844c2615ec25cfe8021656a + Author: hewillk <67143766+hewillk@users.noreply.github.com> + Date: Sat May 21 20:39:59 2022 +0800 + + [move.iter.cons] Add missing Returns + + commit 45498df90fa8fa6ffb4de7341c65a2924de9879c + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Thu Jun 16 04:57:27 2022 +0800 + + [range.join.with.sentinel] Add missing curly brace (#5530) + + commit d78d53f96d076f66a8af4ca7e71ae48e1d0596be + Author: Jens Maurer + Date: Thu Jun 16 13:52:29 2022 +0200 + + [allocator.adaptor.syn] Fix typo in comment in header synopsis + + commit 01f16bc99a6a89e69b7a6ec5ae8bfe307ec5299a + Author: Jens Maurer + Date: Thu Jun 16 17:33:52 2022 +0200 + + [functional.syn,func.search.default] Fix name of template parameter + + commit 0678f9986b2c1f75e55d596f63876979433522d4 + Author: Jens Maurer + Date: Thu Jun 16 17:43:07 2022 +0200 + + [meta.rel] Add parentheses for consistency + + Parentheses are used for is_pointer_interconvertible_base_of. + + commit c8a496c62d973305cd6eb5a23d80f169062335fc + Author: Jens Maurer + Date: Thu Jun 16 17:51:57 2022 +0200 + + [string.view.general] Add missing template-argument-list + + commit 70d07925ad874144f2dae4359f5a17c6cada1cdb + Author: Jens Maurer + Date: Thu Jun 16 17:55:30 2022 +0200 + + [forward.list.modifiers] Fix misspelled parameter name + + commit 66fd28de5c730a271bcf631f8452048c0e709232 + Author: Jens Maurer + Date: Thu Jun 16 17:56:48 2022 +0200 + + [set.cons] Fix grammar typo + + commit de6b0e70ffe2da0a0f91ce434863202f78c9e029 + Author: Jens Maurer + Date: Thu Jun 16 18:00:21 2022 +0200 + + [unord.map.overview] Fix presentation of member types + + commit 5be153e248d9e741c841ff3ab6c2e3714ecba24b + Author: Jens Maurer + Date: Fri Jun 17 08:14:19 2022 +0200 + + [unord.set.overview] Fix presentation of member types + + commit 633178f3fd48a784a96a6610f6b12c10700603c0 + Author: Jens Maurer + Date: Fri Jun 17 08:15:22 2022 +0200 + + [unord.multiset.overview] Fix presentation of member types + + commit 5ae534c0c522cf661d3e94c58f54c7d37cf7905a + Author: Jens Maurer + Date: Fri Jun 17 08:18:34 2022 +0200 + + [random.access.iterators] Add semicolon at end of statement + + commit f60caf420b5210f0ad284999a1e471d50c424856 + Author: Jens Maurer + Date: Fri Jun 17 08:21:11 2022 +0200 + + [range.req.general] Fix grammar typo + + commit 75436ee3dd005cf13153ee05c9174a3a3df0054d + Author: Jens Maurer + Date: Fri Jun 17 08:32:31 2022 +0200 + + [range.take.view] Replace 'struct' with 'class' for consistency + + commit 8738cac27de2d66addf735f4fc2b370b73bb9ecc + Author: Jens Maurer + Date: Fri Jun 17 08:33:59 2022 +0200 + + [range.take.while.overview] Highlight use of ranges::begin + + commit 51cad172464c89cc14fff19d87d6bba6bc68f61d + Author: Jens Maurer + Date: Fri Jun 17 08:38:54 2022 +0200 + + [algorithms.requirements] Add commas for readability + + commit 5096e87c6c882ae2aff40c3558db7c2ec95ff4a8 + Author: Jens Maurer + Date: Fri Jun 17 08:39:08 2022 +0200 + + [algorithms.requirements] Add hyphen for non-copied + + commit 63f3e4030497e43f39ff89ec0171f89a11dfc0a7 + Author: Jens Maurer + Date: Fri Jun 17 08:41:53 2022 +0200 + + [alg.equal] Add missing period + + commit 736c755c70be70d5fb75e71f2c212c3c633ddc34 + Author: Casey Carter + Date: Thu Jun 23 14:26:40 2022 -0700 + + [priqueue.overview] Add misssing `>` to deduction guide (#5535) + + commit 3bf6ac52ddd619ae925d32ebb68a90a5bec0c115 + Author: Jens Maurer + Date: Fri Jun 24 15:50:30 2022 +0200 + + [class.prop] Clarify definition of implicit-lifetime class (#5319) + + commit 314fa9e2c16bcdaba33febddf2992b3e26c02212 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Wed Jul 13 01:54:20 2022 +0800 + + [sequence.reqmts] Add ranges namespace qualifier for range concepts (#5563) + + commit 433b7af41ef02b8656c3153ab6ebb1c1c616f5b3 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Wed Jul 13 23:40:21 2022 +0800 + + [range.take.overview] Fix punctuation (#5564) + + commit f6cb84439e8094ec7c67c708d1cc0ddef59262ec + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Tue Jul 26 23:09:38 2022 +0800 + + [ranges.syn] Add \ref for `ref_view` (#5652) + + commit c816ae797e36daa466c287f3eff445aa87d8bfeb + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Fri Jul 29 03:11:43 2022 +0800 + + [istreambuf.iterator.general] Add \ref for proxy (#5669) + + commit d59a4f3392fd1cf87af4ba128518fb4c00cbf77c + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Fri Jul 29 03:13:33 2022 +0800 + + [algorithm.syn,bitset.syn,rand.synopsis,valarray.syn] Add \ref for header (#5666) + + commit 78b91e849b270423ec3296f7f95666078531e032 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Sat Jul 30 05:13:40 2022 +0800 + + [range.join.with.overview,range.split.overview] use qualified name in examples (#5683) + + commit e24445344d26e3d9a3ad92b939b8c034daa47eb4 + Author: Thomas Köppe + Date: Sun Aug 14 20:53:03 2022 +0100 + + [mdspan.*] Replace remaining "pointer"s with "data_handle_type". + + These edits are part of LWG Motion 4 (P2604R0) but were accidentally omitted. + + commit 762480c9317759ffd6db76f7fef27744776e081d + Author: Thomas Köppe + Date: Wed Aug 17 11:41:51 2022 +0100 + + [ranges] Remove now-unused exposition-only "tuple-or-pair". + + Also fix one missed replacement of "tuple-or-pair" with "tuple" as + instructed by LWG-Motion 12 (P2165R4, "tuple-like objects"). + + commit b832e2702df41ebe79ddd9d159ac71e68e9b772a + Author: Thomas Köppe + Date: Sun Aug 14 22:26:15 2022 +0100 + + [container.reqmnts] Remove stray `{}` + + commit f09e7c5164d6dbc43e4a160aa4676725a83f488d + Author: Thomas Köppe + Date: Wed Aug 17 15:03:41 2022 +0100 + + [expr.spaceship, fs.path.generic, temp.inst] Use em-dash for parentheticals, not en-dash. + + We are using em-dashes elsewhere already. + + commit 5dd17bf20e46a2964131ec208b6ed31cc659c400 + Author: Thomas Köppe + Date: Wed Aug 17 23:18:35 2022 +0100 + + [ranges] Add missing requirement on itemdecl, and fix spacing + + commit bb1145f751e2de491873aac5a42faf0a6931c218 + Author: Thomas Köppe + Date: Fri Aug 12 12:03:55 2022 +0100 + + [mdspan.{overview,extents.ctor}] Increase reuse of definitions + + commit e97f917d3fd39d7fb2421105d8e45cb73bd24a1e + Author: Eelis van der Weegen + Date: Thu Aug 18 18:42:15 2022 +0200 + + [range.zip.transform.view] Fix typo: mmove_constructible. + + commit f440cfa4e3ebf139b5acec3735e90d4acf5785e6 + Author: Thomas Köppe + Date: Thu Aug 18 15:25:55 2022 +0100 + + [ranges.syn] Add missing "freestanding" comment for as_rvalue. + + commit 999005ab72ca0078b3361979584007dd9d991fac + Author: Yihe Li + Date: Fri Aug 5 08:49:10 2022 +0800 + + [strings.general] Add header to "String classes" row + + commit 1fbf5f8b683802849cfc8bb57fef3f48a61bd242 + Author: Yihe Li + Date: Fri Aug 5 08:49:40 2022 +0800 + + [thread.general] Remove non-existent header + + commit 0d7d1d70641a773f67b08f4de44e53f00e3b352d + Author: Jens Maurer + Date: Fri Jun 24 15:40:43 2022 +0200 + + [temp.inst] Clarify referent of 'declaration' + + commit 99bc532e3c9440defd761985d2329da064b7f9f9 + Author: Jens Maurer + Date: Thu Jun 23 23:17:13 2022 +0200 + + [module.private.frag] Remove misleading example and broaden note + + commit 596137c054407d4d5f2ccf327bd5d3e2a8b4fef5 + Author: A. Jiang + Date: Tue May 17 09:49:27 2022 +0800 + + [mem.poly.allocator.class.general] Clarify polymorphic_allocator etc. + + commit 193cfc17cbb73e7e6c65d1e596ef9c1a035c7811 + Author: Jens Maurer + Date: Fri Nov 5 19:58:41 2021 +0100 + + [diff.dcl] Discuss 'alignas' placement restrictions + + commit 8b2d70502c379b96ddb9d6eb97d5aafcc1d4765c + Author: Jens Maurer + Date: Fri Nov 5 20:00:00 2021 +0100 + + [diff.dcl] Remove 'implicit int' discussion + + C99 has removed implicit int. + + commit f91c425a8fe6f0dd826bd399a5bc82796aec8180 + Author: Jens Maurer + Date: Fri Mar 4 21:20:21 2022 +0100 + + [diff.expr] Remove 'implicit function declaration' discussion + + C99 has removed implicit function declarations. + + commit b208eb4da5a97cf800f2822318fd487f332d82ad + Author: Jonathan Wakely + Date: Fri Feb 22 06:22:04 2019 +0000 + + [meta.trans.other] Use "denotes" in decay, enable_if and conditional + + commit 769e15bd0559a8ff572d2c508f2cce0227229a39 + Author: Jonathan Wakely + Date: Fri Feb 22 07:04:02 2019 +0000 + + [meta.unary.prop.query] Use "is an array type" not "names an array type" + + commit 3d010460fc4159b6f99d430a3cf0eb0ff30d0053 + Author: Jonathan Wakely + Date: Fri Feb 22 07:05:09 2019 +0000 + + [meta.trans.ref] Use "is a referenceable type" and "denotes the type" + + commit 66cb97967adb501ff352b6e69815b4db10e095bf + Author: Jonathan Wakely + Date: Fri Feb 22 07:06:14 2019 +0000 + + [meta.trans.sign] Use "is a ... type" and "denotes the type" + + commit 485192fb3872c1da42d6cc0ff89230ecb7760c9c + Author: Jonathan Wakely + Date: Fri Feb 22 07:06:46 2019 +0000 + + [meta.trans.arr] Use "is a type" not "names a type" + + Also use "denotes" instead of "names" for member typedefs. + + commit e2d032255ad0f346144659ba43d3eb184163c8bb + Author: Jonathan Wakely + Date: Fri Feb 22 07:07:15 2019 +0000 + + [meta.trans.ptr] Use "is a referenceable type" not "names ..." + + commit 2c9482a15375291528e8742dc7972450c9597d96 + Author: Jonathan Wakely + Date: Fri Feb 22 07:09:00 2019 +0000 + + [meta.trans.other] Use "denotes" + + commit c51087e82583b589481f03d4dad2190a569ce857 + Author: Jonathan Wakely + Date: Fri Feb 22 07:16:14 2019 +0000 + + [meta.trans.cv] use "denotes" in specification of member typedefs + + commit 935ec9e8f13d41bc09f8a27a917008ddf2724a29 + Author: Jonathan Wakely + Date: Tue Apr 23 10:33:16 2019 +0100 + + [refwrap.unwrapref] Use "denotes" for member typedef + + commit e412ba9b687e4cdd8ed7546b3ec44122b6baabc5 + Author: Jonathan Wakely + Date: Fri Apr 22 18:20:59 2022 +0100 + + [depr.meta.types] use "denotes" for member typedefs + + commit 887c0330bdd2e4b504854a5c9d34621e5d10a3d2 + Author: Jens Maurer + Date: Tue Nov 27 21:27:28 2018 +0100 + + [cmp.categories] Replace 'operator admits' phrasing. + + commit 1e3e4180ee26e06abe6eeb648537b36baa92c5b7 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Fri Aug 19 01:33:25 2022 +0800 + + [range.as.const.view] Add missing angle bracket (#5745) + + commit d732538953bab8ccdbe4388cfb39b8542a01dc65 + Author: Arthur O'Dwyer + Date: Thu Jul 21 10:09:09 2022 -0400 + + [map.cons,multimap.cons,multiset.cons,set.cons,associative.reqmts.general] "sorted with respect to `comp`" + + https://cplusplus.github.io/LWG/issue3713 + LWG3713 points out that we temporarily lost the term of art + "sorted with respect to `comp`," and brings back a definition + for it. However, several places in the existing draft never + actually used that term of art in the first place. Fix them + up so that they do. + + commit 4db1d62426ef9a9cd8689585d43da38dd3731696 + Author: A. Jiang + Date: Fri Aug 19 01:36:40 2022 +0800 + + [allocator.requirements.general] Use newer style for SimpleAllocator + + commit a458849089b29e3dfc5f9736799c1c6403223f8f + Author: Jens Maurer + Date: Sun Jun 12 16:11:08 2022 +0200 + + [thread.lock.unique.locking] Fix function call expressions + + commit dd4ecf3d19bf8a04899324fc72c690880a328a64 + Author: Jens Maurer + Date: Fri May 13 21:51:13 2022 +0200 + + [stacktrace.basic.nonmem] Add missing \pnum before \recommended + + Also augment check script + + commit fe24762404f5ac7bbd6f139a44dbfa42663ec796 + Author: Barry Revzin + Date: Thu Aug 18 16:03:10 2022 -0500 + + [stmt.pre] List "compound-statement" explicitly as part of a selection statement + + This clarifies the substatements of `if consteval` (which has a compound-statement). + + commit 2940703c7ee125ce8194f668683ff5b0bbd7791b + Author: Jens Maurer + Date: Sun Jan 2 21:46:02 2022 +0100 + + [core] Replace 'enumerated type' with 'enumeration' + + The term "enumerated type" is defined in [enumerated.types] + for use in the standard library, and is not synonymous with + "enumeration type". + + commit a27e5a6ac3a0fc9cb8474b87b92734a923d495c0 + Author: Hubert Tong + Date: Fri Aug 19 10:36:20 2022 -0400 + + [stmt.label, except.pre] Use new wording "control-flow-limited" statement (#5413) + + A new term of art (control-flow-limited statement) is introduced in [stmt.label] + to express the restrictions on control flow into a statement (namely jumping to labels). + Both [stmt.if] and [except.pre] are updated to use the new term. + + This rewords "shall not be used to" avoiding question of actual "use": the "shall not be + used to" phrasing may be taken to refer only in cases where the actual use occurs + or is the primary intent. Instead, the intended restriction can be written in terms + of static properties of the constructs so restricted in the style of [stmt.if]. + + commit 5aa000973bba1ce10ce0f4ca6a3bec61bcea2061 + Author: Jason Merrill + Date: Fri Aug 19 10:47:42 2022 -0400 + + [lex.charset] Add missing hyphens + + In P2071R2 and NameAliases.txt, 0+008E is named SINGLE-SHIFT-2, but it went + into the draft as "single shift-2", losing the hyphen between the words. + + commit 8275c19b3fa9e7cb09f84049ebd6207aceb7ca80 + Author: Thomas Köppe + Date: Fri Aug 19 17:29:40 2022 +0100 + + [range.cartesian.view] Fix definition of cartesian-product-is-common + + The original wording seems to have been a copy-paste error. + + commit 4117a1fc1aeb307d6b15c8aba8a54925fb1b4faf + Author: Mark de Wever + Date: Fri Aug 19 18:37:58 2022 +0200 + + [format.string.escaped] Fix invalid examples + + While implementing new features introduced by P2286R8 Formatting Ranges + I noticed some issues in the examples. These issues are in the paper + too. + + For s3 the alternative would be to adjust the output instead of the + input. + + commit 2d548b2ec835510685cf2fcb175f7645aa798d72 + Author: Thomas Köppe + Date: Fri Aug 19 09:35:25 2022 +0100 + + [dcl.fct.def.default] Elaborate on the difference of two declarations + + This makes it clear that T_1 and T_2 may differ because of the present + rule for the purposes of the blanket statement "other than as allowed + by the preceding rules" futher below. + + commit d2ad0017c5584825fce1cbf741c160e4bd6108b3 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Sun Aug 21 01:22:25 2022 +0800 + + [range.chunk.overview,range.slide.overview] Use maths, not code style for N/M (#5500) + + commit 1277923e3ac7a35a3713823b5782b57b86f956ed + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Sun Aug 21 01:35:35 2022 +0800 + + [range.chunk] Fix subclause headings (#5516) + + commit 2f228c5cad223a5c8d686d91b054ee3bd2d2a123 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Sun Aug 21 05:01:17 2022 +0800 + + [range.as.rvalue.view] Fix accidentally swapped concepts in template head + + Also fixes the whitespace style around the opening brace. + + commit 22133b42b1a20d542a8f4d18cc425e8c875e567b + Author: Thomas Köppe + Date: Sat Aug 20 22:04:26 2022 +0100 + + [complex.members] Remove stray "template" from constructor + + This peculiar presentation had previously worked in conjuction with + a subclause on "explicit specializations", but since those explicit + specializations have been removed by P1467R9, the template head does + not serve any useful purpose any longer. + + commit fee56834fb55355d617a88fe764f9fb20d92c329 + Author: Thomas Köppe + Date: Sat Aug 20 22:35:28 2022 +0100 + + [expr.prim.lambda.capture] Add cross reference to [basic.scope.lambda] + + Suggested by CD review feedback. + + commit 6f70f82eead9ddc10830aedb99286d0db54725ad + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Mon Aug 22 02:11:57 2022 +0800 + + [range.repeat.view] Fix typo (#5765) + + commit 89df45a30a48f30d2ab367490b47c2c0a87f4aa6 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Mon Aug 22 01:51:41 2022 +0800 + + [ranges.cartesian.iterator] Fix typo + + commit 35aa22acdf080fc5886d715a965aadd36de28c27 + Author: Thomas Köppe + Date: Sun Aug 21 01:55:27 2022 +0100 + + [expr.prim.id.unqual] Fix parameter name in example ("y", not "z") + + The misspelling was a misapplication of the motion paper P2579R0. + + Also harmonize the local use of whitespace. + + commit 2841712fc15f831481d7bd39e084c213596ccfec + Author: Thomas Köppe + Date: Sat Aug 20 23:49:21 2022 +0100 + + [vector.syn, vector.bool] Add subclause structure. + + After the addition of the formatting-related specialization, the + original subclause contained several class template synopses without + any intervening separation. The header synopsis is rearranged to + follow the document order. + + commit 259b8d5d1beeaccf793783679ff4956e84774ea4 + Author: Thomas Köppe + Date: Mon Aug 22 00:03:46 2022 +0100 + + [alg.sorting.general] Make "comp" part of the defined term + + Suggested by CD review feedback. + + commit c2aee77b6413fe8ce09bf816d1e239fa2b93f4a9 + Author: Thomas Köppe + Date: Mon Aug 22 00:14:49 2022 +0100 + + [mdspan.overview] Extend the definition to "size of a MD index space" + + Previously, only "size" was the defined term, but P0009R18 asks for + the entire phrase to be the defined term. + + Suggested by CD review feedback. + + commit ac27094ee2f367faf32a37008f476d57b19fd999 + Author: Thomas Köppe + Date: Mon Aug 22 00:29:15 2022 +0100 + + [mdspan.extents.expo] Add "exposition-only" comments to itemdecls + + Suggested by CD review feedback. + + commit cce4e845272506ad2e0d732d78bce1dcfd02b7c7 + Author: Thomas Köppe + Date: Mon Aug 22 00:34:32 2022 +0100 + + [mdspan.extents.ctor] Consistently use "r" as a maths variable, not code. + + Suggested by CD review feedback. + + commit a284ab6c16f387f95adb85e02ad9c07cf36b08a3 + Author: Thomas Köppe + Date: Mon Aug 22 00:43:14 2022 +0100 + + [mdspan.layout.{reqmts,right.ctor}] Consistently use maths, not code + + Suggested by CD review feedback. + + commit 62d024620d93fc08611ce9e931fef95c9e064d03 + Author: Thomas Köppe + Date: Mon Aug 22 00:52:22 2022 +0100 + + [mdspan.accessor.reqmts] Replace "pointer" with "data_handle_type". + + This edit was part of LWG Motion 4 (P2604R0) but was accidentally omitted. + + commit 9369f4c7f116244193c7c2ed12ecc4a625790776 + Author: Thomas Köppe + Date: Mon Aug 22 00:56:57 2022 +0100 + + [mdspan.layout.stride.expo] Replace "SizeType" with "IndexType". + + This edit was part of LWG Motion 3 (P2599R2) but was accidentally omitted. + + commit fd7c919c681630425a48fd01b4c36c631c910303 + Author: Thomas Köppe + Date: Mon Aug 22 01:01:14 2022 +0100 + + [mdspan.layout.stride.{ctor,obs}] Add cross references to [mdspan.layout.policy.reqmts] + + Suggested by CD review feedback. + + commit d0c287b45c5b7ec1d5cfffed2eeeed2e2682ed3b + Author: Thomas Köppe + Date: Mon Aug 22 09:59:57 2022 +0100 + + [flat.multi*] Fix typo ("mutli" => "multi") + + commit 06cbf011ea876313132b51f3699b23f942f91123 + Author: Thomas Köppe + Date: Mon Aug 22 10:13:01 2022 +0100 + + [containers] Add cross references to "erasure" subclauses + + In associative containers, the comment in the synopsis is augmented + with the name of the class template, since each header contains two + class templates (unique and multi). + + Also fixes some index entry spellings. + + commit 3b1461021cb81fbbccd27494ecd60de7daf958b8 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Mon Aug 22 17:56:54 2022 +0800 + + [range.adaptor.tuple] Fix tuple helper parameter name clash (#5769) + + The code as presented originally was ill-formed. + + commit 90c2cfb1fb8e5cb4781a2d8affdc8856279ca09a + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Mon Aug 22 09:32:17 2022 +0800 + + [range.repeat.iterator] repeat_view::iterator is not a class template + + commit 4762e1b6fa3bcaf4fdc080e2160ab4e9e96f77b6 + Author: A. Jiang + Date: Mon Aug 22 15:32:10 2022 +0800 + + Fix preconditions for start_lifetime_as_array(p, n) + + "n > 0 is true" can't be in "Mandates:", and it's in "Preconditions:" according to P2590R2. + + commit 28f49c965a394c573fa927792f082a182d422029 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Mon Aug 22 19:29:40 2022 +0800 + + [range.as.const.view] Fix order of constraints in class synopsis (#5760) + + The header and the class synopses used different orderings in P2446R0, + and the ordering from the header synopsis is the desired one. + + commit 03d73772246ec6e9fa0becb983be6dc08189d8b1 + Author: Thomas Köppe + Date: Mon Aug 22 12:23:51 2022 +0100 + + [flat.*] Harmonize wording "supports the ... operations but not ..." + + commit 9934675dd673bfa8e073bd3c2187575b47e6ea44 + Author: Thomas Köppe + Date: Mon Aug 22 13:48:45 2022 +0100 + + [flat.set.defn] Fix name of function parameter ("rg", not "range") + + commit faa173c296bfc3547e6f20af63329ac0e1a024be + Author: Thomas Köppe + Date: Mon Aug 22 14:06:39 2022 +0100 + + [flat.multiset.ctor] Add missing parameter name "cont" + + commit 96fce7b5259e1bfe1688cc60df2d6b2ecf3e7cd1 + Author: Thomas Köppe + Date: Mon Aug 22 11:49:41 2022 +0100 + + [flat.*.{syn,erasure}] Change return type of erase_if to member size_type + + All other containers and container adapters use the member size_type, + and the flat maps already did so in the item specification, but not in + the synopsis. + + The current wording follows the approved proposals, but this change + seems like an improvement. + + Suggested by CD review feedback. + + commit 7f11031bf6e41515a8779bdbfe741f4f9bbdfccc + Author: Thomas Köppe + Date: Sat Aug 20 21:14:55 2022 +0100 + + [diff] Uniform style for examples + + For C++ differences, examples are always preceded by the phrase "For + example:", do not use the usual [Example n: ... -- end example] style, + and always appear in the "Effects on original feature" paragraph. + + For differences with C, a different set of styles is used (examples + being part of paragraphs such as "Change" and "Rationale"), and that + subclause remains unchanged by this commit. + + commit d4280f38ddd489aecd8fb0da17a41f577db42e2a + Author: Thomas Köppe + Date: Sat Aug 20 23:11:39 2022 +0100 + + [memory.syn] Add missing "// freestanding" comment to "destroy" + + The comment was supposed to be added by P1642R11, but was accidentally + omitted. + + commit 47b0e73cc1e8d2ea344afedf60e07ec80df118f4 + Author: mordante + Date: Mon Aug 22 17:48:36 2022 +0200 + + [format.string.std] Reorder std-format-spec field descriptions. (#5246) + + Moves the wording describing the zero-padding before the description of + the width; matching the order of the fields in the std-format-spec. + + The original order was introduced in the initial paper P0645R10 "Text Formatting". + Since both fields had one paragraph of description, it wasn't too noticeable. P1868R2 "🦄 width: + clarifying units of width and precision in std::format" expanded the wording of the width. + Now it's not so easy to find the description of the zero-padding field. + + commit 517290b26fa8391d3b77d43ca8c271bb92695db7 + Author: Thomas Köppe + Date: Mon Aug 22 17:06:34 2022 +0100 + + [range.cartesian.view] Further fixing of cartesian-product-is-common + + The first fix in 8275c19b3fa9e7cb09f84049ebd6207aceb7ca80 was + incorrect. Only Const needs to be dropped (which was an error + in the paper), but ignoring Vs... is intentional. + + commit 101e7205882495cec1a944c7f6190b08bd131543 + Author: Thomas Köppe + Date: Mon Aug 22 17:23:46 2022 +0100 + + [ranges] Add missing closing delimiters + + commit 17be256d2431f66842479bf7ab2e92f30fff3060 + Author: Jens Maurer + Date: Sat Jun 18 21:39:06 2022 +0200 + + [alg.partitions] Indicate base of logarithm outside big-oh notation + + commit c6e83c4dba380b235be59b21db6c54bdffcb997d + Author: Jens Maurer + Date: Sat Jun 18 21:39:59 2022 +0200 + + [set.difference] Fix grammar typo + + commit 68e365415c707038f8af6c76f0f6f4cd3a4ce407 + Author: Jens Maurer + Date: Sat Jun 18 21:44:05 2022 +0200 + + [uninitialized.move] Fix typos in parameter names + + commit c3c6761111cff26e0e742e4d14b5d9e0bd28c4aa + Author: Jens Maurer + Date: Sat Jun 18 22:53:51 2022 +0200 + + [rand.adapt.disc] Remove superfluous trailing semicolon + + commit 65c9e5bcb3068a1172a66a7507d26a93adae7981 + Author: Jens Maurer + Date: Sat Jun 18 22:55:17 2022 +0200 + + [rand.adapt.ibits] Remove superfluous trailing semicolon + + commit 6ede23707505a18cdbb558108d635a0b21a1eeb0 + Author: Jens Maurer + Date: Sat Jun 18 22:55:47 2022 +0200 + + [rand.adapt.shuf] Remove superfluous trailing semicolon + + commit 5e44bc70b72b64e03e0d09564b2eaf45938a7752 + Author: Jens Maurer + Date: Sat Jun 18 22:58:11 2022 +0200 + + [valarray.members] Fix bad reference to argument + + commit 43b2bce231b04c1ccf7dc4bfd20e13f29c0e9c6c + Author: Jens Maurer + Date: Sun Jun 19 21:29:54 2022 +0200 + + [time.duration.io] Fix grammar typo + + commit 6e9b678f03a1a4fa8218152596a1952c209d1f27 + Author: Jens Maurer + Date: Sun Jun 19 21:32:40 2022 +0200 + + [time.cal.year.members] Fix erroneous qualified-id + + commit f0ab64a1dcb5bac1249ff67e838a7f899efeb586 + Author: Jens Maurer + Date: Sun Jun 19 21:39:48 2022 +0200 + + [locale.codecvt.general] Remove extra space before template-argument-list + + commit bbb7552af35266accf98ae718912579527ee11b8 + Author: Jens Maurer + Date: Sun Jun 19 21:41:58 2022 +0200 + + [locale.collate.general] Fix grammar typo + + commit 324dfd448ec5b632fc922015414cd206920b5842 + Author: Jens Maurer + Date: Sun Jun 19 21:45:29 2022 +0200 + + [ios.base.storage] Fix grammar typo + + commit fc53c9ede41d4992dc64f556bc32febb28ad0e1e + Author: Jens Maurer + Date: Sun Jun 19 21:45:58 2022 +0200 + + [fpos] Fix typo in exposition-only member + + commit 47273ceb655716f62fc1c9fe00a317b44c221267 + Author: Jens Maurer + Date: Sun Jun 19 21:47:05 2022 +0200 + + [fpos.operations] Fix name of type trait + + commit 04d7e61e9deaf2481d144e2c0a7d2478cff58764 + Author: Jens Maurer + Date: Sun Jun 19 21:49:00 2022 +0200 + + [streambuf.cons] Fix grammar typo + + commit f055ba09397bd479317a92c315e5a074f7c2e474 + Author: Jens Maurer + Date: Sun Apr 17 11:19:04 2022 +0200 + + [atomics.syn] Move namespace-scope memory_order_* variables here + + commit f400d80927fd580f99f5f2d94c3d07eaa47373d0 + Author: Jens Maurer + Date: Sun Apr 17 11:23:54 2022 +0200 + + [ranges.syn] Move namespace-scope declarations for get(subrange) here + + commit e9434db227e8b3113a477dcdd0c6c14ffe2c14b8 + Author: Jonathan Wakely + Date: Mon Aug 22 18:56:41 2022 +0100 + + [tuple.creation] Add missing semi-colon to example + + commit 25bb0a278e8141613f2c813c50a74428e3da7b8b + Author: Jonathan Wakely + Date: Mon Aug 22 18:58:39 2022 +0100 + + [util.smartptr.shared.obs], [util.smartptr.shared.create] use nullptr for null pointer constant + + commit 7a4324c21e4f66af801bc7e7fc78b94119253301 + Author: Jonathan Wakely + Date: Mon Aug 22 21:52:22 2022 +0100 + + [char.traits.require] use nullptr for null pointer constant + + commit b3b64b35ce456a7e54476b9a00185323b68fcd6d + Author: Jonathan Wakely + Date: Mon Aug 22 22:01:22 2022 +0100 + + [unord.req.general] Use "constant" not "const" + + commit a421a3029418651b9734ae786c9b89b72b08b42d + Author: Jonathan Wakely + Date: Mon Aug 22 22:09:00 2022 +0100 + + [unord.multimap.overview] Fix presentation of member types + + As already done in de6b0e70ffe2da0a0f91ce434863202f78c9e029 for unordered_map. + + commit a758844278a818fd8ccbd33a6ca0460b31616d74 + Author: Jonathan Wakely + Date: Mon Aug 22 22:33:04 2022 +0100 + + [range.elements.view] fix class-key for iterator and sentinel + + commit 44b146eda750e453ee3d52587c2accab4be6c74d + Author: Jonathan Wakely + Date: Mon Aug 22 22:35:18 2022 +0100 + + [range.elements.iterator] remove stray semi-colon + + commit 3a51f3e858e14abc0623f8823e0d2c883c27a4e4 + Author: Jonathan Wakely + Date: Mon Aug 22 22:45:30 2022 +0100 + + [complex.ops] use character literal for single character + + commit 678907e6d8af62cab9429b7065be69c36ffa2592 + Author: Jonathan Wakely + Date: Mon Aug 22 22:46:43 2022 +0100 + + [rand.req.dist] fix grammar typo + + commit 698be9d6b09517dc1323ca99fc4bb84ec62fae9e + Author: Jonathan Wakely + Date: Mon Aug 22 22:56:42 2022 +0100 + + [cons.slice], [gslice.cons] remove undeclared/undocumented copy constructor signatures + + commit 1cda1f9d2ac5d8caa81e793ce3f95364aba1fb6b + Author: Jonathan Wakely + Date: Mon Aug 22 23:01:23 2022 +0100 + + [template.mask.array.overview], [template.indirect.array.overview] fix itemdecl typos + + commit f3ddcf79a971f488b3acf0e52ca6ea9689af7fd7 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Tue Aug 23 19:58:08 2022 +0800 + + [ranges.cartesian.iterator] Fix typo "reference_t" => "range_reference_t" (#5777) + + commit 227c3b249f0f52484920400b861717649895e6cc + Author: cor3ntin + Date: Tue Aug 23 14:00:44 2022 +0200 + + [range.adjacent.overview] Use tuple in example, not pair (#5779) + + adjacent_view always yields tuples, but the example was written as if it yielded a std::pair. + + commit c0c0d75402b1dc33f0cba971c898dc2ac7bfaa06 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Tue Aug 23 20:00:49 2022 +0800 + + [range.cartesian.view] Add missing angle brackets for cartesian-is-sized-sentinel + + commit c777f930668fe23ab287ff765463d3b3731696eb + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Tue Aug 23 21:45:23 2022 +0800 + + [range.zip, ranges.cartesian.iterator] Simplify `maybe-const` to `const Views` (#5778) + + The type `maybe-const` only appears after `Const &&` + in these cases, so that only the case where `Const` is `true` matters. + + commit eca39f43798d7a58fdd482232c60b6db428b656f + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Wed Aug 24 01:57:58 2022 +0800 + + [tuple.syn, tuple.like] Fix template head formatting (#5784) + + commit 356fb7ff88b63d956b1109c72c5e3bf424f6ba29 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Wed Aug 24 01:58:17 2022 +0800 + + [algorithm.syn] Fix template head formatting (#5786) + + commit 6ccb959c7a8c10fc5fa7dd469c64f3c992e7e7ee + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Tue Aug 23 20:10:44 2022 +0800 + + [range.zip.overview] Use tuple in example, not pair + + commit 8404284d8b7ac6ff2725a33d5e33410d1ea3b470 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Tue Aug 23 23:10:39 2022 +0800 + + [range.drop.overview, range.take.overview] Fixed unformatted (void)F, decay-copy(E) + + commit 6e2b23594abd64c9ba50934654c68bd174c7ab91 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Wed Aug 24 18:49:21 2022 +0800 + + [format.range.fmtstr] Add ranges namespace qualifier (#5788) + + The range concept is named outside of the `ranges` namespace. + + commit 301f0cdcb547f54b1d39163550a5869a0c6b073f + Author: Thomas Köppe + Date: Thu Aug 25 02:28:09 2022 +0100 + + [coroutine.syn] Move "all freestanding" comment to the top + + commit e38650de03741a87d6c625ce93974946f46f5caa + Author: Thomas Köppe + Date: Thu Aug 25 02:41:49 2022 +0100 + + [tuple.like] Remove extraneous "std::" qualification. + + commit 3da6b0e8798681144b676b3b4180301f8f7c8f2c + Author: Thomas Köppe + Date: Thu Aug 25 10:55:25 2022 +0100 + + [const.iterators.{alias,iterators}] Add "exposition only" comments + + Suggested by CD review feedback. + + commit 5dd0216a477391fbce339e22f169136420472979 + Author: Thomas Köppe + Date: Thu Aug 25 11:12:24 2022 +0100 + + [range.refinements] Fix template argument name ("T", not "R") + + commit 347ded018d09d2a226e3ab42665d1a13b25d489a + Author: Thomas Köppe + Date: Thu Aug 25 11:27:38 2022 +0100 + + [vector.bool.pspc] Reinstate redundant "inline", as per paper + + The "inline" was removed editorially in + 2141dab25c7f6d186d662e0ebe916efcd56843ae, but CD review has requested + we retain it. + + commit 79ab62930d2538e1ef668c6a1b50e8d7027ebedc + Author: Thomas Köppe + Date: Thu Aug 25 11:34:57 2022 +0100 + + [format.string.escaped] Fix typos in "APOSTROPHE" + + commit 426ce8a7ec2232aebaaf76bf2f5e4a69a500cef6 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Thu Aug 25 19:31:57 2022 +0800 + + [ranges] Tweak some examples (#5791) + + Removes redundant `std::` qualifications and uses `views::meow` instead of `meow_view`. + + commit 4ed7fcf6b725207ac307a6d1411ad2aa4ed55c8f + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Fri Aug 26 04:36:08 2022 +0800 + + [containers] Add `std::` for `forward`/`move` (#5793) + + commit aec46d1970a8869db0d178c436545b0e40968425 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Fri Aug 26 04:43:03 2022 +0800 + + [move.sentinel] Remove extraneous "std" qualification in example (#5792) + + commit ed18148b1d514c0aea12d99b1ec3a56d4a834266 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Fri Aug 26 15:00:12 2022 +0800 + + [util.smartptr.shared.create] Add std:: qualification for forward + + commit eb703517cd6c79f56df12c5dca359121efbef4ee + Author: Thomas Köppe + Date: Fri Aug 26 14:39:39 2022 +0100 + + [range.move.wrap] Fix constraint (move, not copy-constructible) + + This was accidentally omitted from previous changes requested by P2494R2. + + commit 2a600822d08332a8350e3a093212bdc7f8a82e2b + Author: Thomas Köppe + Date: Fri Aug 26 15:06:06 2022 +0100 + + [format.range.fmtdef] Add "exposition only" comments + + commit 9d71b7d3b0aac1f179fc3973b0ff1624b00b07ce + Author: Thomas Köppe + Date: Fri Aug 26 15:26:39 2022 +0100 + + [obj.lifetime] Add cross-reference pointing at basic.types.general + + Suggested by CD review feedback. + + commit 9eb92bf36b19381a534273ad98e296dfeb7a0fc9 + Author: Jens Maurer + Date: Mon Aug 29 22:45:41 2022 +0200 + + [flat.set.modifiers] Remove stray 'return' in Effects clause + + commit 69177109f387d3958ffea237c9b0419e4d2aa49c + Author: Thomas Köppe + Date: Fri Sep 2 23:44:14 2022 +0100 + + [expr.ass] Fix typo, "~" should be "^". + + This was a misapplication of P2327R1 in 0aebf5cacded1b64cf089dbc7a0504fbb9f50aa6. + + commit e6e17d5e136934f113d6e0a8bde4c227459a9d47 + Author: Thomas Köppe + Date: Sat Sep 3 02:10:27 2022 +0100 + + [diff.cpp20.{dcl,expr}] Fix subclause order to match main document + + commit 853747c5d8130880b96a39ab940c343aa7530d71 + Author: Thomas Köppe + Date: Sat Sep 3 15:02:00 2022 +0100 + + [basic.fundamental] Use correct number; "are", not "is". + + commit 07e02a80fe890dcb6e84182a5697046f1bd4c630 + Author: Jens Maurer + Date: Mon Aug 29 22:23:54 2022 +0200 + + [expected.object.assign] Add missing 'Returns: *this' + + commit 06dcf0556631382ecdc420c22c66366168c226b4 + Author: Thomas Köppe + Date: Sun Sep 4 13:01:12 2022 +0100 + + [mdspan.layout.left.overview] Reorder "explicit" and "constexpr" + + The standard ordering is "constexpr explicit", not the other way + round. The paper P0009R18 contains a non-standard style, and other + instances had already been fixed. Only this one seems to have been + missed previously. + + commit e651f145df7c587ea810aca754e680bb27ea8481 + Author: Thomas Köppe + Date: Sun Sep 4 13:08:42 2022 +0100 + + [mdspan.layout.{left,right}.overview] Replace "see below" with condition + + The condition is spelled out in the item descriptions already, and the + class synopses seem to simply have been inconsistent with that in the + incoming paper P0009R18. Since the "see below"s are never referenced + explicitly, we just replace them with the actual conditions, which is + also how the surrounding members are presented. + + commit 1765844a9382e1f3415bbbdcd12eaa09a6b1f827 + Author: Thomas Köppe + Date: Sun Sep 4 13:25:52 2022 +0100 + + [mdspan.layout.stride.expo] Move "otherwise" from trailing to leading + + We have a mild preference for the leading position. + + commit c02512ecf3f15fb0f29dc602eb153bc7dabd643d + Author: Thomas Köppe + Date: Sun Sep 4 13:53:01 2022 +0100 + + [mdspan.layout.stride.obs] Add missing parentheses + + commit 9897c566ec3ecd6f25078a3dd10ce34c17e812e7 + Author: Thomas Köppe + Date: Sun Sep 4 13:54:19 2022 +0100 + + [mdspan.accessor.default.members] Fix typo in "equivalent" + + commit 3b6163d1a3b1f5cc2be49d6ff0eb6b3889b552df + Author: Thomas Köppe + Date: Sun Sep 4 13:58:09 2022 +0100 + + [flat.map.syn] Add missing "namespace std {" + + commit c164add6cdac73cae85649ba2172de43c3d8ed5b + Author: Thomas Köppe + Date: Sun Sep 4 14:02:11 2022 +0100 + + [flat.map.modifiers] Typo: "range" should be "rg" + + commit 1b427b20fecbc95b98d2380e0ddae71b71c1f657 + Author: Thomas Köppe + Date: Sun Sep 4 14:06:53 2022 +0100 + + [flat.{,multi}set.ctor] Add missing "explicit" in itemdecls + + commit 8f153df9c66c33f100ec7a4d7998dfaf6a7aa8da + Author: Thomas Köppe + Date: Thu Nov 26 02:43:37 2020 +0000 + + [basic, except, diff] Rewordings to avoid "might" and "could" diff --git a/papers/wd-index.md b/papers/wd-index.md index 5b3d4dee1e..5d6a4f75a1 100644 --- a/papers/wd-index.md +++ b/papers/wd-index.md @@ -41,3 +41,4 @@ * [N4892](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/n4892.pdf) 2021-06 C++ Working Draft * [N4901](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/n4901.pdf) 2021-10 C++ Working Draft * [N4910](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/n4910.pdf) 2022-03 C++ Working Draft + * [N4910](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/n4917.pdf) 2022-07 C++ Working Draft diff --git a/source/config.tex b/source/config.tex index 7b9750928c..f5acf7b1e1 100644 --- a/source/config.tex +++ b/source/config.tex @@ -1,7 +1,7 @@ %!TEX root = std.tex %%-------------------------------------------------- %% Version numbers -\newcommand{\docno}{Dxxxx} +\newcommand{\docno}{N4917} \newcommand{\prevdocno}{N4910} \newcommand{\cppver}{202002L}