Date: Thu, 2 Apr 2026 09:48:18 +0800
Hi Mark,
Thank you for your continued detailed clarification and explanation for
mdspan; I have benefited greatly from it.
Have you considered adding converting constructors so that users can
> go from an iterator-to-nonconst to an iterator-to-const?
The proposed wording has the following converting constructors:
template<convertible_to<I> I2>
constexpr iterator_accessor(iterator_accessor<I2>) noexcept {}
I think it's enough to cover it?
My only concern is that the
> non-wording sections of the paper say some things about mdspan's
> design that I don't think are quite accurate.
Thank you for pointing it out.
In fact, a large part of the discussion section was written with AI
assistance. :)
I neglected to proofread it, resulting in overly aggressive words, given
that it might not fully understand mdspan. I have revised the discussion.
Additionally, note that I used __cpp_lib_iterator_accessor because the
standard already has a similar __cpp_lib_aligned_accessor.
Here is the revised one: https://isocpp.org/files/papers/P4173R0.html
Hewill
Mark Hoemmen <mark.hoemmen_at_[hidden]> 於 2026年4月2日週四 上午1:51寫道:
> Hewill Kang wrote:
> > Hi, I wrote a paper on this:
> https://isocpp.org/files/papers/P4173R0.html
>
> Hi and thanks for your interest in mdspan!
>
> I do think a "random access iterator accessor" would be useful. I've
> actually implemented this for some of my colleagues, who asked for a
> proposal like this.
>
> Have you considered adding converting constructors so that users can
> go from an iterator-to-nonconst to an iterator-to-const?
>
> I generally approve of this proposal. My only concern is that the
> non-wording sections of the paper say some things about mdspan's
> design that I don't think are quite accurate.
>
> > Standard mdspan accessors are primarily limited to raw pointers,
> hindering direct integration with non-contiguous C++ Ranges and proxy-based
> containers.
>
> It's true that default_accessor and aligned_accessor work on pointers.
> However, mdspan's design actively encourages users to write custom
> accessors. Just like the Standard can't foresee all possible
> containers, the Standard can't foresee all possible custom accessors
> that users might like to write for their custom hardware. That's why
> it's a customization point. There are a few other places in the paper
> that say things like this. Would you consider correcting them?
>
> > ... hindering direct integration with non-contiguous C++ Ranges
>
> mdspan integrates perfectly well with ranges.
>
> template<class ElementType, class Extents, class Layout, class Accessor>
> constexpr auto to_index_range(extents<IndexType, Exts...> e) {
> auto [...index_views] =
> [] <size_t... Inds> (const auto& exts, index_sequence<Inds>) {
> return tuple{views::indices(exts.extent(Inds))...};
> } (e, make_index_sequence<sizeof...(Exts)>());
> return views::cartesian_product(index_views...);
> }
>
> template<class ElementType, class Extents, class Layout, class Accessor>
> constexpr auto to_range(mdspan<ElementType, Extents, Layout, Accessor> x) {
> if constexpr (std::is_same_v<Layout, layout_right>) {
> return views::indices(x.required_span_size()) |
> views::transform(
> [acc = x.accessor(), handle = x.data_handle()] (size_t k) {
> return acc.access(handle, k);
> });
> } else {
> return to_index_range(x.extents()) | views::transform([=] (auto t) {
> auto [...indices] = t;
> return x[indices...];
> });
> }
> }
>
> There, now you have `to_range(x)`. I haven't proposed this for the
> Standard for two reasons.
>
> 1. What would it mean to `std::copy` from a 2 x 3 x 5 x 7 mdspan to a
> 6 x 15 x 7 mdspan?
>
> 2. Compilers are unlikely to be able to optimize a "multidimensional
> iterator."
>
> 3. It might be a surprising pessimization that `layout_left` mdspan
> would still be iterated in row-major order.
>
> It's important to understand WHY mdspan uses accessors instead of
> iterators. The design intent is that accessors are easy to write for
> hardware experts who are not C++ experts, because it's much more
> likely that users will want to write a custom accessor (to support the
> huge variety of custom memory access patterns and network hardware
> that exists in practice) than it is that they will want to write a
> custom layout mapping. Iterators are hard to write correctly -- hard
> enough that proposals like Zach Laine's P2727 exist to make this
> easier.
>
> All that being said, I don't object to the proposal! I just want to
> help clear up the design intent of mdspan.
>
> Thanks!
> mfh
>
Thank you for your continued detailed clarification and explanation for
mdspan; I have benefited greatly from it.
Have you considered adding converting constructors so that users can
> go from an iterator-to-nonconst to an iterator-to-const?
The proposed wording has the following converting constructors:
template<convertible_to<I> I2>
constexpr iterator_accessor(iterator_accessor<I2>) noexcept {}
I think it's enough to cover it?
My only concern is that the
> non-wording sections of the paper say some things about mdspan's
> design that I don't think are quite accurate.
Thank you for pointing it out.
In fact, a large part of the discussion section was written with AI
assistance. :)
I neglected to proofread it, resulting in overly aggressive words, given
that it might not fully understand mdspan. I have revised the discussion.
Additionally, note that I used __cpp_lib_iterator_accessor because the
standard already has a similar __cpp_lib_aligned_accessor.
Here is the revised one: https://isocpp.org/files/papers/P4173R0.html
Hewill
Mark Hoemmen <mark.hoemmen_at_[hidden]> 於 2026年4月2日週四 上午1:51寫道:
> Hewill Kang wrote:
> > Hi, I wrote a paper on this:
> https://isocpp.org/files/papers/P4173R0.html
>
> Hi and thanks for your interest in mdspan!
>
> I do think a "random access iterator accessor" would be useful. I've
> actually implemented this for some of my colleagues, who asked for a
> proposal like this.
>
> Have you considered adding converting constructors so that users can
> go from an iterator-to-nonconst to an iterator-to-const?
>
> I generally approve of this proposal. My only concern is that the
> non-wording sections of the paper say some things about mdspan's
> design that I don't think are quite accurate.
>
> > Standard mdspan accessors are primarily limited to raw pointers,
> hindering direct integration with non-contiguous C++ Ranges and proxy-based
> containers.
>
> It's true that default_accessor and aligned_accessor work on pointers.
> However, mdspan's design actively encourages users to write custom
> accessors. Just like the Standard can't foresee all possible
> containers, the Standard can't foresee all possible custom accessors
> that users might like to write for their custom hardware. That's why
> it's a customization point. There are a few other places in the paper
> that say things like this. Would you consider correcting them?
>
> > ... hindering direct integration with non-contiguous C++ Ranges
>
> mdspan integrates perfectly well with ranges.
>
> template<class ElementType, class Extents, class Layout, class Accessor>
> constexpr auto to_index_range(extents<IndexType, Exts...> e) {
> auto [...index_views] =
> [] <size_t... Inds> (const auto& exts, index_sequence<Inds>) {
> return tuple{views::indices(exts.extent(Inds))...};
> } (e, make_index_sequence<sizeof...(Exts)>());
> return views::cartesian_product(index_views...);
> }
>
> template<class ElementType, class Extents, class Layout, class Accessor>
> constexpr auto to_range(mdspan<ElementType, Extents, Layout, Accessor> x) {
> if constexpr (std::is_same_v<Layout, layout_right>) {
> return views::indices(x.required_span_size()) |
> views::transform(
> [acc = x.accessor(), handle = x.data_handle()] (size_t k) {
> return acc.access(handle, k);
> });
> } else {
> return to_index_range(x.extents()) | views::transform([=] (auto t) {
> auto [...indices] = t;
> return x[indices...];
> });
> }
> }
>
> There, now you have `to_range(x)`. I haven't proposed this for the
> Standard for two reasons.
>
> 1. What would it mean to `std::copy` from a 2 x 3 x 5 x 7 mdspan to a
> 6 x 15 x 7 mdspan?
>
> 2. Compilers are unlikely to be able to optimize a "multidimensional
> iterator."
>
> 3. It might be a surprising pessimization that `layout_left` mdspan
> would still be iterated in row-major order.
>
> It's important to understand WHY mdspan uses accessors instead of
> iterators. The design intent is that accessors are easy to write for
> hardware experts who are not C++ experts, because it's much more
> likely that users will want to write a custom accessor (to support the
> huge variety of custom memory access patterns and network hardware
> that exists in practice) than it is that they will want to write a
> custom layout mapping. Iterators are hard to write correctly -- hard
> enough that proposals like Zach Laine's P2727 exist to make this
> easier.
>
> All that being said, I don't object to the proposal! I just want to
> help clear up the design intent of mdspan.
>
> Thanks!
> mfh
>
Received on 2026-04-02 01:48:35
