xref: /freebsd/contrib/llvm-project/libcxx/include/mdspan (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
106c3fb27SDimitry Andric// -*- C++ -*-
206c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
306c3fb27SDimitry Andric//
406c3fb27SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
506c3fb27SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
606c3fb27SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
706c3fb27SDimitry Andric//
806c3fb27SDimitry Andric//===---------------------------------------------------------------------===//
906c3fb27SDimitry Andric
1006c3fb27SDimitry Andric/*
1106c3fb27SDimitry Andric
1206c3fb27SDimitry Andric// Overall mdspan synopsis
1306c3fb27SDimitry Andric
1406c3fb27SDimitry Andricnamespace std {
1506c3fb27SDimitry Andric  // [mdspan.extents], class template extents
1606c3fb27SDimitry Andric  template<class IndexType, size_t... Extents>
1706c3fb27SDimitry Andric    class extents;
1806c3fb27SDimitry Andric
1906c3fb27SDimitry Andric  // [mdspan.extents.dextents], alias template dextents
2006c3fb27SDimitry Andric  template<class IndexType, size_t Rank>
2106c3fb27SDimitry Andric    using dextents = see below;
2206c3fb27SDimitry Andric
2306c3fb27SDimitry Andric  // [mdspan.layout], layout mapping
2406c3fb27SDimitry Andric  struct layout_left;
2506c3fb27SDimitry Andric  struct layout_right;
26*5f757f3fSDimitry Andric  struct layout_stride;
2706c3fb27SDimitry Andric
2806c3fb27SDimitry Andric  // [mdspan.accessor.default], class template default_accessor
2906c3fb27SDimitry Andric  template<class ElementType>
3006c3fb27SDimitry Andric    class default_accessor;
3106c3fb27SDimitry Andric
3206c3fb27SDimitry Andric  // [mdspan.mdspan], class template mdspan
3306c3fb27SDimitry Andric  template<class ElementType, class Extents, class LayoutPolicy = layout_right,
3406c3fb27SDimitry Andric           class AccessorPolicy = default_accessor<ElementType>>
3506c3fb27SDimitry Andric    class mdspan; // not implemented yet
3606c3fb27SDimitry Andric}
3706c3fb27SDimitry Andric
3806c3fb27SDimitry Andric// extents synopsis
3906c3fb27SDimitry Andric
4006c3fb27SDimitry Andricnamespace std {
4106c3fb27SDimitry Andric  template<class _IndexType, size_t... _Extents>
4206c3fb27SDimitry Andric  class extents {
4306c3fb27SDimitry Andric  public:
4406c3fb27SDimitry Andric    using index_type = _IndexType;
4506c3fb27SDimitry Andric    using size_type = make_unsigned_t<index_type>;
4606c3fb27SDimitry Andric    using rank_type = size_t;
4706c3fb27SDimitry Andric
4806c3fb27SDimitry Andric    // [mdspan.extents.obs], observers of the multidimensional index space
4906c3fb27SDimitry Andric    static constexpr rank_type rank() noexcept { return sizeof...(_Extents); }
5006c3fb27SDimitry Andric    static constexpr rank_type rank_dynamic() noexcept { return dynamic-index(rank()); }
5106c3fb27SDimitry Andric    static constexpr size_t static_extent(rank_type) noexcept;
5206c3fb27SDimitry Andric    constexpr index_type extent(rank_type) const noexcept;
5306c3fb27SDimitry Andric
5406c3fb27SDimitry Andric    // [mdspan.extents.cons], constructors
5506c3fb27SDimitry Andric    constexpr extents() noexcept = default;
5606c3fb27SDimitry Andric
5706c3fb27SDimitry Andric    template<class _OtherIndexType, size_t... _OtherExtents>
5806c3fb27SDimitry Andric      constexpr explicit(see below)
5906c3fb27SDimitry Andric        extents(const extents<_OtherIndexType, _OtherExtents...>&) noexcept;
6006c3fb27SDimitry Andric    template<class... _OtherIndexTypes>
6106c3fb27SDimitry Andric      constexpr explicit extents(_OtherIndexTypes...) noexcept;
6206c3fb27SDimitry Andric    template<class _OtherIndexType, size_t N>
6306c3fb27SDimitry Andric      constexpr explicit(N != rank_dynamic())
6406c3fb27SDimitry Andric        extents(span<_OtherIndexType, N>) noexcept;
6506c3fb27SDimitry Andric    template<class _OtherIndexType, size_t N>
6606c3fb27SDimitry Andric      constexpr explicit(N != rank_dynamic())
6706c3fb27SDimitry Andric        extents(const array<_OtherIndexType, N>&) noexcept;
6806c3fb27SDimitry Andric
6906c3fb27SDimitry Andric    // [mdspan.extents.cmp], comparison operators
7006c3fb27SDimitry Andric    template<class _OtherIndexType, size_t... _OtherExtents>
7106c3fb27SDimitry Andric      friend constexpr bool operator==(const extents&,
7206c3fb27SDimitry Andric                                       const extents<_OtherIndexType, _OtherExtents...>&) noexcept;
7306c3fb27SDimitry Andric
7406c3fb27SDimitry Andric  private:
7506c3fb27SDimitry Andric    // libcxx note: we do not use an array here, but we need to preserve the as-if behavior
7606c3fb27SDimitry Andric    // for example the default constructor must zero initialize dynamic extents
7706c3fb27SDimitry Andric    array<index_type, rank_dynamic()> dynamic-extents{};                // exposition only
7806c3fb27SDimitry Andric  };
7906c3fb27SDimitry Andric
8006c3fb27SDimitry Andric  template<class... Integrals>
8106c3fb27SDimitry Andric    explicit extents(Integrals...)
8206c3fb27SDimitry Andric      -> see below;
8306c3fb27SDimitry Andric}
8406c3fb27SDimitry Andric
8506c3fb27SDimitry Andric// layout_left synopsis
8606c3fb27SDimitry Andric
8706c3fb27SDimitry Andricnamespace std {
8806c3fb27SDimitry Andric  template<class Extents>
8906c3fb27SDimitry Andric  class layout_left::mapping {
9006c3fb27SDimitry Andric  public:
9106c3fb27SDimitry Andric    using extents_type = Extents;
9206c3fb27SDimitry Andric    using index_type = typename extents_type::index_type;
9306c3fb27SDimitry Andric    using size_type = typename extents_type::size_type;
9406c3fb27SDimitry Andric    using rank_type = typename extents_type::rank_type;
9506c3fb27SDimitry Andric    using layout_type = layout_left;
9606c3fb27SDimitry Andric
9706c3fb27SDimitry Andric    // [mdspan.layout.right.cons], constructors
9806c3fb27SDimitry Andric    constexpr mapping() noexcept = default;
9906c3fb27SDimitry Andric    constexpr mapping(const mapping&) noexcept = default;
10006c3fb27SDimitry Andric    constexpr mapping(const extents_type&) noexcept;
10106c3fb27SDimitry Andric    template<class OtherExtents>
10206c3fb27SDimitry Andric      constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
10306c3fb27SDimitry Andric        mapping(const mapping<OtherExtents>&) noexcept;
10406c3fb27SDimitry Andric    template<class OtherExtents>
10506c3fb27SDimitry Andric      constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
10606c3fb27SDimitry Andric        mapping(const layout_right::mapping<OtherExtents>&) noexcept;
10706c3fb27SDimitry Andric    template<class OtherExtents>
10806c3fb27SDimitry Andric      constexpr explicit(extents_type::rank() > 0)
10906c3fb27SDimitry Andric        mapping(const layout_stride::mapping<OtherExtents>&) noexcept;
11006c3fb27SDimitry Andric
11106c3fb27SDimitry Andric    constexpr mapping& operator=(const mapping&) noexcept = default;
11206c3fb27SDimitry Andric
11306c3fb27SDimitry Andric    // [mdspan.layout.right.obs], observers
11406c3fb27SDimitry Andric    constexpr const extents_type& extents() const noexcept { return extents_; }
11506c3fb27SDimitry Andric
11606c3fb27SDimitry Andric    constexpr index_type required_span_size() const noexcept;
11706c3fb27SDimitry Andric
11806c3fb27SDimitry Andric    template<class... Indices>
11906c3fb27SDimitry Andric      constexpr index_type operator()(Indices...) const noexcept;
12006c3fb27SDimitry Andric
12106c3fb27SDimitry Andric    static constexpr bool is_always_unique() noexcept { return true; }
12206c3fb27SDimitry Andric    static constexpr bool is_always_exhaustive() noexcept { return true; }
12306c3fb27SDimitry Andric    static constexpr bool is_always_strided() noexcept { return true; }
12406c3fb27SDimitry Andric
12506c3fb27SDimitry Andric    static constexpr bool is_unique() noexcept { return true; }
12606c3fb27SDimitry Andric    static constexpr bool is_exhaustive() noexcept { return true; }
12706c3fb27SDimitry Andric    static constexpr bool is_strided() noexcept { return true; }
12806c3fb27SDimitry Andric
12906c3fb27SDimitry Andric    constexpr index_type stride(rank_type) const noexcept;
13006c3fb27SDimitry Andric
13106c3fb27SDimitry Andric    template<class OtherExtents>
13206c3fb27SDimitry Andric      friend constexpr bool operator==(const mapping&, const mapping<OtherExtents>&) noexcept;
13306c3fb27SDimitry Andric
13406c3fb27SDimitry Andric  private:
13506c3fb27SDimitry Andric    extents_type extents_{};    // exposition only
13606c3fb27SDimitry Andric  };
13706c3fb27SDimitry Andric}
13806c3fb27SDimitry Andric
13906c3fb27SDimitry Andric// layout_right synopsis
14006c3fb27SDimitry Andric
14106c3fb27SDimitry Andricnamespace std {
14206c3fb27SDimitry Andric  template<class Extents>
14306c3fb27SDimitry Andric  class layout_right::mapping {
14406c3fb27SDimitry Andric  public:
14506c3fb27SDimitry Andric    using extents_type = Extents;
14606c3fb27SDimitry Andric    using index_type = typename extents_type::index_type;
14706c3fb27SDimitry Andric    using size_type = typename extents_type::size_type;
14806c3fb27SDimitry Andric    using rank_type = typename extents_type::rank_type;
14906c3fb27SDimitry Andric    using layout_type = layout_right;
15006c3fb27SDimitry Andric
15106c3fb27SDimitry Andric    // [mdspan.layout.right.cons], constructors
15206c3fb27SDimitry Andric    constexpr mapping() noexcept = default;
15306c3fb27SDimitry Andric    constexpr mapping(const mapping&) noexcept = default;
15406c3fb27SDimitry Andric    constexpr mapping(const extents_type&) noexcept;
15506c3fb27SDimitry Andric    template<class OtherExtents>
15606c3fb27SDimitry Andric      constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
15706c3fb27SDimitry Andric        mapping(const mapping<OtherExtents>&) noexcept;
15806c3fb27SDimitry Andric    template<class OtherExtents>
15906c3fb27SDimitry Andric      constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
16006c3fb27SDimitry Andric        mapping(const layout_left::mapping<OtherExtents>&) noexcept;
16106c3fb27SDimitry Andric    template<class OtherExtents>
16206c3fb27SDimitry Andric      constexpr explicit(extents_type::rank() > 0)
16306c3fb27SDimitry Andric        mapping(const layout_stride::mapping<OtherExtents>&) noexcept;
16406c3fb27SDimitry Andric
16506c3fb27SDimitry Andric    constexpr mapping& operator=(const mapping&) noexcept = default;
16606c3fb27SDimitry Andric
16706c3fb27SDimitry Andric    // [mdspan.layout.right.obs], observers
16806c3fb27SDimitry Andric    constexpr const extents_type& extents() const noexcept { return extents_; }
16906c3fb27SDimitry Andric
17006c3fb27SDimitry Andric    constexpr index_type required_span_size() const noexcept;
17106c3fb27SDimitry Andric
17206c3fb27SDimitry Andric    template<class... Indices>
17306c3fb27SDimitry Andric      constexpr index_type operator()(Indices...) const noexcept;
17406c3fb27SDimitry Andric
17506c3fb27SDimitry Andric    static constexpr bool is_always_unique() noexcept { return true; }
17606c3fb27SDimitry Andric    static constexpr bool is_always_exhaustive() noexcept { return true; }
17706c3fb27SDimitry Andric    static constexpr bool is_always_strided() noexcept { return true; }
17806c3fb27SDimitry Andric
17906c3fb27SDimitry Andric    static constexpr bool is_unique() noexcept { return true; }
18006c3fb27SDimitry Andric    static constexpr bool is_exhaustive() noexcept { return true; }
18106c3fb27SDimitry Andric    static constexpr bool is_strided() noexcept { return true; }
18206c3fb27SDimitry Andric
18306c3fb27SDimitry Andric    constexpr index_type stride(rank_type) const noexcept;
18406c3fb27SDimitry Andric
18506c3fb27SDimitry Andric    template<class OtherExtents>
18606c3fb27SDimitry Andric      friend constexpr bool operator==(const mapping&, const mapping<OtherExtents>&) noexcept;
18706c3fb27SDimitry Andric
18806c3fb27SDimitry Andric  private:
18906c3fb27SDimitry Andric    extents_type extents_{};    // exposition only
19006c3fb27SDimitry Andric  };
19106c3fb27SDimitry Andric}
19206c3fb27SDimitry Andric
193*5f757f3fSDimitry Andric// layout_stride synopsis
194*5f757f3fSDimitry Andric
195*5f757f3fSDimitry Andricnamespace std {
196*5f757f3fSDimitry Andric  template<class Extents>
197*5f757f3fSDimitry Andric  class layout_stride::mapping {
198*5f757f3fSDimitry Andric  public:
199*5f757f3fSDimitry Andric    using extents_type = Extents;
200*5f757f3fSDimitry Andric    using index_type = typename extents_type::index_type;
201*5f757f3fSDimitry Andric    using size_type = typename extents_type::size_type;
202*5f757f3fSDimitry Andric    using rank_type = typename extents_type::rank_type;
203*5f757f3fSDimitry Andric    using layout_type = layout_stride;
204*5f757f3fSDimitry Andric
205*5f757f3fSDimitry Andric  private:
206*5f757f3fSDimitry Andric    static constexpr rank_type rank_ = extents_type::rank();    // exposition only
207*5f757f3fSDimitry Andric
208*5f757f3fSDimitry Andric  public:
209*5f757f3fSDimitry Andric    // [mdspan.layout.stride.cons], constructors
210*5f757f3fSDimitry Andric    constexpr mapping() noexcept;
211*5f757f3fSDimitry Andric    constexpr mapping(const mapping&) noexcept = default;
212*5f757f3fSDimitry Andric    template<class OtherIndexType>
213*5f757f3fSDimitry Andric      constexpr mapping(const extents_type&, span<OtherIndexType, rank_>) noexcept;
214*5f757f3fSDimitry Andric    template<class OtherIndexType>
215*5f757f3fSDimitry Andric      constexpr mapping(const extents_type&, const array<OtherIndexType, rank_>&) noexcept;
216*5f757f3fSDimitry Andric
217*5f757f3fSDimitry Andric    template<class StridedLayoutMapping>
218*5f757f3fSDimitry Andric      constexpr explicit(see below) mapping(const StridedLayoutMapping&) noexcept;
219*5f757f3fSDimitry Andric
220*5f757f3fSDimitry Andric    constexpr mapping& operator=(const mapping&) noexcept = default;
221*5f757f3fSDimitry Andric
222*5f757f3fSDimitry Andric    // [mdspan.layout.stride.obs], observers
223*5f757f3fSDimitry Andric    constexpr const extents_type& extents() const noexcept { return extents_; }
224*5f757f3fSDimitry Andric    constexpr array<index_type, rank_> strides() const noexcept { return strides_; }
225*5f757f3fSDimitry Andric
226*5f757f3fSDimitry Andric    constexpr index_type required_span_size() const noexcept;
227*5f757f3fSDimitry Andric
228*5f757f3fSDimitry Andric    template<class... Indices>
229*5f757f3fSDimitry Andric      constexpr index_type operator()(Indices...) const noexcept;
230*5f757f3fSDimitry Andric
231*5f757f3fSDimitry Andric    static constexpr bool is_always_unique() noexcept { return true; }
232*5f757f3fSDimitry Andric    static constexpr bool is_always_exhaustive() noexcept { return false; }
233*5f757f3fSDimitry Andric    static constexpr bool is_always_strided() noexcept { return true; }
234*5f757f3fSDimitry Andric
235*5f757f3fSDimitry Andric    static constexpr bool is_unique() noexcept { return true; }
236*5f757f3fSDimitry Andric    constexpr bool is_exhaustive() const noexcept;
237*5f757f3fSDimitry Andric    static constexpr bool is_strided() noexcept { return true; }
238*5f757f3fSDimitry Andric
239*5f757f3fSDimitry Andric    constexpr index_type stride(rank_type i) const noexcept { return strides_[i]; }
240*5f757f3fSDimitry Andric
241*5f757f3fSDimitry Andric    template<class OtherMapping>
242*5f757f3fSDimitry Andric      friend constexpr bool operator==(const mapping&, const OtherMapping&) noexcept;
243*5f757f3fSDimitry Andric
244*5f757f3fSDimitry Andric  private:
245*5f757f3fSDimitry Andric    extents_type extents_{};                    // exposition only
246*5f757f3fSDimitry Andric    array<index_type, rank_> strides_{};        // exposition only
247*5f757f3fSDimitry Andric  };
248*5f757f3fSDimitry Andric}
249*5f757f3fSDimitry Andric
25006c3fb27SDimitry Andric// default_accessor synopsis
25106c3fb27SDimitry Andric
25206c3fb27SDimitry Andricnamespace std {
25306c3fb27SDimitry Andric  template<class ElementType>
25406c3fb27SDimitry Andric  struct default_accessor {
25506c3fb27SDimitry Andric    using offset_policy = default_accessor;
25606c3fb27SDimitry Andric    using element_type = ElementType;
25706c3fb27SDimitry Andric    using reference = ElementType&;
25806c3fb27SDimitry Andric    using data_handle_type = ElementType*;
25906c3fb27SDimitry Andric
26006c3fb27SDimitry Andric    constexpr default_accessor() noexcept = default;
26106c3fb27SDimitry Andric    template<class OtherElementType>
26206c3fb27SDimitry Andric      constexpr default_accessor(default_accessor<OtherElementType>) noexcept;
26306c3fb27SDimitry Andric    constexpr reference access(data_handle_type p, size_t i) const noexcept;
26406c3fb27SDimitry Andric    constexpr data_handle_type offset(data_handle_type p, size_t i) const noexcept;
26506c3fb27SDimitry Andric  };
26606c3fb27SDimitry Andric}
26706c3fb27SDimitry Andric
2688a4dda33SDimitry Andric// mdspan synopsis
2698a4dda33SDimitry Andric
2708a4dda33SDimitry Andricnamespace std {
2718a4dda33SDimitry Andric  template<class ElementType, class Extents, class LayoutPolicy = layout_right,
2728a4dda33SDimitry Andric           class AccessorPolicy = default_accessor<ElementType>>
2738a4dda33SDimitry Andric  class mdspan {
2748a4dda33SDimitry Andric  public:
2758a4dda33SDimitry Andric    using extents_type = Extents;
2768a4dda33SDimitry Andric    using layout_type = LayoutPolicy;
2778a4dda33SDimitry Andric    using accessor_type = AccessorPolicy;
2788a4dda33SDimitry Andric    using mapping_type = typename layout_type::template mapping<extents_type>;
2798a4dda33SDimitry Andric    using element_type = ElementType;
2808a4dda33SDimitry Andric    using value_type = remove_cv_t<element_type>;
2818a4dda33SDimitry Andric    using index_type = typename extents_type::index_type;
2828a4dda33SDimitry Andric    using size_type = typename extents_type::size_type;
2838a4dda33SDimitry Andric    using rank_type = typename extents_type::rank_type;
2848a4dda33SDimitry Andric    using data_handle_type = typename accessor_type::data_handle_type;
2858a4dda33SDimitry Andric    using reference = typename accessor_type::reference;
2868a4dda33SDimitry Andric
2878a4dda33SDimitry Andric    static constexpr rank_type rank() noexcept { return extents_type::rank(); }
2888a4dda33SDimitry Andric    static constexpr rank_type rank_dynamic() noexcept { return extents_type::rank_dynamic(); }
2898a4dda33SDimitry Andric    static constexpr size_t static_extent(rank_type r) noexcept
2908a4dda33SDimitry Andric      { return extents_type::static_extent(r); }
2918a4dda33SDimitry Andric    constexpr index_type extent(rank_type r) const noexcept { return extents().extent(r); }
2928a4dda33SDimitry Andric
2938a4dda33SDimitry Andric    // [mdspan.mdspan.cons], constructors
2948a4dda33SDimitry Andric    constexpr mdspan();
2958a4dda33SDimitry Andric    constexpr mdspan(const mdspan& rhs) = default;
2968a4dda33SDimitry Andric    constexpr mdspan(mdspan&& rhs) = default;
2978a4dda33SDimitry Andric
2988a4dda33SDimitry Andric    template<class... OtherIndexTypes>
2998a4dda33SDimitry Andric      constexpr explicit mdspan(data_handle_type ptr, OtherIndexTypes... exts);
3008a4dda33SDimitry Andric    template<class OtherIndexType, size_t N>
3018a4dda33SDimitry Andric      constexpr explicit(N != rank_dynamic())
3028a4dda33SDimitry Andric        mdspan(data_handle_type p, span<OtherIndexType, N> exts);
3038a4dda33SDimitry Andric    template<class OtherIndexType, size_t N>
3048a4dda33SDimitry Andric      constexpr explicit(N != rank_dynamic())
3058a4dda33SDimitry Andric        mdspan(data_handle_type p, const array<OtherIndexType, N>& exts);
3068a4dda33SDimitry Andric    constexpr mdspan(data_handle_type p, const extents_type& ext);
3078a4dda33SDimitry Andric    constexpr mdspan(data_handle_type p, const mapping_type& m);
3088a4dda33SDimitry Andric    constexpr mdspan(data_handle_type p, const mapping_type& m, const accessor_type& a);
3098a4dda33SDimitry Andric
3108a4dda33SDimitry Andric    template<class OtherElementType, class OtherExtents,
3118a4dda33SDimitry Andric             class OtherLayoutPolicy, class OtherAccessorPolicy>
3128a4dda33SDimitry Andric      constexpr explicit(see below)
3138a4dda33SDimitry Andric        mdspan(const mdspan<OtherElementType, OtherExtents,
3148a4dda33SDimitry Andric                            OtherLayoutPolicy, OtherAccessorPolicy>& other);
3158a4dda33SDimitry Andric
3168a4dda33SDimitry Andric    constexpr mdspan& operator=(const mdspan& rhs) = default;
3178a4dda33SDimitry Andric    constexpr mdspan& operator=(mdspan&& rhs) = default;
3188a4dda33SDimitry Andric
3198a4dda33SDimitry Andric    // [mdspan.mdspan.members], members
3208a4dda33SDimitry Andric    template<class... OtherIndexTypes>
3218a4dda33SDimitry Andric      constexpr reference operator[](OtherIndexTypes... indices) const;
3228a4dda33SDimitry Andric    template<class OtherIndexType>
3238a4dda33SDimitry Andric      constexpr reference operator[](span<OtherIndexType, rank()> indices) const;
3248a4dda33SDimitry Andric    template<class OtherIndexType>
3258a4dda33SDimitry Andric      constexpr reference operator[](const array<OtherIndexType, rank()>& indices) const;
3268a4dda33SDimitry Andric
3278a4dda33SDimitry Andric    constexpr size_type size() const noexcept;
3288a4dda33SDimitry Andric    [[nodiscard]] constexpr bool empty() const noexcept;
3298a4dda33SDimitry Andric
3308a4dda33SDimitry Andric    friend constexpr void swap(mdspan& x, mdspan& y) noexcept;
3318a4dda33SDimitry Andric
3328a4dda33SDimitry Andric    constexpr const extents_type& extents() const noexcept { return map_.extents(); }
3338a4dda33SDimitry Andric    constexpr const data_handle_type& data_handle() const noexcept { return ptr_; }
3348a4dda33SDimitry Andric    constexpr const mapping_type& mapping() const noexcept { return map_; }
3358a4dda33SDimitry Andric    constexpr const accessor_type& accessor() const noexcept { return acc_; }
3368a4dda33SDimitry Andric
337*5f757f3fSDimitry Andric    // per LWG-4021 "mdspan::is_always_meow() should be noexcept"
338*5f757f3fSDimitry Andric    static constexpr bool is_always_unique() noexcept
3398a4dda33SDimitry Andric      { return mapping_type::is_always_unique(); }
340*5f757f3fSDimitry Andric    static constexpr bool is_always_exhaustive() noexcept
3418a4dda33SDimitry Andric      { return mapping_type::is_always_exhaustive(); }
342*5f757f3fSDimitry Andric    static constexpr bool is_always_strided() noexcept
3438a4dda33SDimitry Andric      { return mapping_type::is_always_strided(); }
3448a4dda33SDimitry Andric
3458a4dda33SDimitry Andric    constexpr bool is_unique() const
3468a4dda33SDimitry Andric      { return map_.is_unique(); }
3478a4dda33SDimitry Andric    constexpr bool is_exhaustive() const
3488a4dda33SDimitry Andric      { return map_.is_exhaustive(); }
3498a4dda33SDimitry Andric    constexpr bool is_strided() const
3508a4dda33SDimitry Andric      { return map_.is_strided(); }
3518a4dda33SDimitry Andric    constexpr index_type stride(rank_type r) const
3528a4dda33SDimitry Andric      { return map_.stride(r); }
3538a4dda33SDimitry Andric
3548a4dda33SDimitry Andric  private:
3558a4dda33SDimitry Andric    accessor_type acc_;         // exposition only
3568a4dda33SDimitry Andric    mapping_type map_;          // exposition only
3578a4dda33SDimitry Andric    data_handle_type ptr_;      // exposition only
3588a4dda33SDimitry Andric  };
3598a4dda33SDimitry Andric
3608a4dda33SDimitry Andric  template<class CArray>
3618a4dda33SDimitry Andric    requires(is_array_v<CArray> && rank_v<CArray> == 1)
3628a4dda33SDimitry Andric    mdspan(CArray&)
3638a4dda33SDimitry Andric      -> mdspan<remove_all_extents_t<CArray>, extents<size_t, extent_v<CArray, 0>>>;
3648a4dda33SDimitry Andric
3658a4dda33SDimitry Andric  template<class Pointer>
3668a4dda33SDimitry Andric    requires(is_pointer_v<remove_reference_t<Pointer>>)
3678a4dda33SDimitry Andric    mdspan(Pointer&&)
3688a4dda33SDimitry Andric      -> mdspan<remove_pointer_t<remove_reference_t<Pointer>>, extents<size_t>>;
3698a4dda33SDimitry Andric
3708a4dda33SDimitry Andric  template<class ElementType, class... Integrals>
3718a4dda33SDimitry Andric    requires((is_convertible_v<Integrals, size_t> && ...) && sizeof...(Integrals) > 0)
3728a4dda33SDimitry Andric    explicit mdspan(ElementType*, Integrals...)
3738a4dda33SDimitry Andric      -> mdspan<ElementType, dextents<size_t, sizeof...(Integrals)>>;
3748a4dda33SDimitry Andric
3758a4dda33SDimitry Andric  template<class ElementType, class OtherIndexType, size_t N>
3768a4dda33SDimitry Andric    mdspan(ElementType*, span<OtherIndexType, N>)
3778a4dda33SDimitry Andric      -> mdspan<ElementType, dextents<size_t, N>>;
3788a4dda33SDimitry Andric
3798a4dda33SDimitry Andric  template<class ElementType, class OtherIndexType, size_t N>
3808a4dda33SDimitry Andric    mdspan(ElementType*, const array<OtherIndexType, N>&)
3818a4dda33SDimitry Andric      -> mdspan<ElementType, dextents<size_t, N>>;
3828a4dda33SDimitry Andric
3838a4dda33SDimitry Andric  template<class ElementType, class IndexType, size_t... ExtentsPack>
3848a4dda33SDimitry Andric    mdspan(ElementType*, const extents<IndexType, ExtentsPack...>&)
3858a4dda33SDimitry Andric      -> mdspan<ElementType, extents<IndexType, ExtentsPack...>>;
3868a4dda33SDimitry Andric
3878a4dda33SDimitry Andric  template<class ElementType, class MappingType>
3888a4dda33SDimitry Andric    mdspan(ElementType*, const MappingType&)
3898a4dda33SDimitry Andric      -> mdspan<ElementType, typename MappingType::extents_type,
3908a4dda33SDimitry Andric                typename MappingType::layout_type>;
3918a4dda33SDimitry Andric
3928a4dda33SDimitry Andric  template<class MappingType, class AccessorType>
3938a4dda33SDimitry Andric    mdspan(const typename AccessorType::data_handle_type&, const MappingType&,
3948a4dda33SDimitry Andric           const AccessorType&)
3958a4dda33SDimitry Andric      -> mdspan<typename AccessorType::element_type, typename MappingType::extents_type,
3968a4dda33SDimitry Andric                typename MappingType::layout_type, AccessorType>;
3978a4dda33SDimitry Andric}
39806c3fb27SDimitry Andric*/
39906c3fb27SDimitry Andric
40006c3fb27SDimitry Andric#ifndef _LIBCPP_MDSPAN
40106c3fb27SDimitry Andric#define _LIBCPP_MDSPAN
40206c3fb27SDimitry Andric
40306c3fb27SDimitry Andric#include <__config>
40406c3fb27SDimitry Andric#include <__fwd/mdspan.h>
40506c3fb27SDimitry Andric#include <__mdspan/default_accessor.h>
40606c3fb27SDimitry Andric#include <__mdspan/extents.h>
40706c3fb27SDimitry Andric#include <__mdspan/layout_left.h>
40806c3fb27SDimitry Andric#include <__mdspan/layout_right.h>
409*5f757f3fSDimitry Andric#include <__mdspan/layout_stride.h>
4108a4dda33SDimitry Andric#include <__mdspan/mdspan.h>
411*5f757f3fSDimitry Andric#include <version>
41206c3fb27SDimitry Andric
41306c3fb27SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
41406c3fb27SDimitry Andric#  pragma GCC system_header
41506c3fb27SDimitry Andric#endif
41606c3fb27SDimitry Andric
41706c3fb27SDimitry Andric#endif // _LIBCPP_MDSPAN
418