Skip to content

Commit

Permalink
P2662R3 Pack Indexing
Browse files Browse the repository at this point in the history
  • Loading branch information
jensmaurer committed Nov 12, 2023
1 parent 38dfe3d commit 8f02007
Show file tree
Hide file tree
Showing 7 changed files with 145 additions and 20 deletions.
2 changes: 1 addition & 1 deletion source/basic.tex
Original file line number Diff line number Diff line change
Expand Up @@ -2170,7 +2170,7 @@
followed by a \tcode{::} scope resolution operator
considers only
namespaces, types, and templates whose specializations are types.
If a name, \grammarterm{template-id}, or \grammarterm{decltype-specifier}
If a name, \grammarterm{template-id}, or \grammarterm{computed-type-specifier}
is followed by a \tcode{::},
it shall designate a namespace, class, enumeration, or dependent type,
and the \tcode{::} is never interpreted as
Expand Down
12 changes: 6 additions & 6 deletions source/classes.tex
Original file line number Diff line number Diff line change
Expand Up @@ -2188,7 +2188,7 @@
In an explicit destructor call, the destructor is specified by a
\tcode{\~{}}
followed by a
\grammarterm{type-name} or \grammarterm{decltype-specifier}
\grammarterm{type-name} or \grammarterm{computed-type-specifier}
that denotes the destructor's class type.
The invocation of a destructor is subject to the usual rules for member
functions\iref{class.mfct};
Expand Down Expand Up @@ -3397,16 +3397,16 @@

\begin{bnf}
\nontermdef{base-specifier}\br
\opt{attribute-specifier-seq} class-or-decltype\br
\opt{attribute-specifier-seq} \keyword{virtual} \opt{access-specifier} class-or-decltype\br
\opt{attribute-specifier-seq} access-specifier \opt{\keyword{virtual}} class-or-decltype
\opt{attribute-specifier-seq} class-or-computed-type-specifier\br
\opt{attribute-specifier-seq} \keyword{virtual} \opt{access-specifier} class-or-computed-type-specifier\br
\opt{attribute-specifier-seq} access-specifier \opt{\keyword{virtual}} class-or-computed-type-specifier
\end{bnf}

\begin{bnf}
\nontermdef{class-or-decltype}\br
\nontermdef{class-or-computed-type-specifier}\br
\opt{nested-name-specifier} type-name\br
nested-name-specifier \keyword{template} simple-template-id\br
decltype-specifier
computed-type-specifier
\end{bnf}

\indextext{specifier access|see{access specifier}}%
Expand Down
23 changes: 23 additions & 0 deletions source/compatibility.tex
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,29 @@
bool b = ne({2,3}, {1,2,3}); // unspecified result; previously \tcode{false}
\end{codeblock}

\rSec2[diff.cpp23.dcl.dcl]{\ref{dcl.dcl}: Declarations}

\diffref{decl.array}
\change
Previously, \tcode{T...[n]} would declare a pack of function parameters.
\tcode{T...[n]} is now a \grammarterm{pack-index-specifier}.
\rationale
Improve the handling of packs.
\effect
Valid \CppXXIII{} code that declares a pack of parameters
without specifying a \grammarterm{declarator-id} becomes ill-formed.
For example:
\begin{codeblock}
template <typename... T>
void f(T... [1]);
template <typename... T>
void g(T... ptr[1]);
int main() {
f<int, double>(nullptr, nullptr); // ill-formed, previously \tcode{void f<int, double>(int [1], double [1])}
g<int, double>(nullptr, nullptr); // ok
}
\end{codeblock}

\rSec2[diff.cpp23.strings]{\ref{strings}: strings library}

\diffref{string.conversions}
Expand Down
43 changes: 41 additions & 2 deletions source/declarations.tex
Original file line number Diff line number Diff line change
Expand Up @@ -1285,7 +1285,7 @@
\nontermdef{simple-type-specifier}\br
\opt{nested-name-specifier} type-name\br
nested-name-specifier \keyword{template} simple-template-id\br
decltype-specifier\br
computed-type-specifier\br
placeholder-type-specifier\br
\opt{nested-name-specifier} template-name\br
\keyword{char}\br
Expand All @@ -1311,6 +1311,12 @@
typedef-name
\end{bnf}

\begin{bnf}
\nontermdef{computed-type-specifier}\br
decltype-specifier\br
pack-index-specifier
\end{bnf}

\pnum
\indextext{component name}
The component names of a \grammarterm{simple-type-specifier} are those of its
Expand Down Expand Up @@ -1382,6 +1388,7 @@
\grammarterm{type-name} & the type named \\
\grammarterm{simple-template-id} & the type as defined in~\ref{temp.names}\\
\grammarterm{decltype-specifier} & the type as defined in~\ref{dcl.type.decltype}\\
\grammarterm{pack-index-specifier} & the type as defined in~\ref{dcl.type.pack.index}\\
\grammarterm{placeholder-type-specifier}
& the type as defined in~\ref{dcl.spec.auto}\\
\grammarterm{template-name} & the type as defined in~\ref{dcl.type.class.deduct}\\
Expand Down Expand Up @@ -1431,6 +1438,32 @@
forces \tcode{char} objects to be signed; it is redundant in other contexts.
\end{note}

\rSec3[dcl.type.pack.index]{Pack indexing specifier}

\begin{bnf}
\nontermdef{pack-index-specifier}\br
typedef-name \terminal{...} \terminal{[} constant-expression \terminal{]}
\end{bnf}

\pnum
The \grammarterm{typedef-name} $P$ in a \grammarterm{pack-index-specifier}
shall denote a pack.

\pnum
The \grammarterm{constant-expression} shall be
a converted constant expression\iref{expr.const} of type \tcode{std::size_t}
whose value $V$, termed the index,
is such that $0 \le V < \tcode{sizeof...(}P\tcode{)}$.

\pnum
A \grammarterm{pack-index-specifier} is a pack expansion\iref{temp.variadic}.

\pnum
\begin{note}
The \grammarterm{pack-index-specifier} denotes
the type of the $V^\tcode{th}$ element of the pack\iref{temp.variadic}.
\end{note}

\rSec3[dcl.type.elab]{Elaborated type specifiers}%
\indextext{type specifier!elaborated}%
\indextext{\idxcode{typename}}%
Expand Down Expand Up @@ -1604,6 +1637,13 @@
decltype(i) x2; // type is \tcode{int}
decltype(a->x) x3; // type is \tcode{double}
decltype((a->x)) x4 = x3; // type is \tcode{const double\&}

void f() {
[](auto ...pack) {
decltype(pack...[0]) x5; // type is \tcode{int}
decltype((pack...[0])) x6; // type is \tcode{int\&}
}(0);
}
\end{codeblock}
\end{example}
\begin{note}
Expand Down Expand Up @@ -2366,7 +2406,6 @@
\begin{bnf}
\nontermdef{noptr-abstract-pack-declarator}\br
noptr-abstract-pack-declarator parameters-and-qualifiers\br
noptr-abstract-pack-declarator \terminal{[} \opt{constant-expression} \terminal{]} \opt{attribute-specifier-seq}\br
\terminal{...}
\end{bnf}

Expand Down
47 changes: 37 additions & 10 deletions source/expressions.tex
Original file line number Diff line number Diff line change
Expand Up @@ -1325,7 +1325,8 @@
\begin{bnf}
\nontermdef{id-expression}\br
unqualified-id\br
qualified-id
qualified-id\br
pack-index-expression
\end{bnf}

\pnum
Expand Down Expand Up @@ -1430,7 +1431,7 @@
conversion-function-id\br
literal-operator-id\br
\terminal{\~} type-name\br
\terminal{\~} decltype-specifier\br
\terminal{\~} computed-type-specifier\br
template-id
\end{bnf}

Expand All @@ -1447,7 +1448,7 @@
\grammarterm{conversion-function-id}{s}, see~\ref{class.conv.fct}; for
\grammarterm{literal-operator-id}{s}, see~\ref{over.literal}; for
\grammarterm{template-id}{s}, see~\ref{temp.names}.
A \grammarterm{type-name} or \grammarterm{decltype-specifier}
A \grammarterm{type-name} or \grammarterm{computed-type-specifier}
prefixed by \tcode{\~} denotes the destructor of the type so named;
see~\ref{expr.prim.id.dtor}.
Within the definition of a non-static member function, an
Expand Down Expand Up @@ -1595,7 +1596,7 @@
\terminal{::}\br
type-name \terminal{::}\br
namespace-name \terminal{::}\br
decltype-specifier \terminal{::}\br
computed-type-specifier \terminal{::}\br
nested-name-specifier identifier \terminal{::}\br
nested-name-specifier \opt{\keyword{template}} simple-template-id \terminal{::}
\end{bnf}
Expand Down Expand Up @@ -1633,8 +1634,8 @@
\pnum
The \grammarterm{nested-name-specifier} \tcode{::} nominates
the global namespace.
A \grammarterm{nested-name-specifier} with a \grammarterm{decltype-specifier}
nominates the type denoted by the \grammarterm{decltype-specifier},
A \grammarterm{nested-name-specifier} with a \grammarterm{computed-type-specifier}
nominates the type denoted by the \grammarterm{computed-type-specifier},
which shall be a class or enumeration type.
If a \grammarterm{nested-name-specifier} $N$
is declarative and
Expand Down Expand Up @@ -1666,9 +1667,9 @@
\pnum
A \grammarterm{qualified-id} shall not be of the form
\grammarterm{nested-name-specifier} \opt{\keyword{template}} \tcode{\~}
\grammarterm{decltype-specifier}
\grammarterm{computed-type-specifier}
nor of the form
\grammarterm{decltype-specifier} \tcode{::} \tcode{\~} \grammarterm{type-name}.
\grammarterm{computed-type-specifier} \tcode{::} \tcode{\~} \grammarterm{type-name}.

\pnum
The result of a \grammarterm{qualified-id} $Q$ is
Expand All @@ -1690,6 +1691,32 @@
\end{itemize}
and a prvalue otherwise.

\rSec3[expr.prim.pack.index]{Pack indexing expression}

\begin{bnf}
\nontermdef{pack-index-expression}\br
id-expression \terminal{...} \terminal{[} constant-expression \terminal{]}
\end{bnf}

\pnum
The \grammarterm{id-expression} $P$ in a \grammarterm{pack-index-expression}
shall be an \grammarterm{identifier} that denotes a pack.

\pnum
The \grammarterm{constant-expression} shall be
a converted constant expression\iref{expr.const} of type \tcode{std::size_t}
whose value $V$, termed the index,
is such that $0 \le V < \tcode{sizeof...(}P\tcode{)}$.

\pnum
A \grammarterm{pack-index-expression} is a pack expansion\iref{temp.variadic}.

\pnum
\begin{note}
A \grammarterm{pack-index-expression} denotes
the $V^\tcode{th}$ element of the pack\iref{temp.variadic}.
\end{note}

\rSec3[expr.prim.id.dtor]{Destruction}

\pnum
Expand Down Expand Up @@ -4689,14 +4716,14 @@
\end{note}
There is an ambiguity
in the grammar when \tcode{\~{}} is followed by
a \grammarterm{type-name} or \grammarterm{decltype-specifier}.
a \grammarterm{type-name} or \grammarterm{computed-type-specifier}.
The ambiguity is resolved by treating \tcode{\~{}} as the
operator rather than as the start of an \grammarterm{unqualified-id}
naming a destructor.
\begin{note}
Because the grammar does not permit an operator to follow the
\tcode{.}, \tcode{->}, or \tcode{::} tokens, a \tcode{\~{}} followed by
a \grammarterm{type-name} or \grammarterm{decltype-specifier} in a
a \grammarterm{type-name} or \grammarterm{computed-type-specifier} in a
member access expression or \grammarterm{qualified-id} is
unambiguously parsed as a destructor name.
\end{note}
Expand Down
1 change: 1 addition & 0 deletions source/preprocessor.tex
Original file line number Diff line number Diff line change
Expand Up @@ -1851,6 +1851,7 @@
\defnxname{cpp_nontype_template_args} & \tcode{201911L} \\ \rowsep
\defnxname{cpp_nontype_template_parameter_auto} & \tcode{201606L} \\ \rowsep
\defnxname{cpp_nsdmi} & \tcode{200809L} \\ \rowsep
\defnxname{cpp_pack_indexing} & \tcode{202311L} \\ \rowsep
\defnxname{cpp_placeholder_variables} & \tcode{202306L} \\ \rowsep
\defnxname{cpp_range_based_for} & \tcode{202211L} \\ \rowsep
\defnxname{cpp_raw_strings} & \tcode{200710L} \\ \rowsep
Expand Down
37 changes: 36 additions & 1 deletion source/templates.tex
Original file line number Diff line number Diff line change
Expand Up @@ -2144,6 +2144,19 @@
e.g., by a \grammarterm{typedef-name}.
\end{note}

\pnum
For a type template parameter pack \tcode{T},
\tcode{T...[}\grammarterm{constant-expression}\tcode{]} denotes
a unique dependent type.

\pnum
If the \grammarterm{constant-expression} of a \grammarterm{pack-index-specifier}
is value-dependent,
two such \grammarterm{pack-index-specifier}s refer to the same type
only if their \grammarterm{constant-expression}s are equivalent\iref{temp.over.link}.
Otherwise, two such \grammarterm{pack-index-specifier}s refer to the same type
only if their indexes have the same value.

\rSec1[temp.decls]{Template declarations}

\rSec2[temp.decls.general]{General}
Expand Down Expand Up @@ -2743,6 +2756,12 @@
\item In a \tcode{sizeof...} expression\iref{expr.sizeof}; the pattern is an
\grammarterm{identifier}.

\item In a \grammarterm{pack-index-expression};
the pattern is an \grammarterm{identifier}.

\item In a \grammarterm{pack-index-spexifier};
the pattern is a \grammarterm{typedef-name}.

\item In a \grammarterm{fold-expression}\iref{expr.prim.fold};
the pattern is the \grammarterm{cast-expression}
that contains an unexpanded pack.
Expand Down Expand Up @@ -2845,6 +2864,16 @@
The instantiation of a \tcode{sizeof...} expression\iref{expr.sizeof} produces
an integral constant with value $N$.

\pnum
When instantiating a \grammarterm{pack-index-expression} $P$,
let $K$ be the index of $P$.
The instantiation of P is the \grammarterm{id-expression} $E_K$.

\pnum
When instantiating a \grammarterm{pack-index-specifier} $P$,
let $K$ be the index of $P$.
The instantiation of P is the \grammarterm{typedef-name} $E_K$.

\pnum
The instantiation of an \grammarterm{alignment-specifier} with an ellipsis
produces $\tcode{E}_1$ $\tcode{E}_2$ $\dotsc$ $\tcode{E}_N$.
Expand Down Expand Up @@ -5046,7 +5075,7 @@
This includes an injected-class-name\iref{class.pre} of a class template
used without a \grammarterm{template-argument-list}.
\end{footnote}
or
\item a \grammarterm{pack-index-specifier}, or
\item denoted by \tcode{decltype(}\grammarterm{expression}{}\tcode{)},
where \grammarterm{expression} is type-dependent\iref{temp.dep.expr}.
\end{itemize}
Expand Down Expand Up @@ -5193,6 +5222,10 @@
\pnum
A \grammarterm{fold-expression} is type-dependent.

\pnum
A \grammarterm{pack-index-expression} is type-dependent
if its \grammarterm{id-expression} is type-dependent.

\rSec3[temp.dep.constexpr]{Value-dependent expressions}

\pnum
Expand Down Expand Up @@ -8132,6 +8165,8 @@
of a type that was specified using a
\grammarterm{qualified-id}.
\item
A \grammarterm{pack-index-specifier} or a \grammarterm{pack-index-expression}.
\item
The \grammarterm{expression} of a \grammarterm{decltype-specifier}.
\item
A non-type template argument or an array bound in which a subexpression
Expand Down

0 comments on commit 8f02007

Please sign in to comment.