Created on 2025-10-05.00:00:00 last changed 1 month ago
Proposed resolution:
This wording is relative to N5014.
[Drafting note: The exposition-only concept
convertible-to-non-slicingcomes 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: […]
[…]
[ 2025-10-23; Reflector poll. ]
Set priority to 3 after reflector poll.
Even if `data_handle_type` is a pointer to `value_type`, this does not mean that it points to contiguous range of `value_type` objects. Accessor may provide different access parttern.
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-23 09:34:52 | admin | set | messages: + msg15366 |
| 2025-10-10 11:27:48 | admin | set | messages: + msg15131 |
| 2025-10-05 00:00:00 | admin | create | |