Skip to content

Commit 13b0560

Browse files
committed
New issue: Multidimensional arrays are not supported by <tt>meta::reflect_constant_array</tt> and related functions
1 parent e44d873 commit 13b0560

File tree

1 file changed

+112
-0
lines changed

1 file changed

+112
-0
lines changed

xml/issue4483.xml

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
<?xml version='1.0' encoding='utf-8' standalone='no'?>
2+
<!DOCTYPE issue SYSTEM "lwg-issue.dtd">
3+
4+
<issue num="4483" status="New">
5+
<title>Multidimensional arrays are not supported by <tt>meta::reflect_constant_array</tt> and related functions</title>
6+
<section>
7+
<sref ref="[meta.define.static]"/>
8+
</section>
9+
<submitter>Tomasz Kamiński</submitter>
10+
<date>27 Nov 2025</date>
11+
<priority>99</priority>
12+
13+
<discussion>
14+
<p>As any array type (even of structural types) is not considered an structural type, per
15+
<sref ref="[temp.param]"/> p12, any invocation of `reflect_constant_array`/`define_static_array`
16+
with multidimensional array or `span` of arrays is ill formed due <i>Mandate</i> in
17+
<sref ref="meta.define.static"/> p8 that requires range value type to be structural.</p>
18+
19+
<p>As a consequence, `constant_of` currently supports only single-dimensional array
20+
(<tt>reflect_constant_arry</tt> strips outermost extents), while multi-dimensional array are
21+
rejected.</p>
22+
23+
<p>Futhremore, `define_static_object` currently uses <tt>define_static_array(span(addressof(t), 1)).data()</tt>,
24+
for array types. As for `T[N]` input this creates an multidimensional `T[1][N]` constant parameter
25+
object, this function does not support array at all. Futhermore creating an distinct template
26+
parameter object leads to emission of (otherwise uncessary) additional symbols, and breaks the
27+
invariant that for all supported object types `&amp;constant_of(o) == define_static_object(o)`.
28+
We should use `reflect_constant_array` for arrays directly.</p>
29+
30+
<p>The <i>Throws</i> clause of `reflect_constant_array` was updated to include any exception
31+
thrown by iteration over range.</p>
32+
</discussion>
33+
34+
<resolution>
35+
<p>
36+
This wording is relative to <paper num="N5014"/> ammended with changes from LWG <iref ref="4432"/>.
37+
</p>
38+
39+
<ol>
40+
41+
<li><p>Modify <sref ref="[meta.define.static]"/> as indicated:</p>
42+
43+
<pre>
44+
template&lt;ranges::input_range R&gt;
45+
consteval info reflect_constant_array(R&amp;&amp; r);
46+
</pre>
47+
<blockquote>
48+
<p>-8- Let <tt><del>T</del><ins>U</ins></tt> be <tt>ranges::range_value_t&lt;R&gt;</tt>
49+
and <ins><tt>T</tt> be <tt>remove_all_extents_&ltU&gt;</tt></ins>
50+
<del><i>e<sub>i</sub></i> be <tt>static_cast&lt;T&gt;(*<i>it<sub>i</sub></i>)</tt>,
51+
where <i>it<sub>i</sub></i> is an iterator to the <i>i<sup>th</sup></i> element of `r`</del>.
52+
</p>
53+
<p>-9- <i>Mandates</i>:
54+
<ul style="list-style-type: none">
55+
<li><ins>(9.1) &mdash;</ins> <tt>T</tt> is a structural type (<sref ref="[temp.param]"/>),
56+
<del><tt>is_constructible_v&lt;T, ranges::range_reference_t&lt;R&gt;&gt;</tt> is <tt>true</tt>, and</del>
57+
</li>
58+
<li><ins>(9.2) &mdash;</ins> <tt>T</tt> satisfies <tt>copy_constructible</tt><ins>, and</ins></li>
59+
<li><ins>(9.3) &mdash;</ins> <tt>U</tt> does not denote array type, then <tt>is_constructible_v&lt;T, ranges::range_reference_t&lt;R&gt;&gt;</tt> is <tt>true</tt>.</li>
60+
</ul>
61+
</p>
62+
<p>-10- Let <tt>V</tt> be the pack of values of type `info` of the same size as <tt>r</tt>,
63+
where the <i>i<sup>th</sup></i> element is
64+
<ul style="list-style-type: none">
65+
<li><ins>(10.1) &mdash; <tt>reflect_constant_array(*<i>it<sub>i</sub></i>)</tt> if <tt>U</tt> is array type,</ins></li>
66+
<li><ins>(10.2) &mdash;</ins> <tt>reflect_constant(<ins>static_cast&lt;T&gt;(*<i>it<sub>i</sub></i>)</ins><del><i>e<sub>i</sub></i></del>)</tt><ins> otherwise,</ins></li>
67+
</ul>
68+
<ins>and <i>it<sub>i</sub></i> is an iterator to the <i>i<sup>th</sup></i> element of `r`</ins>.</p>
69+
<p>-11- Let <tt><i>P</i></tt> be
70+
<ul style="list-style-type: none">
71+
<li>(11.1) &mdash; If <tt>sizeof...(V) > 0</tt> is true, then the template parameter object (<sref ref="[temp.param]"/>) of type const `T[sizeof...(V)]`
72+
<del>initialized with `{[:V:]...}`</del><ins>, such that <tt>constant_of(<i>P</i>[<i>I</i>]) == V...[<i>I</i>]</tt> is `true`
73+
for all <tt><i>I</i></tt> in range [`0`, `sizeof...(V)`)</ins>.</li>
74+
<li>(11.2) &mdash; Otherwise, the template parameter object of type <tt>const array&lt;T, 0&gt;</tt> initialized with `{}`.</li>
75+
</ul></p>
76+
<p>-12- <i>Returns</i>: <tt>^^<i>P</i></tt>.</p>
77+
<p>-13- <i>Throws</i>: Any <ins>of</ins>
78+
<ul style="list-style-type: none">
79+
<li><ins>(10.1) &mdash; exception thrown by incerement and dereference operations on iterator to `r` and comparision of such iterator to sentinel,</ins></li>
80+
<li><ins>(10.2) &mdash;</ins> exception thrown by the evaluation of any <ins>argument of reflect_constant</ins><del><i>e<sub>i</sub></i></del>, or</li>
81+
<li><ins>(10.3) &mdash;</ins> `meta::exception` if evaluation of any <del><tt>reflect_constant(<i>e<sub>i</sub></i>)</tt></del><ins>evaluation of
82+
<tt>reflect_constant</tt> or <tt>reflect_constant_array</tt></ins> would exit via an exception.</li>
83+
</ul></p>
84+
</blockquote>
85+
[&hellip;]
86+
87+
<pre>
88+
template&lt;class T&gt;
89+
consteval const remove_cvref_t&lt;T&gt;* define_static_object(T&amp;&amp; t);
90+
</pre>
91+
<blockquote>
92+
<p>-15- <i>Effects</i>:Equivalent to:</p>
93+
<pre>
94+
using U = remove_cvref_t&lt;T&gt;;
95+
if constexpr (meta::is_class_type(^^U)) {
96+
return addressof(meta::extract&lt;const U&amp;&gt;(meta::reflect_constant(std::forward&lt;T&gt;(t))));
97+
<ins>} else if constexpr (meta::is_array_type(^^U)) {
98+
return addressof(meta::extract&lt;const U&amp;&gt;(meta::reflect_constant_array(std::forward&lt;T&gt;(t))));</ins>
99+
} else {
100+
return define_static_array(span(addressof(t), 1)).data();
101+
}
102+
</pre>
103+
</blockquote>
104+
105+
</li>
106+
</ol>
107+
108+
</resolution>
109+
110+
111+
112+
</issue>

0 commit comments

Comments
 (0)