Created on 2025-10-05.00:00:00 last changed 2 days ago
Proposed resolution:
This wording is relative to N5014.
[Drafting note: The exposition-only concept
convertible-to-non-slicing
comes from [range.subrange.general].]
Modify [mdspan.mdspan.overview] as indicated:
namespace std { template<class ElementType, class Extents, class LayoutPolicy = layout_right, class AccessorPolicy = default_accessor<ElementType>> class mdspan { public: using extents_type = Extents; using layout_type = LayoutPolicy; using accessor_type = AccessorPolicy; using mapping_type = typename layout_type::template mapping<extents_type>; using element_type = ElementType; using value_type = remove_cv_t<element_type>; using index_type = typename extents_type::index_type; using size_type = typename extents_type::size_type; using rank_type = typename extents_type::rank_type; using data_handle_type = typename accessor_type::data_handle_type; using reference = typename accessor_type::reference; […] template<class... OtherIndexTypes> constexpr explicit mdspan(convertible-to-non-slicing<data_handle_type> auto ptr, OtherIndexTypes... exts); template<class OtherIndexType, size_t N> constexpr explicit(N != rank_dynamic()) mdspan(convertible-to-non-slicing<data_handle_type> auto p, span<OtherIndexType, N> exts); template<class OtherIndexType, size_t N> constexpr explicit(N != rank_dynamic()) mdspan(convertible-to-non-slicing<data_handle_type> auto p, const array<OtherIndexType, N>& exts); constexpr mdspan(convertible-to-non-slicing<data_handle_type> auto p, const extents_type& ext); constexpr mdspan(convertible-to-non-slicing<data_handle_type> auto p, const mapping_type& m); constexpr mdspan(convertible-to-non-slicing<data_handle_type> auto p, const mapping_type& m, const accessor_type& a); […] }; […] }
Modify [mdspan.mdspan.cons] as indicated:
template<class... OtherIndexTypes> constexpr explicit mdspan(convertible-to-non-slicing<data_handle_type> auto p, OtherIndexTypes... exts);-4- Let `N` be `sizeof...(OtherIndexTypes)`.
-5- Constraints: […] […]template<class OtherIndexType, size_t N> constexpr explicit(N != rank_dynamic()) mdspan(convertible-to-non-slicing<data_handle_type> auto p, span<OtherIndexType, N> exts); template<class OtherIndexType, size_t N> constexpr explicit(N != rank_dynamic()) mdspan(convertible-to-non-slicing<data_handle_type> auto p, const array<OtherIndexType, N>& exts);-8- Constraints: […]
[…]constexpr mdspan(convertible-to-non-slicing<data_handle_type> auto p, const extents_type& ext);-11- Constraints: […]
[…]constexpr mdspan(convertible-to-non-slicing<data_handle_type> auto p, const mapping_type& m);-14- Constraints: […]
[…]constexpr mdspan(convertible-to-non-slicing<data_handle_type> auto p, const mapping_type& m, const accessor_type& a);-17- Preconditions: […]
[…]
Unlike `ranges::subrange` or `span`, `mdspan` syntactically allows a multidimensional viewing base class via a derived class pointer (demo):
#include <span>
#include <ranges>
#include <mdspan>
struct Base {};
struct Derived : Base {};
std::array<Derived, 12> arr;
std::ranges::subrange<Base*> s(arr); // error, slicing
std::span<Base> sp(arr.data(), arr.size()); // error, slicing
std::mdspan<Base, std::dims<1>> msp(arr.data(), arr.size()); // ok
Given that we intend to reject object slicing for both `default_accessor` and `aligned_accessor`, there seems no reason not to reject this invalid pointer arithmetic for `mdspan`.
History | |||
---|---|---|---|
Date | User | Action | Args |
2025-10-10 11:27:48 | admin | set | messages: + msg15131 |
2025-10-05 00:00:00 | admin | create |