Skip to content

Commit 37a92d0

Browse files
jensmaurertkoeppe
authored andcommitted
P2996R13 Reflection for C++26 [core]
1 parent 7a8f1e2 commit 37a92d0

File tree

10 files changed

+1914
-337
lines changed

10 files changed

+1914
-337
lines changed

source/basic.tex

Lines changed: 314 additions & 36 deletions
Large diffs are not rendered by default.

source/classes.tex

Lines changed: 87 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,7 @@
555555
using-declaration\br
556556
using-enum-declaration\br
557557
static_assert-declaration\br
558+
consteval-block-declaration\br
558559
template-declaration\br
559560
explicit-specialization\br
560561
deduction-guide\br
@@ -646,13 +647,14 @@
646647
\end{note}
647648

648649
\pnum
649-
A \grammarterm{member-declaration} does not declare new members of the class
650+
A \grammarterm{member-declaration} does not itself declare new members of the class
650651
if it is
651652
\begin{itemize}
652653
\item a friend declaration\iref{class.friend},
653654
\item a \grammarterm{deduction-guide}\iref{temp.deduct.guide},
654655
\item a \grammarterm{template-declaration} whose \grammarterm{declaration} is one of the above,
655656
\item a \grammarterm{static_assert-declaration},
657+
\item a \grammarterm{consteval-block-declaration},
656658
\item a \grammarterm{using-declaration}\iref{namespace.udecl}, or
657659
\item an \grammarterm{empty-declaration}.
658660
\end{itemize}
@@ -686,10 +688,21 @@
686688
Any other data member or member function is a \defnadj{non-static}{member}
687689
(a \defnadj{non-static}{data member} or
688690
\defnadj{non-static}{member function}\iref{class.mfct.non.static}, respectively).
689-
\begin{note}
690-
A non-static data member of non-reference
691-
type is a member subobject of a class object\iref{intro.object}.
692-
\end{note}
691+
692+
\pnum
693+
Every object of class type has a unique member subobject
694+
corresponding to each of its direct non-static data members.
695+
If any non-static data member of a class \tcode{C} is of reference type,
696+
then let \tcode{D} be an invented class
697+
that is identical to \tcode{C}
698+
except that each non-static member of \tcode{D} corresponding to
699+
a member of \tcode{C} of type ``reference to \tcode{T}''
700+
instead has type ``pointer to \tcode{T}''.
701+
Every member subobject of a complete object of type \tcode{C}
702+
has the same size, alignment, and offset
703+
as that of the corresponding subobject of a complete object of type \tcode{D}.
704+
The size and alignment of \tcode{C} are the same as
705+
the size and alignment of \tcode{D}.
693706

694707
\pnum
695708
A member shall not be declared twice in the
@@ -999,6 +1012,46 @@
9991012
pointer-interconvertible\iref{basic.compound,expr.static.cast}.
10001013
\end{note}
10011014

1015+
\pnum
1016+
A \defnadj{data member}{description} is
1017+
a quintuple ($T$, $N$, $A$, $W$, $\mathit{NUA}$)
1018+
describing the potential declaration of a non-static data member where
1019+
\begin{itemize}
1020+
\item $T$ is a type,
1021+
\item $N$ is an identifier or $\bot$,
1022+
\item $A$ is an alignment or $\bot$,
1023+
\item $W$ is a bit-field width or $\bot$, and
1024+
\item $\mathit{NUA}$ is a boolean value.
1025+
\end{itemize}
1026+
Two data member descriptions are equal
1027+
if each of their respective components are the same entities,
1028+
are the same identifiers, have equal values, or are both $\bot$.
1029+
\begin{note}
1030+
The components of a data member description describe a data member such that
1031+
\begin{itemize}
1032+
\item
1033+
its type is specified using the type given by $T$,
1034+
\item
1035+
it is declared with the name given by $N$
1036+
if $N$ is not $\bot$ and is otherwise unnamed,
1037+
\item
1038+
it is declared with the \grammarterm{alignment-specifier}\iref{dcl.align}
1039+
given by \tcode{alignas($A$)}
1040+
if $A$ is not $\bot$ and
1041+
is otherwise declared without an \grammarterm{alignment-specifier},
1042+
\item
1043+
it is a bit-field\iref{class.bit} with the width given by $W$
1044+
if W is not $\bot$ and is otherwise not a bit-field, and
1045+
\item
1046+
it is declared with
1047+
the attribute \tcode{[[no_unique_address]]}\iref{dcl.attr.nouniqueaddr}
1048+
if $\mathit{NUA}$ is true and is otherwise declared without that attribute.
1049+
\end{itemize}
1050+
Data member descriptions are represented by reflections\iref{basic.fundamental}
1051+
returned by \tcode{std::meta::data_member_spec}\iref{meta.reflection.define.aggregate} and
1052+
can be reified as data members of a class using \tcode{std::meta::define_aggregate}.
1053+
\end{note}
1054+
10021055
\rSec2[class.mfct]{Member functions}%
10031056
\indextext{member function!class}
10041057

@@ -3514,7 +3567,12 @@
35143567
The class denoted by the \grammarterm{class-or-decltype} of
35153568
a \grammarterm{base-specifier} is called a
35163569
\defnadj{direct}{base class}
3517-
for the class being defined.
3570+
for the class being defined;
3571+
for each such \grammarterm{base-specifier},
3572+
the corresponding \defnadj{direct base class}{relationship}
3573+
is the ordered pair (\tcode{D}, \tcode{B})
3574+
where \tcode{D} is the class being defined and
3575+
\tcode{B} is the direct base class.
35183576
\indextext{base class}%
35193577
\indextext{derivation|see{inheritance}}%
35203578
The lookup for the component name of
@@ -4345,9 +4403,10 @@
43454403
\end{codeblock}
43464404
\end{example}
43474405
\begin{note}
4348-
Because access control applies to the declarations named, if access control is applied to a
4349-
\grammarterm{typedef-name}, only the accessibility of the typedef or alias declaration itself is considered.
4350-
The accessibility of the entity referred to by the \grammarterm{typedef-name} is not considered.
4406+
Because access control applies to the declarations named,
4407+
if access control is applied to a type alias,
4408+
only the accessibility of the typedef or alias declaration itself is considered.
4409+
The accessibility of the underlying entity is not considered.
43514410
\begin{example}
43524411
\begin{codeblock}
43534412
class A {
@@ -4738,10 +4797,18 @@
47384797
to a pointer to a private or protected immediate base class of
47394798
\tcode{X}.
47404799
\end{note}
4741-
The access to a member is affected by the class in which the member is
4742-
named.
4743-
This naming class is
4744-
the class in whose scope name lookup performed a search that found the member.
4800+
An expression $E$ that designates a member \tcode{m}
4801+
has a \defnadj{designating}{class}
4802+
that affects the access to \tcode{m}.
4803+
This designating class is either
4804+
\begin{itemize}
4805+
\item
4806+
the innermost class of which \tcode{m} is directly a member
4807+
if $E$ is a \grammarterm{splice-expression} or
4808+
\item
4809+
the class in whose scope name lookup performed a search
4810+
that found \tcode{m} otherwise.
4811+
\end{itemize}
47454812
\begin{note}
47464813
This class can be explicit, e.g., when a
47474814
\grammarterm{qualified-id}
@@ -4753,7 +4820,7 @@
47534820
\grammarterm{qualified-id}
47544821
are used to name the member (as in
47554822
\tcode{p->T::m}),
4756-
the class naming the member is the class denoted by the
4823+
the class designating the member is the class designated by the
47574824
\grammarterm{nested-name-specifier}
47584825
of the
47594826
\grammarterm{qualified-id}
@@ -4764,11 +4831,13 @@
47644831
\tcode{m}
47654832
is accessible at the point
47664833
\placeholder{R}
4767-
when named in class
4834+
when designated in class
47684835
\tcode{N}
47694836
if
47704837
\begin{itemize}
47714838
\item
4839+
\tcode{m} is designated by a \grammarterm{splice-expression}, or
4840+
\item
47724841
\tcode{m}
47734842
as a member of
47744843
\tcode{N}
@@ -4810,7 +4879,7 @@
48104879
\tcode{m}
48114880
is accessible at
48124881
\placeholder{R}
4813-
when named in class
4882+
when designated in class
48144883
\tcode{B}.
48154884
\begin{example}
48164885
\begin{codeblock}
@@ -4836,10 +4905,10 @@
48364905
left operand (considered as a pointer in the
48374906
``\tcode{.}''
48384907
operator case) cannot be implicitly converted to a
4839-
pointer to the naming class of the right operand.
4908+
pointer to the designating class of the right operand.
48404909
\begin{note}
48414910
This requirement is in addition to the requirement that
4842-
the member be accessible as named.
4911+
the member be accessible as designated.
48434912
\end{note}
48444913

48454914
\rSec2[class.friend]{Friends}%

source/compatibility.tex

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,22 @@
1313

1414
\rSec2[diff.cpp23.lex]{\ref{lex}: Lexical conventions}
1515

16+
\diffref{lex.operators}
17+
\change
18+
New operator \tcode{\caret\caret}.
19+
\rationale
20+
Required for new features.
21+
\effect
22+
Valid \CppXXIII{} code that contains two consecutive \tcode{\caret} tokens
23+
can be ill-formed in this revision of \Cpp{}.
24+
\begin{example}
25+
\begin{codeblock}
26+
struct C { int operator^(int); };
27+
int operator^(int (C::*p)(int), C);
28+
int i = &C::operator^^C{}; // ill-formed; previously well-formed
29+
\end{codeblock}
30+
\end{example}
31+
1632
\diffref{lex.key}
1733
\change
1834
New keywords.
@@ -148,6 +164,22 @@
148164
\end{codeblock}
149165
\end{example}
150166

167+
\diffref{dcl.attr.grammar}
168+
\change
169+
New token \tcode{:]}.
170+
\rationale
171+
Required for new features.
172+
\effect
173+
Valid \CppXXIII{} code that contained an \grammarterm{attribute-specifier}
174+
with an \grammarterm{attribute-using-prefix}
175+
but no attributes and no whitespace is ill-formed in this revision of \Cpp{}.
176+
\begin{example}
177+
\begin{codeblock}
178+
struct [[using CC:]] C; // ill-formed; previously well-formed
179+
struct [[using DD: ]] D; // OK
180+
\end{codeblock}
181+
\end{example}
182+
151183
\rSec2[diff.cpp23.temp]{\ref{temp}: templates}
152184

153185
\diffref{temp.constr}

0 commit comments

Comments
 (0)