|
| 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 `&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<ranges::input_range R> |
| 45 | + consteval info reflect_constant_array(R&& r); |
| 46 | +</pre> |
| 47 | +<blockquote> |
| 48 | +<p>-8- Let <tt><del>T</del><ins>U</ins></tt> be <tt>ranges::range_value_t<R></tt> |
| 49 | +and <ins><tt>T</tt> be <tt>remove_all_extents_<U></tt></ins> |
| 50 | +<del><i>e<sub>i</sub></i> be <tt>static_cast<T>(*<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) —</ins> <tt>T</tt> is a structural type (<sref ref="[temp.param]"/>), |
| 56 | + <del><tt>is_constructible_v<T, ranges::range_reference_t<R>></tt> is <tt>true</tt>, and</del> |
| 57 | +</li> |
| 58 | +<li><ins>(9.2) —</ins> <tt>T</tt> satisfies <tt>copy_constructible</tt><ins>, and</ins></li> |
| 59 | +<li><ins>(9.3) —</ins> <tt>U</tt> does not denote array type, then <tt>is_constructible_v<T, ranges::range_reference_t<R>></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) — <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) —</ins> <tt>reflect_constant(<ins>static_cast<T>(*<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) — 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) — Otherwise, the template parameter object of type <tt>const array<T, 0></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) — 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) —</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) —</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 | +[…] |
| 86 | + |
| 87 | +<pre> |
| 88 | +template<class T> |
| 89 | + consteval const remove_cvref_t<T>* define_static_object(T&& t); |
| 90 | +</pre> |
| 91 | +<blockquote> |
| 92 | +<p>-15- <i>Effects</i>:Equivalent to:</p> |
| 93 | +<pre> |
| 94 | +using U = remove_cvref_t<T>; |
| 95 | +if constexpr (meta::is_class_type(^^U)) { |
| 96 | + return addressof(meta::extract<const U&>(meta::reflect_constant(std::forward<T>(t)))); |
| 97 | +<ins>} else if constexpr (meta::is_array_type(^^U)) { |
| 98 | + return addressof(meta::extract<const U&>(meta::reflect_constant_array(std::forward<T>(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