diff --git a/src/constraints.tex b/src/constraints.tex
index 7b01213..fe1dd82 100644
--- a/src/constraints.tex
+++ b/src/constraints.tex
@@ -54,13 +54,11 @@
\enternote
The satisfaction of constraints on class templates, alias templates,
and variable templates is required when referring to a template specialization
-(\ref{temp.names}). The satisfaction of constraints on functions and
+(\ref{temp.names}).
+%
+The satisfaction of constraints on functions and
function templates is required during overload resolution
-(\ref{over.match.viable}). The satisfaction of constraints introduced by
-\grammarterm{constrained-type-specifier}{s} (\ref{dcl.spec.auto.constr})
-in the type of a variable or declared return type of a function is
-required when values are deduced for their corresponding placeholders
-(\ref{dcl.spec.auto}).
+(\ref{over.match.viable}).
\exitnote
%
Determining if a constraint is satisfied entails the substitution
@@ -199,10 +197,7 @@
\enternote
A predicate constraint is introduced by the \grammarterm{constraint-expression}
of a
-\grammarterm{requires-clause} (\ref{temp.constr.decl}),
-or as the associated constraint of a
-\grammarterm{constrained-parameter} (\ref{temp.param}) or
-\grammarterm{template-introduction} (\ref{temp.intro}).
+\grammarterm{requires-clause} (\ref{temp.constr.decl}).
\exitnote
%
After substitution, \tcode{E} shall have type \tcode{bool}.
@@ -556,11 +551,8 @@
\pnum
Constraints can also be associated with a declaration through the use of
-\grammarterm{template-introduction}{}s,
\grammarterm{constrained-parameter}{}s in a
-\grammarterm{template-parameter-list}, and
-\grammarterm{constrained-type-specifier}{}s in the parameter-type-list
-of a function template.
+\grammarterm{template-parameter-list}.
%
Each of these forms introduces additional \grammarterm{constraint-expression}{s}
that are used to constrain the declaration.
@@ -678,32 +670,13 @@
%
First, create a new expression \tcode{E} by replacing all
subexpressions in \tcode{X} that refer to concepts with their
-corresponding definitions. In particular,
-%
-\begin{xaddedblock}
+corresponding definitions. That is,
replace all \grammarterm{id-expression}{s} of the form
\tcode{C}, where \tcode{C} is a concept with the
result of substituting the template arguments \tcode{A$1$, A$2$, ..., A$N$}
into the \grammarterm{constraint-expression} of \tcode{C}.
-\end{xaddedblock}
-%
-\begin{xremovedblock}
-\begin{itemize}
-\item replace all function calls of the form
-\tcode{C()}, where \tcode{C} refers to the function
-concept \tcode{D} (\ref{dcl.spec.concept}) selected by the rules for concept
-resolution (\ref{temp.constr.resolve}), with the result of substituting
-\tcode{A$1$, A$2$, ..., A$N$} into the expression returned by \tcode{D}, and
-
-\item replace all \grammarterm{id-expression}{s} of the form
-\tcode{C}, where \tcode{C} is the variable
-concept \tcode{D} (\ref{dcl.spec.concept}) selected by the rules for concept
-resolution (\ref{temp.constr.resolve}), with the result of substituting
-\tcode{A$1$, A$2$, ..., A$N$} into the initializer of \tcode{D}.
-\end{itemize}
-\end{xremovedblock}
%
-If \xremoved{any such} \xadded{that} substitution fails, the program is ill-formed.
+If that substitution fails, the program is ill-formed.
%
Second, transform the expression \tcode{E} into a constraint as follows:
\begin{itemize}
@@ -756,10 +729,10 @@
%
\enterexample
\begin{codeblock}
-template concept bool C1() { return sizeof(T) == 1; }
-template concept bool C2 = C1() && 1 == 2;
-template concept bool C3 = requires { typename T::type; };
-template concept bool C4 = requires (T x) { ++x; }
+template concept C = sizeof(T) == 1;
+template concept C2 = C1() && 1 == 2;
+template concept C3 = requires { typename T::type; };
+template concept C4 = requires (T x) { ++x; }
template void f1(T); // \#1
template void f2(T); // \#2
@@ -915,132 +888,3 @@
\end{addedblock}
\end{quote}
-
-%%
-%% Resolution of qualified references to concepts
-%%
-\rSec2[temp.constr.resolve]{Resolution of qualified references to concepts}
-
-Remove this section. Concept definitions can no longer overload.
-
-\begin{quote}
-\begin{xremovedblock}
-\pnum
-\defn{Concept resolution} is the process of selecting a concept
-from a set of concept definitions referred to by a
-\grammarterm{qualified-concept-name},
-%
-or from a set of declarations including one or more concept definitions
-referred to by a \grammarterm{simple-template-id} or a \grammarterm{qualified-id}
-whose \grammarterm{unqualified-id} is a \grammarterm{simple-template-id}.
-%
-Concept resolution is performed when such a name appears
-\begin{itemize}
-\item as a \grammarterm{constrained-type-specifier} (\ref{dcl.spec.auto.constr}),
-\item in a \grammarterm{constrained-parameter} (\ref{temp.param}),
-\item in a \grammarterm{template-introduction} (\ref{temp.intro}), or
-\item within a \grammarterm{constraint-expression} (\ref{temp.constr.decl}).
-\end{itemize}
-Within such a name, let \tcode{C} be the \grammarterm{concept-name} or
-\grammarterm{template-name} that refers to the set of concept definitions.
-
-\pnum
-The selection of a concept from this set is done by matching the
-template parameters of each concept in that set to a sequence of template
-arguments and \defn{wildcard}{s}.
-%
-This sequence is called the \defn{concept argument list}, and its elements
-are called \defn{concept argument}{s}.
-%
-For the purpose this matching, a wildcard can match a template
-parameter of any kind (type, non-type, template) as described below.
-
-\pnum
-The method for determining the concept argument list depends on the
-context in which \tcode{C} appears.
-%
-\begin{itemize}
-\item If \tcode{C} is part of a \grammarterm{constrained-type-specifier} or
-\grammarterm{constrained-parameter},
-then
- \begin{itemize}
- \item if \tcode{C} is a \grammarterm{constrained-type-name}, the concept
- argument list is comprised of a single wildcard, or
- \item if \tcode{C} is the \grammarterm{concept-name} of a
- \grammarterm{partial-concept-id}, the concept argument list is comprised of a
- single wildcard followed by the \grammarterm{template-argument}{s} of that
- \grammarterm{partial-concept-id}.
- \end{itemize}
-
-\item If \tcode{C} is the \grammarterm{concept-name} in a
-\grammarterm{template-introduction}. the concept argument list is a sequence
-of wildcards of the same length as the \grammarterm{introduction-list} of
-the \grammarterm{template-introduction}.
-
-\item If \tcode{C} appears as a \grammarterm{template-name} of a
-\grammarterm{simple-template-id}, the concept argument list is the sequence of
-\grammarterm{template-argument}{s} of that \grammarterm{simple-template-id}.
-\end{itemize}
-
-\pnum
-The selection of a concept from the set referred to by \tcode{C} is done
-by matching the concept argument list against the template parameter lists of
-each concept in that set.
-%
-For a concept \tcode{CC} in that set to be a viable selection, each
-argument in the concept argument list is matched against the corresponding
-template parameters of \tcode{CC}.
-%
-Default template arguments of \tcode{CC} (if any) are instantiated for each
-template parameter that does not correspond to a concept argument. Instantiated
-default arguments are appended to the concept argument list.
-%
-If the last declared template parameter of \tcode{CC} is not a parameter pack
-and the number of template parameters of \tcode{CC} is greater than the
-number of concept arguments, \tcode{CC} is not a viable selection.
-%
-Otherwise, concept arguments are matched to template parameters using the
-following rules:
-%
-\begin{itemize}
-\item a template argument matches a template parameter if and only if
-it matches in kind (type, non-type, template) and type according to the
-rules in \ref{temp.arg};
-
-\item a wildcard matches a template parameter of any kind;
-
-\item a template parameter pack (\cxxref{temp.variadic}), matches zero or more
-concept arguments, provided that each of those arguments matches the pattern
-of the template parameter pack using the rules above for matching matching
-concept arguments and template parameters.
-\end{itemize}
-%
-If any concept arguments do not match a corresponding template parameter,
-the concept \tcode{CC} is not a viable selection.
-%
-The concept selected by concept resolution shall be the single viable selection
-in the set of concepts referred by \tcode{C}.
-%
-\enterexample
-\begin{codeblock}
-template concept bool C1() { return true; } // \#1
-template concept bool C1() { return true; } // \#2
-template concept bool C2() { return true; }
-template concept bool C2() { return true; }
-template concept bool C3 = true;
-
-void f1(const C1*); // OK: \tcode{C1} selects \#1
-void f2(C1); // OK: \tcode{C1} selects \#2
-
-template T> struct S1; // error: no matching concept for \tcode{C2<0>},
- // mismatched template arguments
-template struct S2; // error: resolution of \tcode{C2} is ambiguous,
- // both concepts are viable
-
-C3{...Ts} void q1(); // OK: selects \tcode{C3}
-C3{T} void q2(); // OK: selects \tcode{C3}
-\end{codeblock}
-\exitexample
-
-\end{xremovedblock}
-\end{quote}
diff --git a/src/declarations.tex b/src/declarations.tex
index 86b0a95..605213b 100644
--- a/src/declarations.tex
+++ b/src/declarations.tex
@@ -30,992 +30,7 @@
\setcounter{Paras}{12}
\begin{quote}
\pnum
-A \grammarterm{concept-definition} shall only appear as a part of
-\grammarterm{template-declaration}.
+A \grammarterm{concept-definition} (\ref{temp.concept}) shall only appear as
+part of \grammarterm{template-declaration}.
\end{quote}
-%%
-%% Specifiers
-%%
-\rSec1[dcl.spec]{Specifiers}
-
-Remove this introduction.
-
-\begin{xremovedblock}
-Extend the \grammarterm{decl-specifier} production
-in paragraph 1 to include the \tcode{concept} specifier.
-
-\begin{quote}
-\pnum
-The specifiers that can be used in a declaration are
-
-\begin{bnf}
-\nontermdef{decl-specifier}\br
- storage-class-specifier\br
- defining-type-specifier\br
- function-specifier\br
- \terminal{friend}\br
- \terminal{typedef}\br
- \terminal{constexpr}\br
- \terminal{concept}
-\end{bnf}
-\end{quote}
-\end{xremovedblock}
-
-%%
-%% Type specifiers
-%%
-\setcounter{subsection}{6}
-\rSec2[dcl.type]{Type specifiers}
-
-
-%%
-%% Simple type specifiers
-%%
-\setcounter{subsubsection}{1}
-\rSec3[dcl.type.simple]{Simple type specifiers}
-
-Add \grammarterm{constrained-type-specifier}
-to the grammar for \grammarterm{simple-type-specifier}{}s.
-
-\begin{quote}
-\begin{bnf}
-\nontermdef{simple-type-specifier}\br
- nested-name-specifier\opt type-name\br
- nested-name-specifier \terminal{template} simple-template-id\br
- nested-name-specifier\opt template-name\br
- \terminal{char}\br
- \terminal{char16_t}\br
- \terminal{char32_t}\br
- \terminal{wchar_t}\br
- \terminal{bool}\br
- \terminal{short}\br
- \terminal{int}\br
- \terminal{long}\br
- \terminal{signed}\br
- \terminal{unsigned}\br
- \terminal{float}\br
- \terminal{double}\br
- \terminal{void}\br
- \terminal{auto}\br
- decltype-specifier\br
- \added{constrained-type-specifier}
-\end{bnf}
-\end{quote}
-
-Modify paragraph 2 to begin:
-
-\begin{quote}
-\setcounter{Paras}{1}
-\pnum
-\removed{The \grammarterm{simple-type-specifier} \tcode{auto} specifier is a
-placeholder for a type to be deduced (\ref{dcl.spec.auto}).}
-\added{The \grammarterm{simple-type-specifier} \tcode{auto} and
-\grammarterm{constrained-type-specifier}{s}
-are placeholders for values (type, non-type, template) to be deduced
-(\ref{dcl.spec.auto}).}
-\end{quote}
-
-Add \grammarterm{constrained-type-specifier}{s} to the table of
-\grammarterm{simple-type-specifier}{s} in Table~\ref{tab:simple.type.specifiers}.
-
-\renewcommand{\thetable}{\arabic{table}}
-\setcounter{table}{10}
-\begin{simpletypetable}
-{\grammarterm{simple-type-specifier}{s} and the types they specify}
-{tab:simple.type.specifiers}
-{ll}
-\topline
-Specifier(s) & Type \\ \capsep
-\grammarterm{type-name} & the type named \\
-\grammarterm{simple-template-id} & the type as defined in~\ref{temp.names} \\
-\multicolumn{2}{|c|}{\vdots} \\
-\tcode{auto} & placeholder for a type to be deduced \\
-\tcode{decltype(auto)} & placeholder for a type to be deduced \\
-\tcode{decltype(}\grammarterm{expression}\tcode{)} & the type as defined below \\
-\added{\grammarterm{constrained-type-specifier}} & \added{placeholder for value (type, non-type, template) to be deduced} \\
-\end{simpletypetable}
-
-
-%%
-%% Auto specifier
-%%
-\setcounter{subsubsection}{3}
-\rSec3[dcl.spec.auto]{\tcode{auto} specifier}
-
-Extend this section to allow for \grammarterm{constrained-type-specifier}{s}
-as a new syntax for designating placeholders. The meaning of
-\grammarterm{constrained-type-specifier}{s} is described in
-\ref{dcl.spec.auto.constr}.
-
-Replace paragraph 1 with the text below.
-
-\begin{quote}
-\begin{removedblock}
-\pnum
-The \tcode{auto} and \tcode{decltype(auto)} \grammarterm{type-specifier}{s}
-are used to
-designate a placeholder type that will be replaced later by deduction
-from an initializer. The \tcode{auto}
-\grammarterm{type-specifier} is also used to
-introduce a function type having a \grammarterm{trailing-return-type} or to
-signify that a lambda is a generic lambda (\cxxref{expr.prim.lambda.closure}).
-The \tcode{auto} \grammarterm{type-specifier} is also used to introduce a
-structured binding declaration (\cxxref{dcl.struct.bind}).
-\end{removedblock}
-\begin{addedblock}
-The \grammarterm{type-specifier}{}s \tcode{auto} and \tcode{decltype(auto)}
-and \grammarterm{constrained-type-specifier}{}s designate a placeholder
-(type, non-type, or template) that will be replaced later, either through
-deduction or an explicit specification.
-%
-The \tcode{auto} and \tcode{decltype(auto)} \grammarterm{type-specifier}{}s
-designate placeholder types; a \grammarterm{constrained-type-specifier} can
-also designate placeholders for values and templates.
-%
-\enternote
-The deduction of placeholders is done through the invention of template
-parameters as described in \ref{dcl.spec.auto.deduct} and \ref{dcl.fct}.
-\exitnote
-%
-Placeholders are also used to signify that a lambda is a generic lambda
-(\ref{expr.prim.lambda}), that a function declaration is an
-abbreviated function template (\ref{dcl.fct}), or that a
-\grammarterm{trailing-return-type} in a \grammarterm{compound-requirement}
-(\ref{expr.prim.req.compound}) introduces an argument deduction constraint
-(\ref{temp.constr.deduct}).
-%
-The \tcode{auto} \grammarterm{type-specifier} is also introduce a function type
-having a \grammarterm{trailing-return-type} or to introduce a structured binding
-declaration \cxxref{dcl.struct.bind}.
-%
-\enternote
-A \grammarterm{nested-name-specifier} can also include placeholders (\ref{expr.prim}).
-Replacements for those placeholders are determined according to the rules
-in this section.
-\exitnote
-%
-\end{addedblock}
-\end{quote}
-
-Modify paragraph 2 to allow \grammarterm{constrained-type-specifier}{}s
-with function declarators, except in the declared return type.
-
-\begin{quote}
-\pnum
-\removed{The placeholder type}\added{Placeholders} can appear with a function
-declarator in the \grammarterm{decl-specifier-seq}, \grammarterm{type-specifier-seq},
-\grammarterm{conversion-function-id}, or \grammarterm{trailing-return-type},
-in any context where such a declarator is valid.
-%
-If the function declarator includes a \grammarterm{trailing-return-type}
-(\ref{dcl.fct}), that \grammarterm{trailing-return-type} specifies the declared
-return type of the function. Otherwise, the function declarator shall declare
-a function.
-%
-If the declared return type of the function contains a placeholder, the
-return type of the function is deduced from non-discarded return statements,
-if any, in the body of the function (\ref{stmt.if}).
-%
-\added{
-In a function declarator of the form \tcode{auto D -> T} where
-\tcode{T} contains placeholders, the initial \tcode{auto} does
-not designate a placeholder.
-}
-\end{quote}
-
-
-Modify paragraph 3 to allow the use of \tcode{auto} within the
-parameter type of a lambda or function.
-
-\begin{quote}
-\pnum
-If \removed{the \tcode{auto} \grammarterm{type-specifier}} \added{a placeholder}
-appears \removed{as one of the \grammarterm{decl-specifier}{}s in the
-\grammarterm{decl-specifier-seq} of a \grammarterm{parameter-declaration}}
-\added{in a parameter type} of a \grammarterm{lambda-expression}, the lambda
-is a generic lambda
-(\ref{expr.prim.lambda}).
-%
-\enterexample
-\begin{codeblock}
-auto glambda = [](int i, auto a) { return i; }; // OK: a generic lambda
-\end{codeblock}
-\exitexample
-%
-\begin{addedblock}
-Similarly, if a placeholder appears in a parameter type of a function
-declaration, the function declaration declares an abbreviated function
-template (\ref{dcl.fct}).
-%
-\enterexample
-\begin{codeblock}
-void f(const auto&, int); // OK: an abbreviated function template
-\end{codeblock}
-\exitexample
-\end{addedblock}
-\end{quote}
-
-
-Add the following after paragraph 3 to describe when
-\grammarterm{constrained-type-specifier}{}s in the return type
-refer to template parameters.
-
-\begin{quote}
-\begin{addedblock}
-\pnum
-A \grammarterm{constrained-type-specifier} \tcode{C1} within the declared
-return type of an abbreviated function template declaration does not
-designate a placeholder if its introduced
-\grammarterm{constraint-expression} (\ref{dcl.spec.auto.constr})
-is determined to be equivalent, using the rules in \ref{temp.over.link}
-for comparing expressions, to the introduced
-\grammarterm{constraint-expression} for a
-\grammarterm{constrained-type-specifier} \tcode{C2} in the
-\grammarterm{parameter-declaration-clause} of that function declaration.
-%
-Instead, \tcode{C1} is replaced by the template parameter invented for
-\tcode{C2} (\ref{dcl.fct}).
-\enterexample
-\begin{codeblock}
-template concept bool C = true;
-
-template struct Tuple;
-
-C const& f1(C); // has one template parameter and no deduced return type
-Tuple f2(C); // has one template parameter and a deduced return type
-\end{codeblock}
-In the declaration \tcode{f1}, the \grammarterm{constraint-expression}
-introduced by the \grammarterm{constrained-type-specifier}{}s in the
-\grammarterm{parameter-declaration-clause} and return type are equivalent
-; they would both introduce the expression \tcode{C}, for some invented
-template parameter \tcode{T}.
-%
-In \tcode{f2}, the use of \tcode{C} in the return type would introduce the
-\grammarterm{constraint-expression} \tcode{(C \&\& ...)}, which is
-distinct from the \grammarterm{constraint-expression} \tcode{C} introduced
-by the invented \grammarterm{constrained-parameter} (\ref{temp.param}) for
-the \grammarterm{constrained-type-specifier} in the
-\grammarterm{parameter-declaration-clause} according to the rules in
-\ref{dcl.fct}.
-\exitexample
-\end{addedblock}
-\end{quote}
-
-
-Add the following after paragraph 4 to allow the use of \tcode{auto} in the
-\grammarterm{trailing-return-type} of a \grammarterm{compound-requirement}.
-Also, disallow the use of \tcode{decltype(auto)} with function parameters
-and deduction constraints.
-
-\begin{quote}
-\begin{addedblock}
-\pnum
-If a placeholder appears in the \grammarterm{trailing-return-type}
-of a \grammarterm{compound-requirement} in a \grammarterm{requires-expression}
-(\ref{expr.prim.req.compound}), that return type introduces an argument
-deduction constraint (\ref{temp.constr.deduct}).
-%
-\enterexample
-\begin{codeblock}
-template concept C =
- requires (T i) {
- {*i} -> const auto&; // OK: introduces an argument deduction constraint
- };
-}
-\end{codeblock}
-\exitexample
-
-\pnum
-The \tcode{decltype(auto)} \grammarterm{type-specifier} shall not appear
-in the declared type of a \grammarterm{parameter-declaration} or the
-\grammarterm{trailing-return-type} of a \grammarterm{compound-requirement}.
-\end{addedblock}
-\end{quote}
-
-
-Modify paragraph 4 in the \Cpp Standard (paragraph 7, here) to allow multiple
-placeholders within a variable declaration.
-
-\begin{quote}
-\pnum
-The type of a variable declared using
-\added{a placeholder}
-\removed{\tcode{auto} or \tcode{decltype(auto)}}
-is deduced from its initializer.
-%
-This use is allowed in an initializing declaration (\cxxref{11.6}) of a variable.
-%
-\removed{\tcode{auto} or \tcode{decltype(auto)} shall appear as one
-of the \grammarterm{decl-specifier}{}s in the \grammarterm{decl-specifier-seq} }
-%
-\added{
-A placeholder can appear anywhere in the declared type of the variable, but
-\tcode{decltype(auto)} shall appear only as one of the
-\grammarterm{decl-specifier}{}s of the \grammarterm{decl-specifier-seq}.
-}
-\removed{and the}\added{The} \grammarterm{decl-specifier-seq} \added{of such a
-variable} shall be followed by one or more \grammarterm{init-declarator}{}s,
-each of which shall be followed by a non-empty initializer.
-%
-In an initializer of the form
-\begin{codeblock}
-( expression-list )
-\end{codeblock}
-the \grammarterm{expression-list} shall be a single
-\grammarterm{assignment-expression}.
-%
-\enterexample
-\begin{codeblock}
-auto x = 5; // OK: \tcode{x} has type int
-const auto *v = &x, u = 6; // OK: \tcode{v} has type \tcode{const int*}, \tcode{u} has type \tcode{const int}
-static auto y = 0.0; // OK: \tcode{y} has type \tcode{double}
-auto int r; // error: \tcode{auto} is not a storage-class-specifier
-auto f() -> int; // OK: \tcode{f} returns \tcode{int}
-auto g() { return 0.0; } // OK: \tcode{g} returns \tcode{double}
-auto h(); // OK: \tcode{h}'s return type will be deduced when it is defined
-\end{codeblock}
-\exitexample
-\end{quote}
-
-Add the following declarations to the example in the previous paragraph.
-
-\begin{quote}
-\begin{addedblock}
-\begin{codeblock}
-struct N {
- template struct Wrap;
- template static Wrap make_wrap(T);
-};
-template struct Pair;
-template Pair make_pair(T, U);
-template struct Size { void f(int) { } };
-
-void (auto::* p1)(auto) = &Size<0>::f; // OK: \tcode{p1} has type \tcode{void(Size<0>::*)(int)}
-Pair p2 = make_pair(0, 'a'); // OK: \tcode{p2} has type \tcode{Pair}
-N::Wrap a = N::make_wrap(0.0); // OK: \tcode{a} has type \tcode{Wrap}
-auto::Wrap x = N::make_wrap(0); // error: failed to deduce value for \tcode{auto}
-Size y = Size<0>{}; // error: failed to deduce value for \tcode{auto}
-
-template concept bool C = true;
-template concept bool D = false;
-C z1 = 0; // OK: \tcode{z1} has type \tcode{int}
-D z2 = 0; // error: constraints not satisfied
-C cf1() { return 0.0; }; // OK: \tcode{cf1} returns \tcode{double}
-D cf2() { return 0.0; }; // error: constraints not satisfied
-auto cf3() -> C; // OK: \tcode{cf3}'s return type will be deduced when it is defined
-\end{codeblock}
-\end{addedblock}
-\end{quote}
-
-Update paragraph 6 in the \Cpp Standard (paragraph 8, here) to disallow
-placeholders in other contexts.
-
-\begin{quote}
-\pnum
-A program that uses \removed{\tcode{auto} or \tcode{decltype(auto)}}
-\added{placeholders} in a context not explicitly allowed in this section is
-ill-formed.
-\end{quote}
-
-
-Modify paragraph 7 in the \Cpp standard (paragraph 9, here) to read:
-
-\begin{quote}
-\pnum
-If the \grammarterm{init-declarator-list} contains more than one
-\grammarterm{init-declarator}, they shall all form declarations of variables.
-The type of each declared variable is determined is determined by placeholder
-type deduction (\ref{dcl.spec.auto.deduct}), and if
-the type that replaces \removed{the placeholder type}
-\added{the declared variable type or return type}
-is not the same in each deduction, the program is ill-formed.
-\end{quote}
-
-Add add the following examples to that paragraph.
-
-\begin{quote}
-\enterexample
-\begin{addedblock}
-\begin{codeblock}
-Pair p1 = make_pair(0, 0),
- *p2 = &p1; // OK: replacement type is \tcode{Pair}
-Pair p3 = make_pair(0, 'a'),
- p4 = make_pair('a', 0); // error: different replacement types
-\end{codeblock}
-\end{addedblock}
-\exitexample
-\end{quote}
-
-Modify paragraph 8 in the \Cpp Standard (paragraph 10, here) to read:
-\begin{quote}
-\pnum
-If a function with a declared return type that contains
-\removed{a placeholder type}
-\added{placeholders}
-has multiple non-discarded \tcode{return} statements,
-the return type is deduced for each such \tcode{return} statement.
-If the type deduced is not the same in each deduction,
-the program is ill-formed.
-\end{quote}
-
-Modify paragraph 9 in \Cpp Standard (paragraph 11, here) to read:
-
-\begin{quote}
-\pnum
-If a function with a declared return type that uses
-\removed{a placeholder type}
-\added{placeholders}
-has no non-discarded \tcode{return} statements, the return type is deduced as
-though from a \tcode{return} statement with no operand at the closing brace of
-the function body.
-\end{quote}
-
-Modify the first sentence of paragraph 10 in the \Cpp Standard (paragraph 12,
-here).
-
-\begin{quote}
-\pnum
-If the type of an entity with an undeduced placeholder \removed{type}
-is needed to determine the type of an expression, the program is
-ill-formed.
-\end{quote}
-
-Modify paragraph 12 in the \Cpp Standard (paragraph 14, here) to read:
-
-\begin{quote}
-\setcounter{Paras}{13}
-\pnum
-Redeclarations or specializations of a function or function template
-with a declared return type that uses
-\removed{a placeholder type}
-\added{placeholders} shall also use that placeholder,
-not a deduced type.
-%
-\added{If a placeholder is designated by a
-\grammarterm{constrained-type-specifier}, redeclarations or specializations
-shall use the same \grammarterm{constrained-type-specifier}.}
-\end{quote}
-
-Add the following examples to that paragraph.
-
-\begin{quote}
-\begin{addedblock}
-\begin{codeblock}
-template concept bool C1 = true;
-template concept bool C2 = true;
-
-template auto cf(T) -> C1; // \#1
-template C1 cf(T); // \#2, redeclaration of \#1
-template C2 cf(T); // error: redeclared with different placeholder
-\end{codeblock}
-\end{addedblock}
-\end{quote}
-
-Modify paragraph 13 in the \Cpp Standard (paragraph 15, here) to disallow
-placeholders in the return types of virtual functions.
-
-\begin{quote}
-\pnum
-A function declared with a return type that uses
-\removed{a placeholder type}
-\added{placeholders}
-shall not be virtual (\cxxref{class.virtual}).
-\end{quote}
-
-
-Modify paragraph 14 in the \Cpp Standard (paragraph 16, here) to read:
-
-\begin{quote}
-\pnum
-An explicit instantiation declaration (\ref{temp.explicit}) does not cause the
-instantiation of an entity declared using
-\removed{a placeholder type}
-\added{placeholders},
-but it also does not prevent that entity from being instantiated as needed to
-determine its type.
-\end{quote}
-
-
-%%%
-%%% Placeholder type deduction
-%%%
-\rSec4[dcl.spec.auto.deduct]{Placeholder type deduction}
-
-
-\begin{quote}
-\pnum
-\defn{Placeholder type deduction} is the process by which a type containing
-\removed{a placeholder type} \added{placeholders} is replaced by
-\removed{a deduced type} \added{deduced values (type, non-type, template)}.
-
-\pnum
-A type \tcode{T} containing a \removed{placeholder type}\added{placeholders},
-and a corresponding initializer \tcode{e},
-are determined as follows:
-
-\begin{itemize}
-\item
-for a non-discarded \tcode{return} statement that occurs
-in a function declared with a return type
-that contains \removed{a placeholder type}\added{placeholders},
-\tcode{T} is the declared return type
-and \tcode{e} is the operand of the \tcode{return} statement.
-If the \tcode{return} statement
-has no operand,
-then \tcode{e} is \tcode{void()};
-\item
-for a variable declared with a type
-that contains \removed{a placeholder type}\added{placeholders},
-\tcode{T} is the declared type of the variable
-and \tcode{e} is the initializer.
-If the initialization is direct-list-initialization,
-the initializer shall be a \grammarterm{braced-init-list}
-containing only a single \grammarterm{assignment-expression}
-and \tcode{e} is the \grammarterm{assignment-expression};
-\item
-for a non-type template parameter declared with a type
-that contains \removed{a placeholder type}\added{placeholders},
-\tcode{T} is the declared type of the non-type template parameter
-and \tcode{e} is the corresponding template argument.
-\end{itemize}
-%
-In the case of a \tcode{return} statement with no operand
-or with an operand of type \tcode{void},
-\tcode{T} shall be either
-\tcode{decltype(auto)} \removed{or}\added{,} \cv{}~\tcode{auto}%
-\added{, or a \grammarterm{constrained-type-specifier}}.
-
-% FIXME: This is a normative change.
-% \added{Otherwise, if the initialization is copy-list-initialization,
-% \tcode{T} shall be either \tcode{decltype(auto)}, \tcode{auto}, or a
-% \grammarterm{constrained-type-specifier}.}
-
-\pnum
-If the placeholder is the \tcode{auto} \grammarterm{type-specifier}
-\added{or a \grammarterm{constrained-type-specifier}}, the deduced type
-$\mathtt{T}'$ replacing \tcode{T} is determined using the rules for template
-argument deduction.
-%
-\removed{Obtain \tcode{P} from
-\tcode{T} by replacing the occurrences of \tcode{auto} with either a new
-invented type template parameter \tcode{U} or,
-if the initialization is copy-list-initialization, with
-\tcode{std::initializer_list}.}
-%
-\begin{addedblock}
-Otherwise, obtain a type \tcode{P} from \tcode{T} as follows:
-\begin{itemize}
-% FIXME: This doesn't do the right thing at all.
-\item if the initialization is a copy-list-initialization
-and a placeholder is a \grammarterm{decl-specifier} of the
-\grammarterm{decl-specifier-seq} of the variable declaration, replace that
-occurrence of the placeholder with \tcode{std::initializer_list}
-where \tcode{U} is an invented type template parameter;
-
-\item otherwise, replace each occurrence of a placeholder in the
-variable or return type with a new invented type template parameter
-according to the rules for inventing template parameters
-for placeholders in \ref{dcl.fct}.
-\end{itemize}
-\end{addedblock}
-%
-Deduce a value for \added{each} \removed{\tcode{U}}
-\added{invented type template parameter} using the rules
-of template argument deduction from a function
-call~(\cxxref{temp.deduct.call}),
-where \tcode{P} is a
-function template parameter type and
-the corresponding argument is \tcode{e}.
-%
-If the deduction fails, the declaration is ill-formed.
-%
-\added{If any placeholders in the declared type were introduced by a
-\grammarterm{constrained-type-specifier}, then define \tcode{C} to be a
-\grammarterm{constraint-expression} as follows:}
-\begin{addedblock}
-\begin{itemize}
-\item if there is single \grammarterm{constrained-type-specifier},
-then \tcode{C} is the \grammarterm{constraint-expression} introduced
-by the invented template \grammarterm{constrained-parameter} (\ref{temp.param})
-corresponding to that \grammarterm{constrained-type-specifier};
-\item otherwise, \tcode{C} is the \grammarterm{logical-and-expression}
-(\cxxref{expr.log.and}) whose operands are the
-\grammarterm{constraint-expression}{s} introduced by the invented
-template \grammarterm{constrained-parameter}{s} corresponding to
-each \grammarterm{constrained-type-specifier}, in order of appearance.
-\end{itemize}
-\end{addedblock}
-%
-\added{If the normalized constraint for \tcode{C} (\ref{temp.constr.decl})
-is not satisfied by the deduced values, the declaration is ill-formed.}
-%
-Otherwise, $\mathtt{T}'$ is obtained by
-substituting the deduced \removed{\tcode{U}}
-\added{values for the invented type template parameters}
-into \tcode{P}.
-
-\enterexample
-\begin{codeblock}
-auto x1 = { 1, 2 }; // \tcode{decltype(x1)} is \tcode{std::initializer_list}
-auto x2 = { 1, 2.0 }; // error: cannot deduce element type
-auto x3{ 1, 2 }; // error: not a single element
-auto x4 = { 3 }; // \tcode{decltype(x4)} is \tcode{std::initializer_list}
-auto x5{ 3 }; // \tcode{decltype(x5)} is \tcode{int}
-\end{codeblock}
-\exitexample
-
-\enterexample
-\begin{codeblock}
-const auto &i = expr;
-\end{codeblock}
-The type of \tcode{i} is the deduced type of the parameter \tcode{u} in
-the call \tcode{f(expr)} of the following invented function template:
-\begin{codeblock}
-template void f(const U& u);
-\end{codeblock}
-\exitexample
-\end{quote}
-
-Add the following to the first example in paragraph 4.
-
-\begin{quote}
-\begin{addedblock}
-\enterexample
-\begin{codeblock}
-template struct Vec { };
-template Vec make_vec(std::initializer_list) { return Vec{}; }
-
-template struct Tuple { };
-template auto make_tup(Ts... args) { return Tuple{}; }
-
-auto& x3 = *x1.begin(); // OK: \tcode{decltype(x3)} is \tcode{int\&}
-const auto* p = &x3; // OK: \tcode{decltype(p)} is \tcode{const int*}
-Vec v1 = make_vec({1, 2, 3}); // OK: \tcode{decltype(v1)} is \tcode{Vec}
-Vec v2 = {1, 2, 3}; // error: type deduction fails
-Tuple v3 = make_tup(0, 'a'); // OK: \tcode{decltype(v3)} is \tcode{Tuple}
-\end{codeblock}
-\exitexample
-\end{addedblock}
-\end{quote}
-
-
-Add the following after the second example in paragraph 4.
-
-\begin{quote}
-\begin{addedblock}
-\enterexample
-\begin{codeblock}
-template struct Pair;
-template Pair make_pair(T, U);
-
-struct S { void mfn(bool); } s;
-int fn(char, double);
-
-Pair p = make_pair(fn, &S::mfn);
-\end{codeblock}
-The declared type of \tcode{p} is the deduced type of the parameter
-\tcode{x} in the call of \tcode{g(make_pair(fn, \&S::mfn))} of the following
-invented function template:
-\begin{codeblock}
-template
-void g(Pair< T1(*)(T2, T3), T4 (T5::*)(T6)> x);
-\end{codeblock}
-\exitexample
-
-\enterexample
-\begin{codeblock}
-template concept bool C = true;
-
-const C* cv = expr;
-\end{codeblock}
-The type of \tcode{cv} is deduced from the parameter \tcode{p1} in the
-call \tcode{f1(expr)} of the following invented function:
-\begin{codeblock}
-template void f1(const T* p1);
-\end{codeblock}
-\exitexample
-
-\enterexample
-\begin{codeblock}
-auto cf(int) -> Pair { return expr; }
-\end{codeblock}
-The return type of \tcode{cf} is deduced from the parameter \tcode{p2} in the
-call \tcode{f2(expr)} of the following invented function:
-\begin{codeblock}
-template void f2(Pair);
-\end{codeblock}
-Both \grammarterm{constrained-type-specifier}{}s in the return type of
-\tcode{cf} correspond to the same invented template parameter.
-\exitexample
-\end{addedblock}
-\end{quote}
-
-
-%%
-%% Constrained type specifiers
-%%
-\rSec4[dcl.spec.auto.constr]{Constrained type specifiers}
-
-Add this section to \ref{dcl.spec.auto}.
-
-\begin{quote}
-\begin{addedblock}
-\pnum
-A \grammarterm{constrained-type-specifier} designates a placeholder
-(type, non-type, or template) and introduces an associated constraint
-(\ref{temp.constr.decl}).
-
-\begin{bnf}
-\nontermdef{constrained-type-specifier}\br
- qualified-concept-name
-
-\nontermdef{qualified-concept-name}\br
- nested-name-specifier\opt constrained-type-name
-
-\nontermdef{constrained-type-name}\br
- concept-name\br
- partial-concept-id
-
-\xremoved{
-\nontermdef{concept-name}\br
- identifier}
-
-\nontermdef{partial-concept-id}\br
- concept-name \terminal{<} template-argument-list\opt \terminal{>}
-\end{bnf}
-
-\enterexample
-\begin{codeblock}
-template concept C1 = false;
-template concept C2 = false;
-template class X> concept C3 = false;
-
-template class Array { };
-template class A> class Stack { };
-template class Alloc { };
-
-void f1(C1); // \tcode{C1} designates a placeholder type
-void f2(Array); // \tcode{C2} designates a placeholder for an integer value
-void f3(Stack); // \tcode{C3} designates a placeholder for a class template
-\end{codeblock}
-\exitexample
-
-\begin{xremovedblock}
-\pnum
-An identifier is a \grammarterm{concept-name} if it refers to a set of
-concept definitions (\ref{dcl.spec.concept}).
-%
-\enternote
-The set of concepts has multiple members only when referring to a set of
-overloaded function concepts. There is at most one member of this set when a
-\grammarterm{concept-name} refers to a variable concept.
-\exitnote
-%
-\enterexample
-\begin{codeblock}
-template concept bool C = true; // \#1
-template concept bool C = true; // \#2
-template concept bool D = true; // \#3
-
-void f(C); // OK: the set of concepts referred to by C includes both \#1 and \#2;
- // concept resolution (\ref{temp.constr.resolve}) selects \#1.
-void g(D); // OK: the concept-name \tcode{D} refers only to \#3
-\end{codeblock}
-\exitexample
-\end{xremovedblock}
-
-\pnum
-A \grammarterm{partial-concept-id} is a \grammarterm{concept-name} followed
-by a sequence of \grammarterm{template-argument}{}s.
-
-\enterexample
-\begin{codeblock}
-template concept bool Seq = true;
-
-void f1(Seq<3>); // OK
-void f2(Seq<>); // OK
-\end{codeblock}
-\exitexample
-
-\pnum
-\xremoved{The concept designated by a \grammarterm{constrained-type-specifier}
-is the one selected according to the rules for concept resolution in
-\ref{temp.constr.resolve}.}
-
-\pnum
-\enternote
-The \grammarterm{constraint-expression} introduced by a
-\grammarterm{constrained-type-name} is the one introduced by the invention of a
-\grammarterm{constrained-parameter} (\ref{temp.param}).
-%
-The rules for inventing template parameters corresponding to placeholders
-in the type of a variable or the declared return type of a function are
-described in \ref{dcl.spec.auto.deduct}.
-%
-The rules for inventing template parameters corresponding to placeholders
-in the \grammarterm{parameter-declaration-clause} of a
-\grammarterm{lambda-expression} (\ref{expr.prim.lambda})
-or function declaration (\ref{dcl.fct}) are described in
-\ref{dcl.fct}.
-%
-The rules for inventing a template parameter corresponding to placeholders
-in the \grammarterm{trailing-return-type} of a
-\grammarterm{compound-requirement} are described in
-\ref{temp.constr.deduct}.
-\exitnote
-
-\end{addedblock}
-\end{quote}
-
-
-%%
-%% concept specifier
-%%
-\rSec2[dcl.spec.concept]{\tcode{concept} specifier}
-
-Remove this section.
-
-\begin{quote}
-\begin{xremovedblock}
-Add this section to \ref{dcl.spec}.
-
-\begin{quote}
-\pnum
-The \tcode{concept} specifier shall be applied only to the
-definition of a function template or variable template, declared
-in namespace scope (\cxxref{basic.scope.namespace}).
-%
-A function template definition having the \tcode{concept}
-specifier is called a \defn{function concept}.
-%
-A function concept shall have no \grammarterm{exception-specification}
-and is treated as if it were specified with \tcode{noexcept(true)}
-(\cxxref{except.spec}).
-%
-When a function template is declared to be a concept, it shall be the only
-declaration of that function template in the translation unit.
-%
-A variable template definition having the \tcode{concept}
-specifier is called a \defn{variable concept}.
-%
-A \defn{concept definition} refers to either a function concept
-and its definition or a variable concept and its initializer.
-%
-\enterexample
-\begin{codeblock}
-template
- concept bool F1() { return true; } // OK: declares a function concept
-template
- concept bool F2(); // error: function concept is not a definition
-template
- constexpr bool F3();
-template
- concept bool F3() { return true; } // error: redeclaration of a function as a concept
-template
- concept bool V1 = true; // OK: declares a variable concept
-template
- concept bool V2; // error: variable concept with no initializer
-struct S {
- template
- static concept bool C = true; // error: concept declared in class scope
-};
-\end{codeblock}
-\exitexample
-
-\pnum
-Every concept definition is implicitly defined to be a
-\tcode{constexpr} declaration (\cxxref{dcl.constexpr}).
-%
-A concept definition shall not be declared with the
-\tcode{thread_local}, \tcode{inline}, \tcode{friend}, or
-\tcode{constexpr} specifiers, nor shall a concept definition have associated
-constraints (\ref{temp.constr.decl}).
-
-\pnum
-The definition of a function concept or the initializer of
-a variable concept shall not include a reference to the concept being
-declared.
-%
-\enterexample
-\begin{codeblock}
-template
- concept bool F() { return F(); } // error
-template
- concept bool V = V; // error
-\end{codeblock}
-\exitexample
-
-\pnum
-The first declared template parameter of a concept definition is its
-\defn{prototype parameter}.
-%
-A \defn{variadic concept} is a concept whose prototype parameter
-is a template parameter pack.
-
-\pnum
-A function concept has the following restrictions:
-\begin{itemize}
-\item No \grammarterm{function-specifier}{}s shall
- appear in its declaration (\cxxref{dcl.fct.spec}).
-
-\item The declared return type shall have the type \tcode{bool}.
-
-\item The declaration's parameter list shall be equivalent to an empty
- parameter list.
-
-\item The declaration shall have a \grammarterm{function-body} equivalent
-to \tcode{\{ return E; \}} where \tcode{E} is a
-\grammarterm{constraint-expression} (\ref{temp.constr.expr}).
-\end{itemize}
-%
-\enternote
-Return type deduction requires the instantiation of the function
-definition, but concept definitions are not instantiated; they
-are normalized (\ref{temp.constr.decl}).
-\exitnote
-%
-\enterexample
-\begin{codeblock}
-template
- concept int F1() { return 0; } // error: return type is not bool
-template
- concept auto F2() { return true; } // error: return type is deduced
-template
- concept bool F3(T) { return true; } // error: not an empty parameter list
-\end{codeblock}
-\exitexample
-
-\pnum
-A variable concept has the following restrictions:
-\begin{itemize}
-\item The declared type shall have the type \tcode{bool}.
-\item The declaration shall have an initializer.
-\item The initializer shall be a \grammarterm{constraint-expression}.
-\end{itemize}
-%
-\enterexample
-\begin{codeblock}
-template
- concept bool V1 = 3 + 4; // error: initializer is not a constraint-expression
-concept bool V2 = 0; // error: not a template
-
-template concept bool C = true;
-
-template
- concept bool V3 = true; // error: constrained template declared as a concept
-\end{codeblock}
-\exitexample
-
-\pnum
-A program shall not declare an explicit instantiation (\ref{temp.explicit}),
-an explicit specialization (\ref{temp.expl.spec}), or a partial specialization
-of a concept definition.
-%
-\enternote
-This prevents users from subverting the constraint system by providing a
-meaning for a concept that differs from its original definition.
-\exitnote
-\end{quote}
-\end{xremovedblock}
-\end{quote}
\ No newline at end of file
diff --git a/src/declarators.tex b/src/declarators.tex
index c3a691f..54bfcab 100644
--- a/src/declarators.tex
+++ b/src/declarators.tex
@@ -168,202 +168,3 @@
\added{or associated constraints (\ref{temp.constr.decl})}
are part of the function type.
\end{quote}
-
-Modify paragraph 17. Note that the footnote reference has been
-omitted.
-
-\begin{quote}
-\setcounter{Paras}{16}
-\pnum
-There is a syntactic ambiguity when an ellipsis occurs at the end of a
-\grammarterm{parameter-declaration-clause} without a preceding comma. In this
-case, the ellipsis is parsed as part of the \grammarterm{abstract-declarator}
-if the type of the parameter either names a template parameter pack that has
-not been expanded or contains
-\removed{\tcode{auto}}
-\added{a placeholder (\ref{dcl.spec.auto})};
-otherwise, it is parsed as part
-of the \grammarterm{parameter-declaration-clause}.
-\end{quote}
-
-Add the following paragraphs after paragraph 17.
-
-\begin{quote}
-\begin{addedblock}
-\pnum
-An \defn{abbreviated function template} is a function declaration whose
-parameter-type-list includes one or more placeholders (\ref{dcl.spec.auto}).
-%
-An abbreviated function template is equivalent to a function template
-(\ref{temp.fct}) whose \grammarterm{template-parameter-list}
-includes one invented \grammarterm{template-parameter} for each occurrence
-of a placeholder in the \grammarterm{parameter-declaration-clause},
-in order of appearance, according to the rules below.
-%
-\enternote
-Template parameters are also invented to deduce the type of a variable
-or the return type of a function when the declared type contains placeholders
-(\ref{dcl.spec.auto.deduct}).
-\exitnote
-
-\pnum
-Each template parameter is invented as follows.
-\begin{itemize}
-\item If the placeholder is designated by the \tcode{auto}
-\grammarterm{type-specifier}, then the invented template
-parameter is a type \grammarterm{template-parameter}.
-
-\item Otherwise, the placeholder is designated by a
-\grammarterm{constrained-type-specifier}, and the invented
-parameter is a \grammarterm{constrained-parameter} (\ref{temp.param}) whose
-\grammarterm{qualified-concept-name} is that of the
-\grammarterm{constrained-type-specifier}.
-
-\item If the placeholder appears in the \grammarterm{decl-specifier-seq} of a
-function parameter pack (\cxxref{temp.variadic}), or the
-\grammarterm{type-specifier-seq} of a \grammarterm{type-id} that is a pack
-expansion, the invented template parameter is a
-template parameter pack.
-\end{itemize}
-%
-All placeholders designated by \grammarterm{constrained-type-specifier}{}s
-whose corresponding \grammarterm{constrained-parameter}{s} would introduce
-equivalent \grammarterm{constraint-expression}{s} (\ref{temp.param}),
-using the rules for comparing expressions in \ref{temp.over.link}, have
-the same invented template parameter.
-%
-\enterexample
-\begin{codeblock}
-namespace N {
- template concept bool C = true;
-}
-template concept bool C = true;
-template concept bool D = true;
-template concept bool E = true;
-
-void abbr(C, D<0>);
-\end{codeblock}
-The \grammarterm{constrained-type-specifier}{}s \tcode{C} and \tcode{D<0>}
-correspond to distinct invented template parameters in the declaration
-of \tcode{abbr}.
-\begin{codeblock}
-void f0(C a, C b);
-\end{codeblock}
-The types of \tcode{a} and \tcode{b} are the same invented template
-type parameter.
-%
-\begin{codeblock}
-void f1(C& a, C* b);
-\end{codeblock}
-The type of \tcode{a} is a reference to an invented template type parameter
-\tcode{T}, and the type of \tcode{b} is a pointer to \tcode{T}.
-%
-\begin{codeblock}
-void f2(N::C a, C b);
-void f3(D<0> a, D<1> b);
-\end{codeblock}
-In both functions, the parameters \tcode{a} and
-\tcode{b} have different invented template type parameters.
-%
-\begin{codeblock}
-void f4(E a, E<> b, E<0> c);
-\end{codeblock}
-The types of \tcode{a}, \tcode{b}, and \tcode{c} are the same because the
-\grammarterm{constrained-type-specifier}{s} \tcode{E}, \tcode{E<>}, and
-\tcode{E<0>} all associate the \grammarterm{constraint-expression}
-\tcode{E}, where \tcode{T} is an invented template type parameter.
-%
-\begin{codeblock}
-void f5(C head, C... tail);
-\end{codeblock}
-The types of \tcode{head} and \tcode{tail} are different. Their
-respective introduced \grammarterm{constraint-expression}{s} are \tcode{C}
-and \tcode{(C \&\& ...)}, where \tcode{T} is the template parameter invented
-for \tcode{head} and \tcode{U} is the template parameter invented for
-\tcode{tail} (\ref{temp.param}).
-
-\pnum
-The adjusted function parameters of an abbreviated function template are derived
-from the \grammarterm{parameter-declaration-clause} by replacing each
-occurrence of a placeholder with the name of the corresponding invented
-\grammarterm{template-parameter}.
-%
-If the replacement of a placeholder with the name of a template parameter
-results in an invalid parameter declaration, the program is ill-formed.
-%
-\enternote
-Equivalent function template declarations declare the same function template
-(\ref{temp.over.link}).
-\exitnote
-%
-\enterexample
-\begin{codeblock}
-template class Vec { };
-template class Pair { };
-template class Tuple { };
-
-void f1(const auto&, auto);
-void f2(Vec...);
-void f3(Tuple);
-void f4(auto (auto::*)(auto));
-
-template void f1(const T&, U); // redeclaration of \tcode{f1}
-template void f2(Vec...); // redeclaration of \tcode{f2}
-template void f3(Tuple); // redeclaration of \tcode{f3}
-template void f4(T (U::*)(V)); // redeclaration of \tcode{f4}
-
-template concept bool C1 = true;
-template concept bool C2 = true;
-template concept bool C3 = true;
-template concept bool C4 = true;
-
-void g1(const C1*, C2&);
-void g2(Vec&);
-void g3(C1&...);
-void g4(Vec>);
-void g5(C4...);
-void g6(Tuple);
-void g7(C4 p);
-void g8(Tuple);
-
-template void g1(const T*, U&); // redeclaration of \tcode{g1}
-template void g2(Vec&); // redeclaration of \tcode{g2}
-template void g3(Ts&...); // redeclaration of \tcode{g3}
-template T> void g4(Vec); // redeclaration of \tcode{g4}
-template void g5(Ts...); // redeclaration of \tcode{g5}
-template void g6(Tuple); // redeclaration of \tcode{g6}
-template void g7(T); // redeclaration of \tcode{g7}
-template void g8(Tuple); // redeclaration of \tcode{g8}
-\end{codeblock}
-\exitexample
-%
-\enterexample
-\begin{codeblock}
-template concept bool Num = true;
-
-void h(Num*); // error: invalid type in parameter declaration
-\end{codeblock}
-The equivalent declaration would have this form:
-\begin{codeblock}
-template void h(N*); // error: invalid type
-\end{codeblock}
-\exitexample
-
-\pnum
-A function template can be an abbreviated function template. The
-invented \grammarterm{template-parameter}{}s are appended to the
-\grammarterm{template-parameter-list} after the explicitly declared
-\grammarterm{template-parameter}{}s.
-
-\enterexample
-\begin{codeblock}
-template class Array { };
-
-template void f(Array*);
-template void f(Array*); // OK: redeclaration of \tcode{f(Array*)}
-\end{codeblock}
-\exitexample
-\end{addedblock}
-\end{quote}
-
-
diff --git a/src/expressions.tex b/src/expressions.tex
index d62aa4a..db254fb 100644
--- a/src/expressions.tex
+++ b/src/expressions.tex
@@ -37,13 +37,11 @@
\setcounter{subsection}{3}
\rSec2[expr.prim.id]{Names}
-Add \xremoved{a new paragraph} \xadded{new paragraphs} to the end of this
-section.
-
-\setcounter{Paras}{2}
+Add new paragraphs to the end of this section.
\begin{quote}
-\begin{xaddedblock}
+\begin{addedblock}
+\setcounter{Paras}{2}
\pnum
A \grammarterm{id-expression} that denotes the specialization of a concept
(\ref{temp.concept}) result in a prvalue of type \tcode{bool}.
@@ -52,9 +50,12 @@
(\ref{temp.constr.decl}) \emph{constraint-expression} is satisfied according
to the rules in \ref{temp.constr.constr} and \tcode{false} otherwise.
\enterexample
+\begin{codeblock}
template concept C = true;
static_assert(C); // OK
+\end{codeblock}
\exitexample
+
\pnum
\enternote
A concept's constraints are also evaluated during the resolution of template
@@ -63,10 +64,9 @@
(\ref{temp.constr.order}).
\exitnote
-\end{xaddedblock}
+\end{addedblock}
\end{quote}
-% TODO: The wording "non-overloaded function declaration" is not right.
\begin{quote}
\begin{addedblock}
\pnum
@@ -90,168 +90,6 @@
\end{quote}
-\setcounter{subsubsection}{1}
-\rSec3[expr.prim.id.qual]{Qualified names}
-
-Add \tcode{auto} and \grammarterm{constrained-type-name} to the
-\grammarterm{nested-name-specifier} grammar.
-
-\begin{quote}
-\begin{bnf}
-\nontermdef{nested-name-specifier}\br
- \terminal{::}\br
- type-name \terminal{::}\br
- namespace-name \terminal{::}\br
- decltype-specifier \terminal{::}\br
- \added{\terminal{auto} \terminal{::}}\br
- \added{constrained-type-name \terminal{::}}\br
- nested-name-specifier identifier \terminal{::}\br
- nested-name-specifier \terminal{template}\opt \terminal{::}
-\end{bnf}
-\end{quote}
-
-Add a new paragraph at the end of this section.
-
-\begin{quote}
-\begin{addedblock}
-\setcounter{Paras}{5}
-\pnum
-In a \grammarterm{nested-name-specifier} of the form \tcode{auto::} or
-\tcode{C::}, where \tcode{C} is a \grammarterm{constrained-type-name},
-that \grammarterm{nested-name-specifier} designates a placeholder that
-will be replaced later according to the rules for placeholder deduction in
-\ref{dcl.spec.auto}.
-%
-If a placeholder designated by a \grammarterm{constrained-type-specifier}
-is not a placeholder type, the program is ill-formed.
-%
-\enternote
-A \grammarterm{constrained-type-specifier} can designate a placeholder for
-a non-type or template (\ref{dcl.spec.auto.constr}).
-\exitnote
-%
-The replacement type deduced for a placeholder shall be a class or
-enumeration type.
-%
-\enterexample
-\begin{codeblock}
-template concept bool C = sizeof(T) == sizeof(int);
-template concept bool D = true;
-
-struct S1 { int n; };
-struct S2 { char c; };
-struct S3 { struct X { using Y = int; }; };
-
-int auto::* p1 = &S1::n; // \tcode{auto} deduced as \tcode{S1}
-int D::* p2 = &S1::n; // error: \tcode{D} does not designate a placeholder type
-int C::* p3 = &S1::n; // OK: \tcode{C} deduced as \tcode{S1}
-char C::* p4 = &S2::c; // error: deduction fails because constraints are not satisfied
-
-void f(typename auto::X::Y);
-f(S1()); // error: \tcode{auto} cannot be deduced from \tcode{S1()}
-f(0); // OK
-\end{codeblock}
-In the declaration of \tcode{f}, the placeholder appears in a non-deduced
-context (\cxxref{temp.deduct.type}). It may be replaced later through the
-explicit specification of template arguments.
-\exitexample
-\end{addedblock}
-\end{quote}
-
-
-%%
-%% Lambda expressions
-%%
-\setcounter{subsection}{4}
-\rSec2[expr.prim.lambda]{Lambda expressions}
-
-Insert the following paragraph after paragraph 4 to define the
-term ``generic lambda''.
-
-\begin{quote}
-\begin{addedblock}
-\setcounter{Paras}{4}
-\pnum
-A \defn{generic lambda} is a \grammarterm{lambda-expression} where one
-or more placeholders (\ref{dcl.spec.auto}) appear in the parameter-type-list
-of the \grammarterm{lambda-declarator}.
-\end{addedblock}
-\end{quote}
-
-\rSec3[expr.prim.lambda.closure]{Closure types}
-
-Modify paragraph 3 so that the meaning of a generic lambda is defined
-in terms of its abbreviated member function template call operator.
-
-\begin{quote}
-The closure type for a non-generic
-\grammarterm{lambda-expression} has a public inline
-function call operator (\cxxref{over.call})
-whose parameters and return type are described by the
-\grammarterm{lambda-expression}'s
-\grammarterm{parameter-declaration-clause} and
-\grammarterm{trailing-return-type}, respectively.
-%
-\removed{
-For a generic lambda, the closure type has a public inline function call
-operator member template (\cxxref{temp.mem}) whose
-\grammarterm{template-parameter-list} consists of
-one invented type \grammarterm{template-parameter}
-for each occurrence of \tcode{auto} in the lambda's
-\grammarterm{parameter-declaration-clause}, in order
-of appearance.
-%
-The invented type \grammarterm{template-parameter} is
-a parameter pack if the corresponding
-\grammarterm{parameter-declaration declares} a
-function parameter pack (\ref{dcl.fct}).
-%
-The return type and function parameters of the function call operator
-template are derived from the
-\grammarterm{lambda-expression}'s
-\grammarterm{trailing-return-type} and
-\grammarterm{parameter-declaration-clause} by
-replacing each occurrence of \tcode{auto} in the
-\grammarterm{decl-specifier}{}s of the
-\grammarterm{parameter-declaration-clause}
-with the name of the corresponding invented template-parameter.
-}
-%
-\added{
-The closure type for a generic lambda has a public inline function call
-operator member template that is an abbreviated function template whose
-parameters and return type are derived from the
-\grammarterm{lambda-expression}'s
-\grammarterm{parameter-declaration-clause} and
-\grammarterm{trailing-return-type} according to the
-rules in (\ref{dcl.fct}).
-}
-\end{quote}
-
-Add the following example after those in paragraph 3 in the
-\Cpp Standard.
-
-\begin{quote}
-\begin{addedblock}
-\enterexample
-\begin{codeblock}
-template concept bool C = true;
-
-auto gl = [](C& a, C* b) { a = *b; }; // OK: denotes a generic lambda
-
-struct Fun {
- auto operator()(C& a, C* b) const { a = *b; }
-} fun;
-\end{codeblock}
-\tcode{C} is a
-\grammarterm{constrained-type-specifier},
-signifying that the lambda is generic. The generic lambda \tcode{gl}
-and the function object \tcode{fun} have equivalent behavior when
-called with the same arguments.
-\exitexample
-\end{addedblock}
-\end{quote}
-
%%
%% Requires expressions
%%
diff --git a/src/templates.tex b/src/templates.tex
index 7744729..058943d 100644
--- a/src/templates.tex
+++ b/src/templates.tex
@@ -17,7 +17,6 @@
\nontermdef{template-declaration}\br
\terminal{template} \terminal{<} template-parameter-list \terminal{>}
\added{requires-clause\opt} declaration\br
- \added{template-introduction declaration}
\begin{addedblock}
\nontermdef{requires-clause}\br
@@ -26,24 +25,6 @@
\end{bnf}
\end{quote}
-
-Add the following paragraphs after paragraph 6.
-
-\begin{quote}
-\begin{addedblock}
-\setcounter{Paras}{6}
-\pnum
-A \grammarterm{template-declaration} is written in terms of its template
-parameters. These parameters are declared explicitly in a
-\grammarterm{template-parameter-list} (\ref{temp.param}), or they are
-introduced by a \grammarterm{template-introduction} (\ref{temp.intro}).
-%
-The optional \grammarterm{requires-clause} following a
-\grammarterm{template-parameter-list} allows the specification of
-constraints (\ref{temp.constr.decl}) on template arguments (\ref{temp.arg}).
-\end{addedblock}
-\end{quote}
-
%%
%% Template parameters
@@ -84,6 +65,13 @@
qualified-concept-name ... identifier\opt\br
qualified-concept-name identifier\opt default-template-argument\opt
+\nontermdef{qualified-concept-name}\br
+ nested-name-specifier\opt concept-name\br
+ nested-name-specifier\opt partial-concept-id
+
+\nontermdef{partial-concept-id}\br
+ concept-name \terminal{<} template-argument-list\opt \terminal{>}
+
\nontermdef{default-template-argument}\br
\terminal{=} type-id\br
\terminal{=} id-expression\br
@@ -92,7 +80,7 @@
\end{bnf}
\end{quote}
-Insert a new paragraph after paragraph 1.
+Insert new paragraphs after paragraph 1.
\begin{quote}
\begin{addedblock}
@@ -101,9 +89,11 @@
declaration of a \grammarterm{constrained-parameter} and a
\grammarterm{parameter-declaration}.
%
-If the \grammarterm{type-specifier-seq} of a \grammarterm{parameter-declaration}
-is a \grammarterm{constrained-type-specifier} (\ref{dcl.spec.auto.constr}),
-then the \grammarterm{template-parameter} is a \grammarterm{constrained-parameter}.
+If the \grammarterm{type-specifier-seq} of a
+\grammarterm{parameter-declaration}
+is a \grammarterm{constrained-type-specifier},
+then the \grammarterm{template-parameter} is a
+\grammarterm{constrained-parameter}.
\end{addedblock}
\end{quote}
@@ -117,12 +107,10 @@
A \grammarterm{constrained-parameter} declares a template parameter whose
kind (type, non-type, template) and type match that of the prototype parameter
of the concept designated by the \grammarterm{qualified-concept-name}
-(\ref{dcl.spec.auto.constr}) in the \grammarterm{constrained-parameter}.
-%
-\xremoved{The designated concept is selected by the rules for concept resolution
-described in \ref{temp.constr.resolve}.}
+in the \grammarterm{constrained-parameter}.
%
-Let \tcode{X} be the prototype parameter of the designated concept.
+Let \tcode{X} be the prototype parameter of the concept designated by the
+\grammarterm{concept-name} (\ref{temp.concept}).
%
The declared template parameter is determined by the kind of \tcode{X}
(type, non-type, template) and the optional ellipsis in the
@@ -173,27 +161,16 @@
\begin{itemize}
\item First, form a template argument \tcode{A} from \tcode{P}. If \tcode{P}
declares a template parameter pack (\cxxref{temp.variadic})
-and \tcode{C} is a variadic concept (\ref{dcl.spec.concept}), then \tcode{A} is
+and \tcode{C} is a variadic concept (\ref{temp.concept}), then \tcode{A} is
the pack expansion \tcode{P...}. Otherwise, \tcode{A} is the
\grammarterm{id-expression} \tcode{P}.
% FIXME: This does not guarantee that the expression has the same
% namespace qualification as Q.
-\item \xadded{Then, form an \grammarterm{id-expression} \tcode{E} as follows.
+\item Then, form an \grammarterm{id-expression} \tcode{E} as follows.
If \tcode{Q} is a \grammarterm{concept-name}, then \tcode{E} is \tcode{C}.
Otherwise, \tcode{Q} is a \grammarterm{partial-concept-id} of the form
- \tcode{C}, and \tcode{E} is \tcode{C}.}
-
-\item \xremoved{Then, form a \grammarterm{template-id} \tcode{TT} based on the
-\grammarterm{qualified-concept-name} \tcode{Q}. If \tcode{Q} is
-a \grammarterm{concept-name}, then \tcode{TT} is \tcode{C}. Otherwise,
-\tcode{Q} is a \grammarterm{partial-concept-id} of the form
-\tcode{C}, and \tcode{TT} is \tcode{C}}.
-
-\item \xremoved{Then, form an \grammarterm{expression} \tcode{E} as follows.
-If \tcode{C} is a variable concept (\ref{dcl.spec.concept}), then \tcode{E} is the
-\grammarterm{id-expression} \tcode{TT}. Otherwise, \tcode{C} is a function
-concept and \tcode{E} is the function call \tcode{TT()}}.
+ \tcode{C}, and \tcode{E} is \tcode{C}.
\item Finally, if \tcode{P} declares a template parameter pack and
\tcode{C} is not a variadic concept, \tcode{E} is adjusted to be the
@@ -247,187 +224,6 @@
\end{quote}
-%%
-%% Introduction of template parameters
-%%
-\rSec1[temp.intro]{Introduction of template parameters}
-
-Add this section after \ref{temp.param}.
-
-\begin{quote}
-\begin{addedblock}
-\pnum
-A \grammarterm{template-introduction} provides a concise way of declaring
-templates.
-
-\begin{bnf}
-\nontermdef{template-introduction}\br
- qualified-concept-name \terminal{\{} introduction-list \terminal{\}}
-
-\nontermdef{introduction-list}\br
- introduced-parameter\br
- introduction-list \terminal{,} introduced-parameter
-
-\nontermdef{introduced-parameter}\br
- \terminal{...}\opt identifier
-\end{bnf}
-
-A \grammarterm{template-introduction} declares a template whose
-sequence of \grammarterm{template-parameter}{s} are derived from a
-\grammarterm{qualified-concept-name} (\ref{dcl.spec.auto.constr}) and the
-sequence of \grammarterm{introduced-parameter}{s} in its
-\grammarterm{introduction-list}.
-
-\pnum
-\xremoved{The concept designated by the \grammarterm{qualified-concept-name} is selected
-by the concept resolution rules described in \ref{temp.constr.resolve}. Let
-\tcode{C} be the designated concept.
-%
-The template parameters declared by a \grammarterm{template-introduction}
-are derived from its \grammarterm{introduced-parameter}{s} and the
-template parameter declarations of \tcode{C} to which those
-\grammarterm{introduced-parameter}{s} are matched as wildcards according to
-the rules in \ref{temp.constr.resolve}.}
-%
-\xadded{
-The template parameters declared by a \grammarterm{template-introduction}
-are derived from the \grammarterm{qualified-concept-name} and its template
-parameters using the following rules.
-}
-%
-For each \grammarterm{introduced-parameter} \tcode{I}, declare a template
-parameter using the following rules:
-\begin{itemize}
-\item Let \tcode{P} be the template parameter declaration in \tcode{C}
- corresponding to \tcode{I}. If \tcode{P} does not declare a template
- parameter pack (\cxxref{temp.variadic}), \tcode{I} shall not include
- an ellipsis.
-
-\item If \tcode{P} declares a template parameter pack, adjust \tcode{P}
- to be the pattern of that pack.
-
-\item Declare a template parameter according to the rules for declaring a
- \grammarterm{constrained-parameter} in \ref{temp.param}, using
- \tcode{P} as the prototype parameter and with no ellipsis.
-
-\item If \tcode{I} includes an ellipsis, then the declared template parameter
- is a template parameter pack.
-\end{itemize}
-%
-\enterexample
-\begin{codeblock}
-template concept C1 = true;
-template class X> concept C2 = true;
-template concept C3 = true;
-
-C1{A, B, ...C} // OK: \tcode{A} is declared as \tcode{typename A},
- struct S1; // \tcode{B} is declared as \tcode{int B}, and
- // \tcode{C} is declared as \tcode{typename ... C}
-
-C2{T} void f(); // OK: \tcode{T} is declared as \tcode{template class T}
-C2{...Ts} void g(); // error: the template parameter corresponding to \tcode{Ts}
- // is not a template parameter pack
-
-C3{T} struct S2; // OK: \tcode{T} is declared as \tcode{typename T}
-C3{...Ts} struct S2; // OK: \tcode{Ts} is declared as \tcode{typename ... Ts}
-\end{codeblock}
-\exitexample
-
-
-\pnum
-A concept referred to by a \grammarterm{qualified-concept-name} may have
-template parameters with default template arguments. An
-\grammarterm{introduction-list} may omit \grammarterm{identifier}{}s for a
-corresponding template parameter if it has a default argument.
-%
-Only the \grammarterm{introduced-parameter}{}s are declared as template
-parameters.
-%
-\enterexample
-\begin{codeblock}
-template concept C = true;
-
-C{T} void f(T); // OK: \tcode{f(T)} is a function template with
- // a single template type parameter \tcode{T}
-\end{codeblock}
-\exitexample
-
-\pnum
-An introduced template parameter does not have a default template argument
-even if its corresponding template parameter does.
-%
-\enterexample
-\begin{codeblock}
-template concept P = true;
-
-P{T, N} struct Array { };
-
-Array s1; // OK
-Array s2; // error: \tcode{Array} takes two template arguments
-\end{codeblock}
-\exitexample
-
-\pnum
-A \grammarterm{template-introduction} introduces a
-\grammarterm{constraint-expression} (\ref{temp.constr.decl}). This
-expression is derived from the \grammarterm{qualified-concept-name}
-\tcode{C} in the \grammarterm{template-introduction} and the sequence of
-\grammarterm{introduced-parameter}{s}.
-
-\begin{itemize}
-\item First, form a sequence of template arguments \tcode{A1, A2, ..., A$N$}
-corresponding to the \grammarterm{introduced-parameter}{s}
-\tcode{P1, P2, ..., P$N$}.
-%
-For each \grammarterm{introduced-parameter} \tcode{P}, form a corresponding
-template argument \tcode{A} as follows. If \tcode{P} includes an ellipsis,
-then \tcode{A} is the pack expansion \tcode{P...} (\cxxref{temp.variadic}).
-Otherwise, \tcode{A} is the \grammarterm{id-expression} \tcode{P}.
-
-% FIXME: This doesn't guarantee that the E has the same namespace specifier
-% as the qualified form.
-\item \xremoved{Then, form an expression \tcode{E} as follows. If \tcode{C} designates
-a variable concept (\ref{dcl.spec.concept}), then \tcode{E} is the
-\grammarterm{id-expression}
-\tcode{C}. Otherwise, \tcode{C} designates a function concept and
-\tcode{E} is the function call \tcode{C()}.}
-\xadded{Then, form a \grammarterm{id-expression} \tcode{E} as
-\tcode{C}.}
-\end{itemize}
-%
-\tcode{E} is the introduced \grammarterm{constraint-expression}.
-%
-\enterexample
-\begin{codeblock}
-template concept C1 = true;
-template concept C3 = true;
-
-C1{A, B} struct s1; // associates \tcode{C1}
-C2{...Ts} struct s3; // associates \tcode{C2}
-C2{X, ...Y} struct s4; // associates \tcode{C2}
-\end{codeblock}
-\exitexample
-
-\pnum
-A template declared by a \grammarterm{template-introduction} can also be
-an abbreviated function template (\ref{dcl.fct}).
-%
-The invented template parameters introduced by the placeholders in the
-abbreviated function template are appended to the list of template parameters
-declared by the \grammarterm{template-introduction}.
-%
-\enterexample
-\begin{codeblock}
-template concept C1 = true;
-
-C1{T} void f(T, auto);
-template void f(T, U); // OK: redeclaration of \tcode{f(T, auto)}
-\end{codeblock}
-%
-\exitexample
-\end{addedblock}
-\end{quote}
-
%%
%% Names of template specializations
@@ -993,10 +789,11 @@
%%
\rSec2[temp.concept]{Concept definitions}
-Add the following paragraph.
+Add this section after \cxxref{temp.alias} in the \Cpp Standard.
\begin{quote}
-\begin{xaddedblock}
+\begin{addedblock}
+
\pnum A \defn{concept} defines constraints on its template arguments.
\begin{bnf}
@@ -1010,22 +807,6 @@
\pnum A \grammarterm{concept-definition} declares its \grammarterm{identifier}
to be a concept. The name of the concept is a \grammarterm{concept-name}.
-\enterexample
-\begin{codeblock}
-template
-concept C = requires(T x) {
- { f(x) } -> T;
-};
-template
- requires C
-T g(T x) { return f(x); }
-int f(int n) { return n; }
-void fn() {
- g(0); // OK: \tcode{C} is satisfied
- g((void*)0); // error: cannot call \tcode{g}, \tcode{C} is not satisfied
-}
-\end{codeblock}
-\exitexample
\pnum
A \grammarterm{concept-definition} shall appear in the global scope or in a
@@ -1037,8 +818,8 @@
specializes (\ref{temp.expl.spec}), or partially
specializes a concept is ill-formed.
\enternote
-\emph{id-expression}s that denote a concept specialization are evaluated as
-expressions (\ref{expr.prim.id}).
+\emph{id-expression}{}s that denote a concept specialization are evaluated
+(\ref{expr.prim.id}).
\exitnote
\pnum
@@ -1046,7 +827,7 @@
\defn{prototype parameter}.
A \defn{variadic concept} is a concept whose prototype parameter is a template
parameter pack.
-\end{xaddedblock}
+\end{addedblock}
\end{quote}
%%