Skip to content

Commit 67a5053

Browse files
committed
New issue from Hewill: "mdspan constructor should disallow derived to base conversions"
1 parent 7951e07 commit 67a5053

File tree

1 file changed

+159
-0
lines changed

1 file changed

+159
-0
lines changed

xml/issue4405.xml

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
<?xml version='1.0' encoding='utf-8' standalone='no'?>
2+
<!DOCTYPE issue SYSTEM "lwg-issue.dtd">
3+
4+
<issue num="4405" status="New">
5+
<title>`mdspan` constructor should disallow derived to base conversions</title>
6+
<section>
7+
<sref ref="[mdspan.mdspan.cons]"/>
8+
</section>
9+
<submitter>Hewill Kang</submitter>
10+
<date>05 Oct 2025</date>
11+
<priority>99</priority>
12+
13+
<discussion>
14+
<p>
15+
Unlike `ranges::subrange` or `span`, `mdspan` syntactically allows a multidimensional
16+
viewing base class via a derived class pointer (<a href="https://godbolt.org/z/c56h9fjs8">demo</a>):
17+
</p>
18+
<blockquote><pre>
19+
#include &lt;span&gt;
20+
#include &lt;ranges&gt;
21+
#include &lt;mdspan&gt;
22+
23+
struct Base {};
24+
struct Derived : Base {};
25+
std::array&lt;Derived, 12&gt; arr;
26+
std::ranges::subrange&lt;Base*&gt; s(arr); // error, slicing
27+
std::span&lt;Base&gt; sp(arr.data(), arr.size()); // error, slicing
28+
std::mdspan&lt;Base, std::dims&lt;1&gt;&gt; msp(arr.data(), arr.size()); // <span style="color:#C80000;font-weight:bold">ok</span>
29+
</pre></blockquote>
30+
<p>
31+
Given that we intend to reject object slicing for both `default_accessor` and
32+
`aligned_accessor`, there seems no reason not to reject this invalid pointer
33+
arithmetic for `mdspan`.
34+
</p>
35+
</discussion>
36+
37+
<resolution>
38+
<p>
39+
This wording is relative to <paper num="N5014"/>.
40+
</p>
41+
42+
<blockquote class="note">
43+
<p>
44+
[<i>Drafting note:</i> The exposition-only concept <code><i>convertible-to-non-slicing</i></code> comes from
45+
<sref ref="[range.subrange.general]"/>.]
46+
</p>
47+
</blockquote>
48+
49+
<ol>
50+
51+
<li><p>Modify <sref ref="[mdspan.mdspan.overview]"/> as indicated:</p>
52+
53+
<blockquote>
54+
<pre>
55+
namespace std {
56+
template&lt;class ElementType, class Extents, class LayoutPolicy = layout_right,
57+
class AccessorPolicy = default_accessor&lt;ElementType&gt;&gt;
58+
class mdspan {
59+
public:
60+
using extents_type = Extents;
61+
using layout_type = LayoutPolicy;
62+
using accessor_type = AccessorPolicy;
63+
using mapping_type = typename layout_type::template mapping&lt;extents_type&gt;;
64+
using element_type = ElementType;
65+
using value_type = remove_cv_t&lt;element_type&gt;;
66+
using index_type = typename extents_type::index_type;
67+
using size_type = typename extents_type::size_type;
68+
using rank_type = typename extents_type::rank_type;
69+
using data_handle_type = typename accessor_type::data_handle_type;
70+
using reference = typename accessor_type::reference;
71+
[&hellip;]
72+
template&lt;class... OtherIndexTypes&gt;
73+
constexpr explicit mdspan(<ins><i>convertible-to-non-slicing</i>&lt;</ins>data_handle_type<ins>&gt; auto</ins> ptr, OtherIndexTypes... exts);
74+
template&lt;class OtherIndexType, size_t N&gt;
75+
constexpr explicit(N != rank_dynamic())
76+
mdspan(<ins><i>convertible-to-non-slicing</i>&lt;</ins>data_handle_type<ins>&gt; auto</ins> p, span&lt;OtherIndexType, N&gt; exts);
77+
template&lt;class OtherIndexType, size_t N&gt;
78+
constexpr explicit(N != rank_dynamic())
79+
mdspan(<ins><i>convertible-to-non-slicing</i>&lt;</ins>data_handle_type<ins>&gt; auto</ins> p, const array&lt;OtherIndexType, N&gt;&amp; exts);
80+
constexpr mdspan(<ins><i>convertible-to-non-slicing</i>&lt;</ins>data_handle_type<ins>&gt; auto</ins> p, const extents_type&amp; ext);
81+
constexpr mdspan(<ins><i>convertible-to-non-slicing</i>&lt;</ins>data_handle_type<ins>&gt; auto</ins> p, const mapping_type&amp; m);
82+
constexpr mdspan(<ins><i>convertible-to-non-slicing</i>&lt;</ins>data_handle_type<ins>&gt; auto</ins> p, const mapping_type&amp; m, const accessor_type&amp; a);
83+
[&hellip;]
84+
};
85+
[&hellip;]
86+
}
87+
</pre>
88+
</blockquote>
89+
</li>
90+
91+
<li><p>Modify <sref ref="[mdspan.mdspan.cons]"/> as indicated:</p>
92+
93+
<blockquote>
94+
<pre>
95+
template&lt;class... OtherIndexTypes&gt;
96+
constexpr explicit mdspan(<ins><i>convertible-to-non-slicing</i>&lt;</ins>data_handle_type<ins>&gt; auto</ins> p, OtherIndexTypes... exts);
97+
</pre>
98+
<blockquote>
99+
<p>
100+
-4- Let `N` be `sizeof...(OtherIndexTypes)`.
101+
<p/>
102+
-5- <i>Constraints</i>: [&hellip;]
103+
<p/>
104+
[&hellip;]
105+
</p>
106+
</blockquote>
107+
<pre>
108+
template&lt;class OtherIndexType, size_t N&gt;
109+
constexpr explicit(N != rank_dynamic())
110+
mdspan(<ins><i>convertible-to-non-slicing</i>&lt;</ins>data_handle_type<ins>&gt; auto</ins> p, span&lt;OtherIndexType, N&gt; exts);
111+
template&lt;class OtherIndexType, size_t N&gt;
112+
constexpr explicit(N != rank_dynamic())
113+
mdspan(<ins><i>convertible-to-non-slicing</i>&lt;</ins>data_handle_type<ins>&gt; auto</ins> p, const array&lt;OtherIndexType, N&gt;&amp; exts);
114+
</pre>
115+
<blockquote>
116+
<p>
117+
-8- <i>Constraints</i>: [&hellip;]
118+
<p/>
119+
[&hellip;]
120+
</p>
121+
</blockquote>
122+
<pre>
123+
constexpr mdspan(<ins><i>convertible-to-non-slicing</i>&lt;</ins>data_handle_type<ins>&gt; auto</ins> p, const extents_type&amp; ext);
124+
</pre>
125+
<blockquote>
126+
<p>
127+
-11- <i>Constraints</i>: [&hellip;]
128+
<p/>
129+
[&hellip;]
130+
</p>
131+
</blockquote>
132+
<pre>
133+
constexpr mdspan(<ins><i>convertible-to-non-slicing</i>&lt;</ins>data_handle_type<ins>&gt; auto</ins> p, const mapping_type&amp; m);
134+
</pre>
135+
<blockquote>
136+
<p>
137+
-14- <i>Constraints</i>: [&hellip;]
138+
<p/>
139+
[&hellip;]
140+
</p>
141+
</blockquote>
142+
<pre>
143+
constexpr mdspan(<ins><i>convertible-to-non-slicing</i>&lt;</ins>data_handle_type<ins>&gt; auto</ins> p, const mapping_type&amp; m, const accessor_type&amp; a);
144+
</pre>
145+
<blockquote>
146+
<p>
147+
-17- <i>Preconditions</i>: [&hellip;]
148+
<p/>
149+
[&hellip;]
150+
</p>
151+
</blockquote>
152+
</blockquote>
153+
</li>
154+
155+
</ol>
156+
157+
</resolution>
158+
159+
</issue>

0 commit comments

Comments
 (0)