From a922aec150f2d73d8384a2305feecb3696170811 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sat, 23 Mar 2024 14:25:40 +0100 Subject: [PATCH] P2893R3 Variadic friends --- source/classes.tex | 53 +++++++++++++++++++++++++++++++---------- source/declarations.tex | 18 +++++++++----- source/preprocessor.tex | 1 + source/templates.tex | 13 ++++++---- 4 files changed, 62 insertions(+), 23 deletions(-) diff --git a/source/classes.tex b/source/classes.tex index 76edcfefb5..99c5e719a2 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -462,6 +462,7 @@ \nontermdef{member-declaration}\br \opt{attribute-specifier-seq} \opt{decl-specifier-seq} \opt{member-declarator-list} \terminal{;}\br function-definition\br + friend-type-declaration\br using-declaration\br using-enum-declaration\br static_assert-declaration\br @@ -504,6 +505,24 @@ \terminal{=} \terminal{0} \end{bnf} +\begin{bnf} +\nontermdef{friend-type-declaration}\br + \keyword{friend} friend-type-specifier-list \terminal{;} +\end{bnf} + +\begin{bnf} +\nontermdef{friend-type-specifier-list}\br + friend-type-specifier \opt{\terminal{...}}\br + friend-type-specifier-list \terminal{,} friend-type-specifier \opt{\terminal{...}} +\end{bnf} + +\begin{bnf} +\nontermdef{friend-type-specifier}\br + simple-type-specifier\br + elaborated-type-specifier\br + typename-specifier +\end{bnf} + \pnum In the absence of a \grammarterm{virt-specifier-seq}, the token sequence \tcode{= 0} is treated as a \grammarterm{pure-specifier} @@ -623,6 +642,11 @@ or if $P$ is in a complete-class context of \tcode{C}. Otherwise, \tcode{C} is incomplete at $P$. +\pnum +If a \grammarterm{member-declaration} matches +the syntactic requirements of \grammarterm{friend-type-declaration}, +it is a \grammarterm{friend-type-declaration}. + \pnum In a \grammarterm{member-declarator}, an \tcode{=} immediately following the \grammarterm{declarator} @@ -4787,27 +4811,22 @@ \pnum A friend declaration that does not declare a function -shall have one of the following forms: - -\begin{ncsimplebnf} -\keyword{friend} elaborated-type-specifier \terminal{;}\br -\keyword{friend} simple-type-specifier \terminal{;}\br -\keyword{friend} typename-specifier \terminal{;} -\end{ncsimplebnf} +shall be a \grammarterm{friend-type-declaration}. \begin{note} A friend declaration can be the \grammarterm{declaration} in a \grammarterm{template-declaration}\iref{temp.pre,temp.friend}. \end{note} -If the -type specifier in a friend declaration designates a (possibly +If a \grammarterm{friend-type-specifier} in a friend declaration +designates a (possibly cv-qualified) class type, that class is declared as a friend; otherwise, the -friend declaration is ignored. +\grammarterm{friend-type-specifier} is ignored. \begin{example} \begin{codeblock} class C; typedef C Ct; +class E; class X1 { friend C; // OK, \tcode{class C} is a friend @@ -4819,12 +4838,22 @@ friend class D; // OK, elaborated-type-specifier declares new class }; -template class R { - friend T; +template class R { + friend Ts...; +}; + +template +class R, R> { + friend Ts::Nested..., Us...; }; R rc; // \tcode{class C} is a friend of \tcode{R} +R rce; // classes \tcode{C} and \tcode{E} are friends of \tcode{R} R Ri; // OK, \tcode{"friend int;"} is ignored + +struct E { struct Nested; }; + +R, R> rr; // \tcode{E::Nested} and \tcode{C} are friends of \tcode{R, R>} \end{codeblock} \end{example} diff --git a/source/declarations.tex b/source/declarations.tex index b818177151..6b8804738e 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -28,6 +28,7 @@ block-declaration\br nodeclspec-function-declaration\br function-definition\br + friend-type-declaration\br template-declaration\br deduction-guide\br linkage-specification\br @@ -133,6 +134,11 @@ the declaration that are \emph{not} nested within scopes nested within the declaration. +\pnum +If a \grammarterm{name-declaration} matches +the syntactic requirements of \grammarterm{friend-type-declaration}, +it is a \grammarterm{friend-type-declaration}. + \pnum A \grammarterm{simple-declaration} or @@ -1536,13 +1542,13 @@ The target scope of $E$ is the nearest enclosing namespace or block scope. \pnum -If an \grammarterm{elaborated-type-specifier} appears with -the \keyword{friend} specifier as an entire \grammarterm{member-declaration}, -the \grammarterm{member-declaration} shall have one of the following forms: +A \grammarterm{friend-type-specifier} +that is an \grammarterm{elaborated-type-specifier} +shall have one of the following forms: \begin{ncsimplebnf} -\keyword{friend} class-key \opt{nested-name-specifier} identifier \terminal{;}\br -\keyword{friend} class-key simple-template-id \terminal{;}\br -\keyword{friend} class-key nested-name-specifier \opt{\keyword{template}} simple-template-id \terminal{;} +class-key \opt{nested-name-specifier} identifier\br +class-key simple-template-id\br +class-key nested-name-specifier \opt{\keyword{template}} simple-template-id \end{ncsimplebnf} Any unqualified lookup for the \grammarterm{identifier} (in the first case) does not consider scopes that contain diff --git a/source/preprocessor.tex b/source/preprocessor.tex index b62f7c607f..913fcc20fb 100644 --- a/source/preprocessor.tex +++ b/source/preprocessor.tex @@ -1903,6 +1903,7 @@ \defnxname{cpp_user_defined_literals} & \tcode{200809L} \\ \rowsep \defnxname{cpp_using_enum} & \tcode{201907L} \\ \rowsep \defnxname{cpp_variable_templates} & \tcode{201304L} \\ \rowsep +\defnxname{cpp_variadic_friend} & \tcode{202403L} \\ \rowsep \defnxname{cpp_variadic_templates} & \tcode{200704L} \\ \rowsep \defnxname{cpp_variadic_using} & \tcode{201611L} \\ \end{LongTable} diff --git a/source/templates.tex b/source/templates.tex index 9549d9d1de..3d27393946 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -59,11 +59,7 @@ \end{note} \pnum -The -\grammarterm{declaration} -in a -\grammarterm{template-declaration} -(if any) +The \grammarterm{declaration} in a \grammarterm{template-declaration} (if any) shall \begin{itemize} \item declare or define a function, a class, or a variable, or @@ -73,6 +69,8 @@ \item define a member template of a class or class template, or +\item be a \grammarterm{friend-type-declaration}, or + \item be a \grammarterm{deduction-guide}, or \item be an \grammarterm{alias-declaration}. @@ -2742,6 +2740,9 @@ \item In a \grammarterm{using-declaration}\iref{namespace.udecl}; the pattern is a \grammarterm{using-declarator}. +\item In a \grammarterm{friend-type-declaration}\iref{class.mem.general}; +the pattern is a \grammarterm{friend-type-specifier}. + \item In a template parameter pack that is a pack expansion\iref{temp.param}: \begin{itemize} \item @@ -4411,6 +4412,8 @@ \grammarterm{elaborated-type-specifier}, \grammarterm{class-or-decltype}, or \item +a \grammarterm{simple-type-specifier} of a \grammarterm{friend-type-specifier}, or +\item a \grammarterm{type-specifier} of a \begin{itemize} \item \grammarterm{new-type-id},