-
Notifications
You must be signed in to change notification settings - Fork 32
New issue: Multidimensional arrays are not supported by <tt>meta::ref… #530
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 19 commits
8fc9b6b
942f387
e1fd56a
84e10f5
a9358f8
e259f3b
27cfcfa
1507da3
031eb1f
75d9c65
b411229
ea949a8
7281717
23018b7
da2030a
55c6daa
65ccce4
cd8b3cf
e0c7eb1
0e2ef10
a07a46a
3deb1a6
014da74
c149fc6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,112 @@ | ||
| <?xml version='1.0' encoding='utf-8' standalone='no'?> | ||
| <!DOCTYPE issue SYSTEM "lwg-issue.dtd"> | ||
|
|
||
| <issue num="4483" status="New"> | ||
| <title>Multidimensional arrays are not supported by <tt>meta::reflect_constant_array</tt> and related functions</title> | ||
| <section> | ||
| <sref ref="[meta.define.static]"/> | ||
| </section> | ||
| <submitter>Tomasz Kamiński</submitter> | ||
| <date>27 Nov 2025</date> | ||
| <priority>99</priority> | ||
|
|
||
| <discussion> | ||
| <p>As any array type (even of structural types) is not considered an structural type, per | ||
| <sref ref="[temp.param]"/> p12, any invocation of `reflect_constant_array`/`define_static_array` | ||
| with multidimensional array or `span` of arrays is ill formed due to the <i>Mandates</i> in | ||
| <sref ref="meta.define.static"/> p8 that requires range value type to be structural.</p> | ||
|
|
||
| <p>As a consequence, `constant_of` currently supports only single-dimensional array | ||
Dani-Hub marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| (<tt>reflect_constant_array</tt> strips outermost extents), while multi-dimensional array are | ||
Dani-Hub marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| rejected.</p> | ||
|
|
||
| <p>Furthermore, `define_static_object` currently uses <tt>define_static_array(span(addressof(t), 1)).data()</tt>, | ||
| for array types. Since for `T[N]` input this creates an multidimensional `T[1][N]` constant parameter | ||
| object, this function does not support arrays at all. Furthermore creating a distinct template | ||
| parameter object leads to emission of (otherwise unnecessary) additional symbols, and breaks the | ||
| invariant that for all supported object types <tt>&constant_of(o) == define_static_object(o)</tt>. | ||
| We should use `reflect_constant_array` for arrays directly.</p> | ||
|
|
||
| <p>The <i>Throws</i> clause of `reflect_constant_array` was updated to include any exception | ||
| thrown by iteration over range.</p> | ||
| </discussion> | ||
|
|
||
| <resolution> | ||
| <p> | ||
| This wording is relative to <paper num="N5014"/> amended with changes from LWG <iref ref="4432"/>. | ||
| </p> | ||
|
|
||
| <ol> | ||
|
|
||
| <li><p>Modify <sref ref="[meta.define.static]"/> as indicated:</p> | ||
|
|
||
| <pre> | ||
| template<ranges::input_range R> | ||
| consteval info reflect_constant_array(R&& r); | ||
| </pre> | ||
| <blockquote> | ||
| <p>-8- Let <tt><del>T</del><ins>U</ins></tt> be <tt>ranges::range_value_t<R></tt> | ||
| and <ins><tt>T</tt> be <tt>remove_all_extents_<U></tt></ins> | ||
| <del><i>e<sub>i</sub></i> be <tt>static_cast<T>(*<i>it<sub>i</sub></i>)</tt>, | ||
| where <i>it<sub>i</sub></i> is an iterator to the <i>i<sup>th</sup></i> element of `r`</del>. | ||
| </p> | ||
| <p>-9- <i>Mandates</i>: | ||
| <ul style="list-style-type: none"> | ||
| <li><ins>(9.1) —</ins> <tt>T</tt> is a structural type (<sref ref="[temp.param]"/>), | ||
| <del><tt>is_constructible_v<T, ranges::range_reference_t<R>></tt> is `true`, and</del> | ||
| </li> | ||
| <li><ins>(9.2) —</ins> `T` satisfies `copy_constructible`<ins>, and</ins></li> | ||
| <li><ins>(9.3) —</ins> if `U` does is not an array type, then <tt>is_constructible_v<T, ranges::range_reference_t<R>></tt> is `true`.</li> | ||
| </ul> | ||
| </p> | ||
| <p>-10- Let `V` be the pack of values of type `info` of the same size as `r`, | ||
| where the <i>i<sup>th</sup></i> element is | ||
| <ul style="list-style-type: none"> | ||
| <li><ins>(10.1) — <tt>reflect_constant_array(*<i>it<sub>i</sub></i>)</tt> if <tt>U</tt> is an array type,</ins></li> | ||
| <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> | ||
| </ul> | ||
| <ins>and <i>it<sub>i</sub></i> is an iterator to the <i>i<sup>th</sup></i> element of `r`</ins>.</p> | ||
| <p>-11- Let <tt><i>P</i></tt> be | ||
| <ul style="list-style-type: none"> | ||
| <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)]` | ||
| <del>initialized with `{[:V:]...}`</del><ins>, such that <tt>constant_of(<i>P</i>[<i>I</i>]) == V...[<i>I</i>]</tt> is `true` | ||
| for all <tt><i>I</i></tt> in range [`0`, `sizeof...(V)`)</ins>.</li> | ||
| <li>(11.2) — Otherwise, the template parameter object of type <tt>const array<T, 0></tt> initialized with `{}`.</li> | ||
| </ul></p> | ||
| <p>-12- <i>Returns</i>: <tt>^^<i>P</i></tt>.</p> | ||
| <p>-13- <i>Throws</i>: Any <ins>of</ins> | ||
|
||
| <ul style="list-style-type: none"> | ||
| <li><ins>(10.1) — exception thrown by increment and dereference operations on iterator to `r` and comparison of such iterator to sentinel,</ins></li> | ||
| <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> | ||
| <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 | ||
| <tt>reflect_constant</tt> or <tt>reflect_constant_array</tt></ins> would exit via an exception.</li> | ||
| </ul></p> | ||
| </blockquote> | ||
| […] | ||
|
|
||
| <pre> | ||
| template<class T> | ||
| consteval const remove_cvref_t<T>* define_static_object(T&& t); | ||
| </pre> | ||
| <blockquote> | ||
| <p>-15- <i>Effects</i>:Equivalent to:</p> | ||
| <pre> | ||
| using U = remove_cvref_t<T>; | ||
| if constexpr (meta::is_class_type(^^U)) { | ||
| return addressof(meta::extract<const U&>(meta::reflect_constant(std::forward<T>(t)))); | ||
| <ins>} else if constexpr (meta::is_array_type(^^U)) { | ||
| return addressof(meta::extract<const U&>(meta::reflect_constant_array(std::forward<T>(t))));</ins> | ||
| } else { | ||
| return define_static_array(span(addressof(t), 1)).data(); | ||
| } | ||
| </pre> | ||
| </blockquote> | ||
|
|
||
| </li> | ||
| </ol> | ||
|
|
||
| </resolution> | ||
|
|
||
|
|
||
|
|
||
| </issue> | ||
Uh oh!
There was an error while loading. Please reload this page.