Skip to content

Commit 3f5c31a

Browse files
committed
New issue to address US 102-209: Metafunctions should not be defined in terms of constant subexpressions
1 parent 30eb6f3 commit 3f5c31a

File tree

1 file changed

+175
-0
lines changed

1 file changed

+175
-0
lines changed

xml/issue4428.xml

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
<?xml version='1.0' encoding='utf-8' standalone='no'?>
2+
<!DOCTYPE issue SYSTEM "lwg-issue.dtd">
3+
4+
<issue num="4428" status="New">
5+
<title>Metafunctions should not be defined in terms of constant subexpressions</title>
6+
<section>
7+
<sref ref="[meta.reflection.access.queries]"/>
8+
<sref ref="[meta.reflection.annotation]"/>
9+
<sref ref="[meta.reflection.array]"/>
10+
</section>
11+
<submitter>Jonathan Wakely</submitter>
12+
<date>24 Oct 2025</date>
13+
<priority>99</priority>
14+
15+
<discussion>
16+
<b>Addresses US 102-209</b>
17+
<p>
18+
"is a constant (sub)expression" is incorrect now that errors are reported
19+
via exceptions.
20+
</p>
21+
</discussion>
22+
23+
<resolution>
24+
<p>
25+
This wording is relative to <paper num="N5014"/>.
26+
</p>
27+
28+
<ol>
29+
30+
<li><p>Modify <sref ref="[meta.reflection.access.queries]"/> as indicated:</p>
31+
32+
<blockquote>
33+
<pre>
34+
consteval bool has_inaccessible_nonstatic_data_members(info r, access_context ctx);
35+
</pre>
36+
<blockquote>
37+
<p>-5- <i>Returns</i>:
38+
`true` if `is_accessible(`<i>R</i>`, ctx)` is `false` for any <i>R</i>
39+
in `nonstatic_data_members_of(r, access_context::unchecked())`.
40+
Otherwise, `false`.
41+
</p>
42+
<p>-6- <i>Throws</i>:
43+
`meta::exception` unless
44+
<ul>
45+
<li>(6.1) &mdash;
46+
<ins>The evaluation of</ins>
47+
`nonstatic_data_members_of(r, access_context::unchecked())`
48+
<del>
49+
is a constant subexpression
50+
</del>
51+
<ins>
52+
would not exit via an exception
53+
</ins>
54+
and
55+
</li>
56+
<li>(6.2) &mdash;
57+
`r` does not represent a closure type.
58+
</li>
59+
</ul>
60+
</p>
61+
</blockquote>
62+
<pre>
63+
consteval bool has_inaccessible_bases(info r, access_context ctx);
64+
</pre>
65+
<blockquote>
66+
<p>-5- <i>Returns</i>:
67+
`true` if `is_accessible(`<i>R</i>`, ctx)` is `false` for any <i>R</i>
68+
in `bases_of(r, access_context::unchecked())`.
69+
Otherwise, `false`.
70+
</p>
71+
<p>-6- <i>Throws</i>:
72+
`meta::exception` unless
73+
<ins>The evaluation of</ins>
74+
`bases_of(r, access_context::unchecked())`
75+
<del>is a constant subexpression</del>
76+
<ins>would not exit via an exception</ins>.
77+
</p>
78+
</blockquote>
79+
</blockquote>
80+
</li>
81+
82+
<li><p>Modify <sref ref="[meta.reflection.annotation]"/> as indicated:</p>
83+
84+
<blockquote>
85+
<pre>
86+
consteval vector&lt;info&gt; annotations_of_with_type(info item, info type);
87+
</pre>
88+
<blockquote>
89+
<p>-4- <i>Returns</i>:
90+
A `vector` containing each element `e` of `annotations_of(item)`
91+
where `remove_const(type_of(e)) == remove_const(type)`
92+
is `true`, preserving their order.
93+
</p>
94+
<p>-5- <i>Throws</i>:
95+
`meta::exception` unless
96+
<ul>
97+
<li>(5.1) &mdash;
98+
<ins>The evaluation of</ins>
99+
`annotations_of(item)`
100+
<del>
101+
is a constant subexpression
102+
</del>
103+
<ins>
104+
would not exit via an exception
105+
</ins>
106+
and
107+
</li>
108+
<li>(5.2) &mdash;
109+
`dealias(type)` represents a type that is complete
110+
from some point in the evaluation context.
111+
</li>
112+
</ul>
113+
</p>
114+
</blockquote>
115+
</blockquote>
116+
</li>
117+
118+
<li><p>Modify <sref ref="[meta.reflection.annotation]"/> as indicated:</p>
119+
<blockquote>
120+
<pre>
121+
template&lt;ranges::input_range R&gt;
122+
consteval info reflect_constant_array(R&amp;&amp; r);
123+
</pre>
124+
<blockquote>
125+
<p>-8-
126+
Let `T` be <code>ranges::range_value_t&lt;R&gt;</code>.
127+
</p>
128+
<p>-9- <i>Mandates</i>:
129+
`T` is a structural type (<sref ref="[temp.param]"/>),
130+
<code>is_constructible_v&lt;T, ranges::range_reference_t&lt;R&gt;&gt;</code>
131+
is `true`, and
132+
<code>is_copy_constructible_v&lt;T&gt;</code>
133+
is `true`.
134+
</p>
135+
<p>-10-
136+
Let <i>V</i> be the pack of values of type `info` of the same size as `r`,
137+
where the <i>i</i><sup>th</sup> element is
138+
<code>reflect_constant(e<sub><i>i</i></sub>)</code>,
139+
where <code>e<sub><i>i</i></sub></code> is
140+
the <i>i</i><sup>th</sup> element of `r`.
141+
</p>
142+
<p>-11-
143+
Let <i>P</i> be
144+
<ul>
145+
<li>(11.1) &mdash;
146+
If `sizeof...(`<i>V</i>`) > 0` is `true`,
147+
then the template parameter object (<sref ref="[temp.param]"/>)
148+
of type `const T[sizeof...(`<i>V</i>`)]` initialized with `{[:V:]...}`.
149+
</li>
150+
<li>(11.2) &mdash;
151+
Otherwise, the template parameter object of type <code>array&lt;T, 0&gt;</code>
152+
initialized with `{}`.
153+
</li>
154+
</ul>
155+
</p>
156+
<p>-12- <i>Returns</i>: `^^`<i>P</i>.
157+
</p>
158+
<p>-13- <i>Throws</i>:
159+
`meta::exception` unless
160+
<ins>The evaluation of</ins>
161+
`reflect_constant(e)`
162+
<del>is a constant subexpression</del>
163+
<ins>would not exit via an exception</ins>
164+
for every element `e` of `r`.
165+
</p>
166+
167+
</blockquote>
168+
</blockquote>
169+
</li>
170+
171+
</ol>
172+
173+
</resolution>
174+
175+
</issue>

0 commit comments

Comments
 (0)