diff --git a/source/support.tex b/source/support.tex index 5e055e0d2b..337e1a05f2 100644 --- a/source/support.tex +++ b/source/support.tex @@ -617,6 +617,8 @@ #define @\defnlibxname{cpp_lib_constexpr_typeinfo}@ 202106L // freestanding, also in \libheader{typeinfo} #define @\defnlibxname{cpp_lib_constexpr_utility}@ 201811L // freestanding, also in \libheader{utility} #define @\defnlibxname{cpp_lib_constexpr_vector}@ 201907L // also in \libheader{vector} +#define @\defnlibxname{cpp_lib_constrained_equality}@ 202403L // freestanding, + // also in \libheader{utility}, \libheader{tuple}, \libheader{optional}, \libheader{variant} #define @\defnlibxname{cpp_lib_containers_ranges}@ 202202L // also in \libheader{vector}, \libheader{list}, \libheader{forward_list}, \libheader{map}, \libheader{set}, \libheader{unordered_map}, \libheader{unordered_set}, // \libheader{deque}, \libheader{queue}, \libheader{stack}, \libheader{string} @@ -754,6 +756,7 @@ #define @\defnlibxname{cpp_lib_raw_memory_algorithms}@ 201606L // also in \libheader{memory} #define @\defnlibxname{cpp_lib_rcu}@ 202306L // also in \libheader{rcu} #define @\defnlibxname{cpp_lib_reference_from_temporary}@ 202202L // freestanding, also in \libheader{type_traits} +#define @\defnlibxname{cpp_lib_reference_wrapper}@ 202403L // freestanding, also in \libheader{functional} #define @\defnlibxname{cpp_lib_remove_cvref}@ 201711L // freestanding, also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_result_of_sfinae}@ 201210L // freestanding, also in \libheader{functional}, \libheader{type_traits} diff --git a/source/utilities.tex b/source/utilities.tex index 6c0444e479..a354b49ff0 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -1282,9 +1282,11 @@ \begin{itemdescr} \pnum -\expects -Each of \tcode{decltype(x.first == y.first)} and -\tcode{decltype(x.second == y.second)} models \exposconcept{boolean-testable}. +\constraints +\tcode{x.first == y.first} and \tcode{x.second == y.second} are +valid expressions and +each of \tcode{decltype(x.first == y.first)} and +\tcode{decltype(x.second == y.second)} models \exposconceptx{boolean-\newline testable}{boolean-testable}. \pnum \returns @@ -2935,18 +2937,14 @@ For the first overload let \tcode{UTuple} be \tcode{tuple}. \pnum -\mandates +\constraints For all \tcode{i}, where $0 \leq \tcode{i} < \tcode{sizeof...(TTypes)}$, -\tcode{get(t) == get(u)} is a valid expression. +\tcode{get(t) == get(u)} is a valid expression and +\tcode{decltype(get(t) == get(u))} models \exposconcept{boolean-testable}. \tcode{sizeof...(TTypes)} equals \tcode{tuple_size_v}. -\pnum -\expects -For all \tcode{i}, \tcode{decltype(get(t) == get(u))} models -\exposconcept{boolean-testable}. - \pnum \returns \tcode{true} if \tcode{get(t) == get(u)} for all @@ -4399,7 +4397,7 @@ \begin{itemdescr} \pnum -\mandates +\constraints The expression \tcode{*x == *y} is well-formed and its result is convertible to \tcode{bool}. \begin{note} @@ -4424,7 +4422,7 @@ \begin{itemdescr} \pnum -\mandates +\constraints The expression \tcode{*x != *y} is well-formed and its result is convertible to \tcode{bool}. @@ -4448,7 +4446,7 @@ \begin{itemdescr} \pnum -\mandates +\constraints \tcode{*x < *y} is well-formed and its result is convertible to \tcode{bool}. @@ -4472,7 +4470,7 @@ \begin{itemdescr} \pnum -\mandates +\constraints The expression \tcode{*x > *y} is well-formed and its result is convertible to \tcode{bool}. @@ -4496,7 +4494,7 @@ \begin{itemdescr} \pnum -\mandates +\constraints The expression \tcode{*x <= *y} is well-formed and its result is convertible to \tcode{bool}. @@ -4520,7 +4518,7 @@ \begin{itemdescr} \pnum -\mandates +\constraints The expression \tcode{*x >= *y} is well-formed and its result is convertible to \tcode{bool}. @@ -4589,7 +4587,7 @@ \begin{itemdescr} \pnum -\mandates +\constraints The expression \tcode{*x == v} is well-formed and its result is convertible to \tcode{bool}. \begin{note} @@ -4608,7 +4606,7 @@ \begin{itemdescr} \pnum -\mandates +\constraints The expression \tcode{v == *x} is well-formed and its result is convertible to \tcode{bool}. @@ -4624,7 +4622,7 @@ \begin{itemdescr} \pnum -\mandates +\constraints The expression \tcode{*x != v} is well-formed and its result is convertible to \tcode{bool}. @@ -4640,7 +4638,7 @@ \begin{itemdescr} \pnum -\mandates +\constraints The expression \tcode{v != *x} is well-formed and its result is convertible to \tcode{bool}. @@ -4656,7 +4654,7 @@ \begin{itemdescr} \pnum -\mandates +\constraints The expression \tcode{*x < v} is well-formed and its result is convertible to \tcode{bool}. @@ -4672,7 +4670,7 @@ \begin{itemdescr} \pnum -\mandates +\constraints The expression \tcode{v < *x} is well-formed and its result is convertible to \tcode{bool}. @@ -4688,7 +4686,7 @@ \begin{itemdescr} \pnum -\mandates +\constraints The expression \tcode{*x > v} is well-formed and its result is convertible to \tcode{bool}. @@ -4704,7 +4702,7 @@ \begin{itemdescr} \pnum -\mandates +\constraints The expression \tcode{v > *x} is well-formed and its result is convertible to \tcode{bool}. @@ -4720,7 +4718,7 @@ \begin{itemdescr} \pnum -\mandates +\constraints The expression \tcode{*x <= v} is well-formed and its result is convertible to \tcode{bool}. @@ -4736,7 +4734,7 @@ \begin{itemdescr} \pnum -\mandates +\constraints The expression \tcode{v <= *x} is well-formed and its result is convertible to \tcode{bool}. @@ -4752,7 +4750,7 @@ \begin{itemdescr} \pnum -\mandates +\constraints The expression \tcode{*x >= v} is well-formed and its result is convertible to \tcode{bool}. @@ -4768,7 +4766,7 @@ \begin{itemdescr} \pnum -\mandates +\constraints The expression \tcode{v >= *x} is well-formed and its result is convertible to \tcode{bool}. @@ -5991,7 +5989,7 @@ \begin{itemdescr} \pnum -\mandates +\constraints \tcode{\exposid{GET}<$i$>(v) == \exposid{GET}<$i$>(w)} is a valid expression that is convertible to \tcode{bool}, for all $i$. @@ -6010,7 +6008,7 @@ \begin{itemdescr} \pnum -\mandates +\constraints \tcode{\exposid{GET}<$i$>(v) != \exposid{GET}<$i$>(w)} is a valid expression that is convertible to \tcode{bool}, for all $i$. @@ -6029,7 +6027,7 @@ \begin{itemdescr} \pnum -\mandates +\constraints \tcode{\exposid{GET}<$i$>(v) < \exposid{GET}<$i$>(w)} is a valid expression that is convertible to \tcode{bool}, for all $i$. @@ -6050,7 +6048,7 @@ \begin{itemdescr} \pnum -\mandates +\constraints \tcode{\exposid{GET}<$i$>(v) > \exposid{GET}<$i$>(w)} is a valid expression that is convertible to \tcode{bool}, for all $i$. @@ -6071,7 +6069,7 @@ \begin{itemdescr} \pnum -\mandates +\constraints \tcode{\exposid{GET}<$i$>(v) <= \exposid{GET}<$i$>(w)} is a valid expression that is convertible to \tcode{bool}, for all $i$. @@ -6092,7 +6090,7 @@ \begin{itemdescr} \pnum -\mandates +\constraints \tcode{\exposid{GET}<$i$>(v) >= \exposid{GET}<$i$>(w)} is a valid expression that is convertible to \tcode{bool}, for all $i$. @@ -10999,6 +10997,16 @@ template constexpr invoke_result_t operator()(ArgTypes&&...) const noexcept(is_nothrow_invocable_v); + + // \ref{refwrap.comparisons}, comparisons + friend constexpr bool operator==(reference_wrapper, reference_wrapper); + friend constexpr bool operator==(reference_wrapper, const T&); + friend constexpr bool operator==(reference_wrapper, reference_wrapper); + + friend constexpr @\exposidnc{synth-three-way-result}@ operator<=>(reference_wrapper, reference_wrapper); + friend constexpr @\exposidnc{synth-three-way-result}@ operator<=>(reference_wrapper, const T&); + friend constexpr @\exposidnc{synth-three-way-result}@ operator<=>(reference_wrapper, + reference_wrapper); }; template @@ -11017,6 +11025,12 @@ \pnum The template parameter \tcode{T} of \tcode{reference_wrapper} may be an incomplete type. +\begin{note} +Using the comparison operators described in subclause \ref{refwrap.comparisons} +with \tcode{T} being an incomplete type +can lead to an ill-formed program +with no diagnostic required\iref{temp.point,temp.constr.atomic}. +\end{note} \rSec3[refwrap.const]{Constructors} @@ -11120,6 +11134,88 @@ \tcode{\placeholdernc{INVOKE}(get(), std::forward(args)...)}.\iref{func.require} \end{itemdescr} +\rSec3[refwrap.comparisons]{Comparisons} + +\begin{itemdecl} +friend constexpr bool operator==(reference_wrapper x, reference_wrapper y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +The expression \tcode{x.get() == y.get()} is well-formed and +its result is convertible to \tcode{bool}. + +\pnum +\returns +\tcode{x.get() == y.get()}. +\end{itemdescr} + +\begin{itemdecl} +friend constexpr bool operator==(reference_wrapper x, const T& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +The expression \tcode{x.get() == y} is well-formed and +its result is convertible to \tcode{bool}. + +\pnum +\returns +\tcode{x.get() == y}. +\end{itemdescr} + +\begin{itemdecl} +friend constexpr bool operator==(reference_wrapper x, reference_wrapper y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_const_v} is \tcode{false} and +the expression \tcode{x.get() == y.get()} is well-formed and +its result is convertible to \tcode{bool}. + +\pnum +\returns +\tcode{x.get() == y.get()}. +\end{itemdescr} + +\begin{itemdecl} +friend constexpr @\exposidnc{synth-three-way-result}@ operator<=>(reference_wrapper x, reference_wrapper y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{\exposid{synth-three-way}(x.get(), y.get())}. +\end{itemdescr} + +\begin{itemdecl} +friend constexpr @\exposidnc{synth-three-way-result}@ operator<=>(reference_wrapper x, const T& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{\exposid{synth-three-way}(x.get(), y)}. +\end{itemdescr} + +\begin{itemdecl} +friend constexpr @\exposidnc{synth-three-way-result}@ operator<=>(reference_wrapper x, + reference_wrapper y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_const_v} is \tcode{false}. + +\pnum +\returns +\tcode{\exposid{synth-three-way}(x.get(), y.get())}. +\end{itemdescr} \rSec3[refwrap.helpers]{Helper functions}