diff --git a/src/D2841.tex b/src/D2841.tex index dc1d6e8..35edae0 100644 --- a/src/D2841.tex +++ b/src/D2841.tex @@ -2142,22 +2142,31 @@ \subsection{\textcolor{noteclr}{3. Wording for variable-template and concept tem \rSec3[temp.constr.concept]{Concept-dependent constraint} -A \defn{concept-dependent constraint} is formed from a concept-id \tcode{C} -where \tcode{C} names a concept template parameter. +A \defn{concept-dependent constraint} \tcode{CD} is an atomic constraint whose +expression is a concept-id CI whose \grammarterm{concept-name} names a dependent concept named \tcode{C}. -\ednote{replace formed from?} +To determine if \tcode{CD} is satisfied, the parameter mapping and template arguments are first substituted into \tcode{C}. If substitution results in an invalid concept-id in the immediate context of the constraint ([temp.deduct.general]), the constraint is not satisfied. +Otherwise, let \tcode{CI'} be the normal form of the concept-id after substitution of \tcode{C}. -To determine if a concept-dependent constraint is satisfied, template arguments are first substituted into \tcode{C}. If substitution results in an invalid concept-id in the immediate context of the constraint ([temp.deduct.general]), the constraint is not satisfied. -Otherwise, let \tcode{E} be the normal form of the concept-id after substitution of \tcode{C}. -The constraint is satisfied if \tcode{E} is satisfied. +\begin{note} +Normalization of \tcode{CI} may be ill-formed; no diagnostics is required. +\end{note} +To form \tcode{CI''}, each appearance of \tcode{C}'s template parameters in the parameter mappings of the atomic constraints (including concept-dependent constraints) in \tcode{CI'} is substituted with their respective arguments from the +the parameter mapping of \tcode{CD} and the arguments of \tcode{CI}. + +% +%Each argument in the parameter mapping of CI' +%is substituted for the respective template parameter +%in the parameter mapping of CD. + +The constraint is satisfied if \tcode{CI''} is satisfied. + +\begin{note} +Checking whether \tcode{CI''} is satisfied can lead to further +normalization of concept-dependent constraints. +\end{note} -%During the instantiation of a specialization or member function [temp.inst], -%if the argument \tcode{A} corresonding -%to the concept template parameter named by \tcode{C} is not dependent, \tcode{C} is substituted by -%the normal form of \tcode{A}. -%The substituted normal form of \tcode{C} is the normal form of \tcode{A} where \tcode{A} is the argument -%corresponding to the concept template parameter named by \tcode{C}. \end{addedblock} @@ -2171,16 +2180,16 @@ \subsection{\textcolor{noteclr}{3. Wording for variable-template and concept tem %the \defn{substitutable concept parameter}{s} of \tcode{E} are the set of concept template parameters named by \tcode{E} %that are declared in in the enclosing template of \tcode{D} and for which there exist a corresponding set of non-dependent template arguments. % -Given a concept-id \tcode{C}, -the \defn{substitutable concept parameters} of an expression \tcode{E} that is a subexpression of the \grammarterm{constraint-expression} of \tcode{C} is the set of concept template parameters of \tcode{C} for which there is a corresponding argument in \tcode{C}. +%Given a concept-id \tcode{C}, +%the \defn{substitutable concept parameters} of an expression \tcode{E} that is a subexpression of the \grammarterm{constraint-expression} of \tcode{C} is the set of concept template parameters of \tcode{C} for which there is a corresponding argument in \tcode{C}. % %The \defn{substitutable concept parameters} of \tcode{E} %is the set of non-dependent associated concept parameters of \tcode{E}. -The normal form of a concept-dependent constraint \tcode{CD} whose concept-id \tcode{CI} is \tcode{C} is the normal form of \tcode{CI} after substituting each \tcode{C} and \tcode{A$_1$} that names a substitutable concept parameter by the corresponding template argument -%of \tcode{C}. -If substitution results in an invalid concept-id, the normal form of \tcode{CD} is \tcode{false}. -If no concept template parameter is substituted, the normal form of \tcode{CD} is \tcode{CD}. +%The normal form of a concept-dependent constraint \tcode{CD} whose concept-id \tcode{CI} is \tcode{C} is the normal form of \tcode{CI} after substituting each \tcode{C} and \tcode{A$_1$} that names a substitutable concept parameter by the corresponding template argument +%%of \tcode{C}. +%If substitution results in an invalid concept-id, the normal form of \tcode{CD} is \tcode{false}. +%If no concept template parameter is substituted, the normal form of \tcode{CD} is \tcode{CD}. \end{addedblock} @@ -2204,22 +2213,29 @@ \subsection{\textcolor{noteclr}{3. Wording for variable-template and concept tem is the conjunction of the normal forms of \tcode{E1} and \tcode{E2}. -\added{For a concept-id \tcode{CI} of the form \tcode{C}} -\begin{itemize} -\begin{addedblock} -%\item When \tcode{C} names a substitutable concept parameter, the normal form of a concept-id \tcode{C} is -%the normal form of \tcode{C'} after substituting \tcode{C} by the corresponding template argument \tcode{C'}. -\item When \tcode{C} or any \tcode{A$_{0 \le i < n}$} name a concept template parameter, the normal form of \tcode{CI} is the normal form of a concept-dependent constraint whose concept-id is \tcode{CI}. -\end{addedblock} \item -\added{Otherwise}, \changed{The}{the} normal form of \tcode{CI} + +\changed{The normal form of}{For} a concept-id \tcode{C} \added{termed \added{CI}:} +\begin{removedblock} is the normal form of the \grammarterm{constraint-expression} of \tcode{C}, after substituting \tcode{A$_1$, A$_2$, ..., A$_n$} for - \tcode{C}{'s} respective template parameters in the - parameter mappings in each atomic constraint. - If any such substitution results in an invalid type or expression, - the program is ill-formed; no diagnostic is required. +\tcode{C}{'s} respective template parameters in the +parameter mappings in each atomic constraint. +If any such substitution results in an invalid type or expression, +the program is ill-formed; no diagnostic is required. +\end{removedblock} +\begin{addedblock} +\begin{itemize} +\item If \tcode{C} names a dependent concept, the normal form of \tcode{CI} is a concept dependent constraint whose concept-id is \tcode{CI}. + +\item To form \tcode{CE}, any non-dependent concept template argument A$_i$ +is substituted into the constraint-expression of \tcode{C}. +If any such substitution results in an invalid concept-id the program is ill-formed; no diagnostic is required. + +The normal form of \tcode{CI} is the result of substituting, in the normal \tcode{N} of \tcode{CE}, appearances of \tcode{C}'s template parameters in the parameter mappings of the atomic constraints in N with their respective arguments from \tcode{C}. If any such substitution results in an invalid type or expression, the program is ill-formed; no diagnostic is required. +\end{itemize} +\end{addedblock} %\begin{addedblock} %\begin{itemize} %\item Substituting each substitutable concept parameter in each concept-id \tcode{CI} of each non-atomic subexpression of the \grammarterm{constraint-expression} of \tcode{C} by the corresponding template argument of \tcode{C}. If substitution \tcode{CI} results in an invalid concept-id, the normal form of \tcode{CI} is \tcode{false}. @@ -2232,9 +2248,6 @@ \subsection{\textcolor{noteclr}{3. Wording for variable-template and concept tem %\end{itemize} %\end{addedblock} -\end{itemize} - - \begin{example} \begin{codeblock} template concept A = T::value || true; @@ -2281,16 +2294,21 @@ \subsection{\textcolor{noteclr}{3. Wording for variable-template and concept tem \begin{addedblock} \item -For an expression \tcode{F} of the form \tcode{( E \grammarterm{Op} ... )} +For an expression \tcode{F} of the form \tcode{( E \grammarterm{Op} ... )}, + +let \tcode{E'} be the normal form of \tcode{E}. \begin{itemize} \item -If \tcode{E} names one or more unexpanded substitutable concept template parameter pack $P_k$ which do not denote a pack, let $N_k$ be the number of arguments specified for each pack $P_k$. +If \tcode{E} names one or more unexpanded concept template parameter pack $P_k$ which has corresponding template arguments in the parameter mapping of any +atomic constraint (including context-dependent constraint) +of \tcode{E'}, let $N_k$ be the number of arguments specified for each pack $P_k$. If the value of each $N_k$ differs, the program is ill-formed. Otherwise, the normal form of \tcode{F} is -the normal form of $E_0$ \tcode{Op} $E_1$ \tcode{Op} ... \tcode{Op} $E_{N_0}$. -Within $E_{0 \le i < {N_0}}$, $P_k$ designates the $i^\text{th}$ pack element of $P_k$. +the normal form of $E_0$ \tcode{Op} $E_1$ \tcode{Op} ... \tcode{Op} $E_{N_0}$ after substituting in $E_{0 \le i < {N_0}}$ each respective $i_th$ non-dependent concept argument of each $P_k$ . +If any such substitution results in an invalid type or expression, the program is ill-formed; no diagnostic is required. +%Within $E_{0 \le i < {N_0}}$, $P_k$ designates the $i^\text{th}$ pack element of $P_k$. @@ -2316,7 +2334,7 @@ \subsection{\textcolor{noteclr}{3. Wording for variable-template and concept tem \item Otherwise %(if \tcode{E} does not contain an unexpanded parameter pack that denotes a substitutable concept template parameter pack), the normal form of \tcode{( E Op ... )} is a fold expanded constraint \iref{temp.constr.fold} -whose constraint is the normal form of \tcode{E} and +whose constraint is \tcode{E'} and whose \grammarterm{fold-operator} is \tcode{Op}. \end{itemize} \end{addedblock} diff --git a/src/D2846.tex b/src/D2846.tex index 8088e02..14c01b0 100644 --- a/src/D2846.tex +++ b/src/D2846.tex @@ -5,7 +5,7 @@ \documentclass{wg21} \title{\tcode{reserve\_hint}: Eagerly reserving memory for not-quite-sized lazy ranges} -\docnumber{P2846R4} +\docnumber{D2846R5} \audience{LEWG} \author{Corentin Jabot}{corentin.jabot@gmail.com} @@ -19,6 +19,12 @@ \section{Abstract} \section{Revisions} +\subsection{R5} + +\begin{itemize} +\item Apply some wording feedback following LEWG review, remove the nothrow_move_constructible requirement from vector's constructor complexity requirements, fix feature test macro. +\end{itemize} + \subsection{R4} \begin{itemize} @@ -214,7 +220,7 @@ \subsection{\tcode{vector} constructors} \textbf{This is the option implemented in R3, following LEWG guidance} Tomasz also realized that types that may throw on move might also change the behavior of existing code. -To avoid that we restrict the optimization guarantee in vector to types that are nothrow move-constructible. +To avoid that we restrict the optimization guarantee in vector to types that are nothrow move-constructible. however, LEWG voted not to add this requirement (Wroclaw). \item Allowing implementations to do so without requiring it. @@ -232,7 +238,7 @@ \subsection{\tcode{std::vector} \tcode{insert} and \tcode{append} methods} \subsection{\tcode{string}} -\tcode{string} doesn't currently mandate complexity guarantees so we have ekected not to modify the specification, +\tcode{string} doesn't currently mandate complexity guarantees so we have elected not to modify the specification, and instead preferring a blanket recommended practice that \tcode{reserve_hint} should be used to reduce reallocations. \section{Benchmarks} @@ -247,11 +253,11 @@ \section{Benchmarks} The graph shows that, for a forward range, reserving is consistently about twice as fast. This is consistent with the fact the range is traversed twice. -\includegraphics[width=\textwidth]{D2846_bench1.png} +% \includegraphics[width=\textwidth]{D2846_bench1.png} If the input range is non-forward, there is less difference on small datasets: -\includegraphics[width=\textwidth]{D2846_bench2.png} +% \includegraphics[width=\textwidth]{D2846_bench2.png} But as the data gets bigger and the number of allocations increases being able to reserve memory gets more noticeably impactful (performance delta of 5-10\%). @@ -292,10 +298,10 @@ \section{Naming} \section{Wording} -\ednote{Add the macro \tcode{__cpp_lib_ranges_zip} to \tcode{} and \tcode{}} +\ednote{Add the macro \tcode{__cpp_lib_ranges_reserve_hint} to \tcode{} and \tcode{}} \begin{addedblock} \begin{codeblock} - #define __cpp_lib_ranges_zip 2026XX (**placeholder**) + #define __cpp_lib_ranges_reserve_hint 2024XX (**placeholder**) \end{codeblock} \end{addedblock} @@ -326,8 +332,9 @@ \section{Wording} \begin{addedblock} Performs no reallocations if: \begin{itemize} - \item \tcode{R} models \tcode{ranges::\libconcept{sized_range}}, - \item \tcode{R} models \tcode{ranges::\libconcept{approximately_sized_range}}, \tcode{is_nothrow_move_constructible_v} is \tcode{true}, and \tcode{ranges::distance(rg) <= ranges::reserve_hint(rg)} is \tcode{true}, or + \item \tcode{R} models \tcode{ranges::\libconcept{sized_range}}, or + \item \tcode{R} models \tcode{ranges::\libconcept{approximately_sized_range}}, %\tcode{is_nothrow_move_constructible_v} is \tcode{true}, + and \tcode{ranges::distance(rg) <= ranges::reserve_hint(rg)} is \tcode{true}, or \item \tcode{R} models \tcode{ranges::\libconcept{forward_range}}. \end{itemize} \end{addedblock} @@ -392,7 +399,7 @@ \section{Wording} \begin{addedblock} For the declarations taking a range \tcode{R}, performs at most one reallocation if: \begin{itemize} - \item \tcode{R} models \tcode{ranges::\libconcept{sized_range}}, + \item \tcode{R} models \tcode{ranges::\libconcept{sized_range}}, or \item \tcode{R} models \tcode{ranges::\libconcept{approximately_sized_range}} and \tcode{ranges::distance(rg) <= ranges::reserve_hint(rg)} is \tcode{true}, or \item \tcode{R} models \tcode{ranges::\libconcept{forward_range}}. \end{itemize}