xref: /llvm-project/libcxx/include/mdspan (revision b9a2658a3e8bd13b0f9e7a8a440832a95b377216)
1fcaccf81SChristian Trott// -*- C++ -*-
2fcaccf81SChristian Trott//===----------------------------------------------------------------------===//
3fcaccf81SChristian Trott//
4fcaccf81SChristian Trott// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5fcaccf81SChristian Trott// See https://llvm.org/LICENSE.txt for license information.
6fcaccf81SChristian Trott// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7fcaccf81SChristian Trott//
8fcaccf81SChristian Trott//===---------------------------------------------------------------------===//
9fcaccf81SChristian Trott
10fcaccf81SChristian Trott/*
11cfa096d9SChristian Trott
12cfa096d9SChristian Trott// Overall mdspan synopsis
13cfa096d9SChristian Trott
14cfa096d9SChristian Trottnamespace std {
15cfa096d9SChristian Trott  // [mdspan.extents], class template extents
16cfa096d9SChristian Trott  template<class IndexType, size_t... Extents>
17cfa096d9SChristian Trott    class extents;
18cfa096d9SChristian Trott
19cfa096d9SChristian Trott  // [mdspan.extents.dextents], alias template dextents
20cfa096d9SChristian Trott  template<class IndexType, size_t Rank>
21cfa096d9SChristian Trott    using dextents = see below;
22cfa096d9SChristian Trott
234e338dceSXiaoyang Liu  // [mdspan.extents.dims], alias template dims
244e338dceSXiaoyang Liu  template<size_t Rank, class IndexType = size_t>
254e338dceSXiaoyang Liu    using dims = see below; // since C++26
264e338dceSXiaoyang Liu
27cfa096d9SChristian Trott  // [mdspan.layout], layout mapping
28b4ff8938SChristian Trott  struct layout_left;
29cfa096d9SChristian Trott  struct layout_right;
307c44167dSMark de Wever  struct layout_stride;
31cfa096d9SChristian Trott
32cfa096d9SChristian Trott  // [mdspan.accessor.default], class template default_accessor
33cfa096d9SChristian Trott  template<class ElementType>
3420c6b9d4SChristian Trott    class default_accessor;
35cfa096d9SChristian Trott
36cfa096d9SChristian Trott  // [mdspan.mdspan], class template mdspan
37cfa096d9SChristian Trott  template<class ElementType, class Extents, class LayoutPolicy = layout_right,
38cfa096d9SChristian Trott           class AccessorPolicy = default_accessor<ElementType>>
39cfa096d9SChristian Trott    class mdspan; // not implemented yet
40cfa096d9SChristian Trott}
41cfa096d9SChristian Trott
42cfa096d9SChristian Trott// extents synopsis
43fcaccf81SChristian Trott
44fcaccf81SChristian Trottnamespace std {
45fcaccf81SChristian Trott  template<class _IndexType, size_t... _Extents>
46fcaccf81SChristian Trott  class extents {
47fcaccf81SChristian Trott  public:
48fcaccf81SChristian Trott    using index_type = _IndexType;
49fcaccf81SChristian Trott    using size_type = make_unsigned_t<index_type>;
50fcaccf81SChristian Trott    using rank_type = size_t;
51fcaccf81SChristian Trott
52fcaccf81SChristian Trott    // [mdspan.extents.obs], observers of the multidimensional index space
53fcaccf81SChristian Trott    static constexpr rank_type rank() noexcept { return sizeof...(_Extents); }
54fcaccf81SChristian Trott    static constexpr rank_type rank_dynamic() noexcept { return dynamic-index(rank()); }
55fcaccf81SChristian Trott    static constexpr size_t static_extent(rank_type) noexcept;
56fcaccf81SChristian Trott    constexpr index_type extent(rank_type) const noexcept;
57fcaccf81SChristian Trott
58fcaccf81SChristian Trott    // [mdspan.extents.cons], constructors
59fcaccf81SChristian Trott    constexpr extents() noexcept = default;
60fcaccf81SChristian Trott
61fcaccf81SChristian Trott    template<class _OtherIndexType, size_t... _OtherExtents>
62fcaccf81SChristian Trott      constexpr explicit(see below)
63fcaccf81SChristian Trott        extents(const extents<_OtherIndexType, _OtherExtents...>&) noexcept;
64fcaccf81SChristian Trott    template<class... _OtherIndexTypes>
65fcaccf81SChristian Trott      constexpr explicit extents(_OtherIndexTypes...) noexcept;
66fcaccf81SChristian Trott    template<class _OtherIndexType, size_t N>
67fcaccf81SChristian Trott      constexpr explicit(N != rank_dynamic())
68fcaccf81SChristian Trott        extents(span<_OtherIndexType, N>) noexcept;
69fcaccf81SChristian Trott    template<class _OtherIndexType, size_t N>
70fcaccf81SChristian Trott      constexpr explicit(N != rank_dynamic())
71fcaccf81SChristian Trott        extents(const array<_OtherIndexType, N>&) noexcept;
72fcaccf81SChristian Trott
73fcaccf81SChristian Trott    // [mdspan.extents.cmp], comparison operators
74fcaccf81SChristian Trott    template<class _OtherIndexType, size_t... _OtherExtents>
75fcaccf81SChristian Trott      friend constexpr bool operator==(const extents&,
76fcaccf81SChristian Trott                                       const extents<_OtherIndexType, _OtherExtents...>&) noexcept;
77fcaccf81SChristian Trott
78fcaccf81SChristian Trott  private:
79fcaccf81SChristian Trott    // libcxx note: we do not use an array here, but we need to preserve the as-if behavior
80fcaccf81SChristian Trott    // for example the default constructor must zero initialize dynamic extents
81fcaccf81SChristian Trott    array<index_type, rank_dynamic()> dynamic-extents{};                // exposition only
82fcaccf81SChristian Trott  };
83fcaccf81SChristian Trott
84fcaccf81SChristian Trott  template<class... Integrals>
85fcaccf81SChristian Trott    explicit extents(Integrals...)
86fcaccf81SChristian Trott      -> see below;
87fcaccf81SChristian Trott}
88cfa096d9SChristian Trott
89b4ff8938SChristian Trott// layout_left synopsis
90b4ff8938SChristian Trott
91b4ff8938SChristian Trottnamespace std {
92b4ff8938SChristian Trott  template<class Extents>
93b4ff8938SChristian Trott  class layout_left::mapping {
94b4ff8938SChristian Trott  public:
95b4ff8938SChristian Trott    using extents_type = Extents;
96b4ff8938SChristian Trott    using index_type = typename extents_type::index_type;
97b4ff8938SChristian Trott    using size_type = typename extents_type::size_type;
98b4ff8938SChristian Trott    using rank_type = typename extents_type::rank_type;
99b4ff8938SChristian Trott    using layout_type = layout_left;
100b4ff8938SChristian Trott
101b4ff8938SChristian Trott    // [mdspan.layout.right.cons], constructors
102b4ff8938SChristian Trott    constexpr mapping() noexcept = default;
103b4ff8938SChristian Trott    constexpr mapping(const mapping&) noexcept = default;
104b4ff8938SChristian Trott    constexpr mapping(const extents_type&) noexcept;
105b4ff8938SChristian Trott    template<class OtherExtents>
106b4ff8938SChristian Trott      constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
107b4ff8938SChristian Trott        mapping(const mapping<OtherExtents>&) noexcept;
108b4ff8938SChristian Trott    template<class OtherExtents>
109b4ff8938SChristian Trott      constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
110b4ff8938SChristian Trott        mapping(const layout_right::mapping<OtherExtents>&) noexcept;
111b4ff8938SChristian Trott    template<class OtherExtents>
112b4ff8938SChristian Trott      constexpr explicit(extents_type::rank() > 0)
113b4ff8938SChristian Trott        mapping(const layout_stride::mapping<OtherExtents>&) noexcept;
114b4ff8938SChristian Trott
115b4ff8938SChristian Trott    constexpr mapping& operator=(const mapping&) noexcept = default;
116b4ff8938SChristian Trott
117b4ff8938SChristian Trott    // [mdspan.layout.right.obs], observers
118b4ff8938SChristian Trott    constexpr const extents_type& extents() const noexcept { return extents_; }
119b4ff8938SChristian Trott
120b4ff8938SChristian Trott    constexpr index_type required_span_size() const noexcept;
121b4ff8938SChristian Trott
122b4ff8938SChristian Trott    template<class... Indices>
123b4ff8938SChristian Trott      constexpr index_type operator()(Indices...) const noexcept;
124b4ff8938SChristian Trott
125b4ff8938SChristian Trott    static constexpr bool is_always_unique() noexcept { return true; }
126b4ff8938SChristian Trott    static constexpr bool is_always_exhaustive() noexcept { return true; }
127b4ff8938SChristian Trott    static constexpr bool is_always_strided() noexcept { return true; }
128b4ff8938SChristian Trott
129b4ff8938SChristian Trott    static constexpr bool is_unique() noexcept { return true; }
130b4ff8938SChristian Trott    static constexpr bool is_exhaustive() noexcept { return true; }
131b4ff8938SChristian Trott    static constexpr bool is_strided() noexcept { return true; }
132b4ff8938SChristian Trott
133b4ff8938SChristian Trott    constexpr index_type stride(rank_type) const noexcept;
134b4ff8938SChristian Trott
135b4ff8938SChristian Trott    template<class OtherExtents>
136b4ff8938SChristian Trott      friend constexpr bool operator==(const mapping&, const mapping<OtherExtents>&) noexcept;
137b4ff8938SChristian Trott
138b4ff8938SChristian Trott  private:
139b4ff8938SChristian Trott    extents_type extents_{};    // exposition only
140b4ff8938SChristian Trott  };
141b4ff8938SChristian Trott}
142b4ff8938SChristian Trott
143cfa096d9SChristian Trott// layout_right synopsis
144cfa096d9SChristian Trott
145cfa096d9SChristian Trottnamespace std {
146cfa096d9SChristian Trott  template<class Extents>
147cfa096d9SChristian Trott  class layout_right::mapping {
148cfa096d9SChristian Trott  public:
149cfa096d9SChristian Trott    using extents_type = Extents;
150cfa096d9SChristian Trott    using index_type = typename extents_type::index_type;
151cfa096d9SChristian Trott    using size_type = typename extents_type::size_type;
152cfa096d9SChristian Trott    using rank_type = typename extents_type::rank_type;
153cfa096d9SChristian Trott    using layout_type = layout_right;
154cfa096d9SChristian Trott
155cfa096d9SChristian Trott    // [mdspan.layout.right.cons], constructors
156cfa096d9SChristian Trott    constexpr mapping() noexcept = default;
157cfa096d9SChristian Trott    constexpr mapping(const mapping&) noexcept = default;
158cfa096d9SChristian Trott    constexpr mapping(const extents_type&) noexcept;
159cfa096d9SChristian Trott    template<class OtherExtents>
160cfa096d9SChristian Trott      constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
161cfa096d9SChristian Trott        mapping(const mapping<OtherExtents>&) noexcept;
162cfa096d9SChristian Trott    template<class OtherExtents>
163cfa096d9SChristian Trott      constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
164cfa096d9SChristian Trott        mapping(const layout_left::mapping<OtherExtents>&) noexcept;
165cfa096d9SChristian Trott    template<class OtherExtents>
166cfa096d9SChristian Trott      constexpr explicit(extents_type::rank() > 0)
167cfa096d9SChristian Trott        mapping(const layout_stride::mapping<OtherExtents>&) noexcept;
168cfa096d9SChristian Trott
169cfa096d9SChristian Trott    constexpr mapping& operator=(const mapping&) noexcept = default;
170cfa096d9SChristian Trott
171cfa096d9SChristian Trott    // [mdspan.layout.right.obs], observers
172cfa096d9SChristian Trott    constexpr const extents_type& extents() const noexcept { return extents_; }
173cfa096d9SChristian Trott
174cfa096d9SChristian Trott    constexpr index_type required_span_size() const noexcept;
175cfa096d9SChristian Trott
176cfa096d9SChristian Trott    template<class... Indices>
177cfa096d9SChristian Trott      constexpr index_type operator()(Indices...) const noexcept;
178cfa096d9SChristian Trott
179cfa096d9SChristian Trott    static constexpr bool is_always_unique() noexcept { return true; }
180cfa096d9SChristian Trott    static constexpr bool is_always_exhaustive() noexcept { return true; }
181cfa096d9SChristian Trott    static constexpr bool is_always_strided() noexcept { return true; }
182cfa096d9SChristian Trott
183cfa096d9SChristian Trott    static constexpr bool is_unique() noexcept { return true; }
184cfa096d9SChristian Trott    static constexpr bool is_exhaustive() noexcept { return true; }
185cfa096d9SChristian Trott    static constexpr bool is_strided() noexcept { return true; }
186cfa096d9SChristian Trott
187cfa096d9SChristian Trott    constexpr index_type stride(rank_type) const noexcept;
188cfa096d9SChristian Trott
189cfa096d9SChristian Trott    template<class OtherExtents>
190cfa096d9SChristian Trott      friend constexpr bool operator==(const mapping&, const mapping<OtherExtents>&) noexcept;
191cfa096d9SChristian Trott
192cfa096d9SChristian Trott  private:
193cfa096d9SChristian Trott    extents_type extents_{};    // exposition only
194cfa096d9SChristian Trott  };
195cfa096d9SChristian Trott}
196cfa096d9SChristian Trott
197639a0986SChristian Trott// layout_stride synopsis
198639a0986SChristian Trott
199639a0986SChristian Trottnamespace std {
200639a0986SChristian Trott  template<class Extents>
201639a0986SChristian Trott  class layout_stride::mapping {
202639a0986SChristian Trott  public:
203639a0986SChristian Trott    using extents_type = Extents;
204639a0986SChristian Trott    using index_type = typename extents_type::index_type;
205639a0986SChristian Trott    using size_type = typename extents_type::size_type;
206639a0986SChristian Trott    using rank_type = typename extents_type::rank_type;
207639a0986SChristian Trott    using layout_type = layout_stride;
208639a0986SChristian Trott
209639a0986SChristian Trott  private:
210639a0986SChristian Trott    static constexpr rank_type rank_ = extents_type::rank();    // exposition only
211639a0986SChristian Trott
212639a0986SChristian Trott  public:
213639a0986SChristian Trott    // [mdspan.layout.stride.cons], constructors
214639a0986SChristian Trott    constexpr mapping() noexcept;
215639a0986SChristian Trott    constexpr mapping(const mapping&) noexcept = default;
216639a0986SChristian Trott    template<class OtherIndexType>
217639a0986SChristian Trott      constexpr mapping(const extents_type&, span<OtherIndexType, rank_>) noexcept;
218639a0986SChristian Trott    template<class OtherIndexType>
219639a0986SChristian Trott      constexpr mapping(const extents_type&, const array<OtherIndexType, rank_>&) noexcept;
220639a0986SChristian Trott
221639a0986SChristian Trott    template<class StridedLayoutMapping>
222639a0986SChristian Trott      constexpr explicit(see below) mapping(const StridedLayoutMapping&) noexcept;
223639a0986SChristian Trott
224639a0986SChristian Trott    constexpr mapping& operator=(const mapping&) noexcept = default;
225639a0986SChristian Trott
226639a0986SChristian Trott    // [mdspan.layout.stride.obs], observers
227639a0986SChristian Trott    constexpr const extents_type& extents() const noexcept { return extents_; }
228639a0986SChristian Trott    constexpr array<index_type, rank_> strides() const noexcept { return strides_; }
229639a0986SChristian Trott
230639a0986SChristian Trott    constexpr index_type required_span_size() const noexcept;
231639a0986SChristian Trott
232639a0986SChristian Trott    template<class... Indices>
233639a0986SChristian Trott      constexpr index_type operator()(Indices...) const noexcept;
234639a0986SChristian Trott
235639a0986SChristian Trott    static constexpr bool is_always_unique() noexcept { return true; }
236639a0986SChristian Trott    static constexpr bool is_always_exhaustive() noexcept { return false; }
237639a0986SChristian Trott    static constexpr bool is_always_strided() noexcept { return true; }
238639a0986SChristian Trott
239639a0986SChristian Trott    static constexpr bool is_unique() noexcept { return true; }
240639a0986SChristian Trott    constexpr bool is_exhaustive() const noexcept;
241639a0986SChristian Trott    static constexpr bool is_strided() noexcept { return true; }
242639a0986SChristian Trott
243639a0986SChristian Trott    constexpr index_type stride(rank_type i) const noexcept { return strides_[i]; }
244639a0986SChristian Trott
245639a0986SChristian Trott    template<class OtherMapping>
246639a0986SChristian Trott      friend constexpr bool operator==(const mapping&, const OtherMapping&) noexcept;
247639a0986SChristian Trott
248639a0986SChristian Trott  private:
249639a0986SChristian Trott    extents_type extents_{};                    // exposition only
250639a0986SChristian Trott    array<index_type, rank_> strides_{};        // exposition only
251639a0986SChristian Trott  };
252639a0986SChristian Trott}
253639a0986SChristian Trott
25420c6b9d4SChristian Trott// default_accessor synopsis
25520c6b9d4SChristian Trott
25620c6b9d4SChristian Trottnamespace std {
25720c6b9d4SChristian Trott  template<class ElementType>
25820c6b9d4SChristian Trott  struct default_accessor {
25920c6b9d4SChristian Trott    using offset_policy = default_accessor;
26020c6b9d4SChristian Trott    using element_type = ElementType;
26120c6b9d4SChristian Trott    using reference = ElementType&;
26220c6b9d4SChristian Trott    using data_handle_type = ElementType*;
26320c6b9d4SChristian Trott
26420c6b9d4SChristian Trott    constexpr default_accessor() noexcept = default;
26520c6b9d4SChristian Trott    template<class OtherElementType>
26620c6b9d4SChristian Trott      constexpr default_accessor(default_accessor<OtherElementType>) noexcept;
26720c6b9d4SChristian Trott    constexpr reference access(data_handle_type p, size_t i) const noexcept;
26820c6b9d4SChristian Trott    constexpr data_handle_type offset(data_handle_type p, size_t i) const noexcept;
26920c6b9d4SChristian Trott  };
27020c6b9d4SChristian Trott}
27120c6b9d4SChristian Trott
272fc487657SChristian Trott// mdspan synopsis
273fc487657SChristian Trott
274fc487657SChristian Trottnamespace std {
275fc487657SChristian Trott  template<class ElementType, class Extents, class LayoutPolicy = layout_right,
276fc487657SChristian Trott           class AccessorPolicy = default_accessor<ElementType>>
277fc487657SChristian Trott  class mdspan {
278fc487657SChristian Trott  public:
279fc487657SChristian Trott    using extents_type = Extents;
280fc487657SChristian Trott    using layout_type = LayoutPolicy;
281fc487657SChristian Trott    using accessor_type = AccessorPolicy;
282fc487657SChristian Trott    using mapping_type = typename layout_type::template mapping<extents_type>;
283fc487657SChristian Trott    using element_type = ElementType;
284fc487657SChristian Trott    using value_type = remove_cv_t<element_type>;
285fc487657SChristian Trott    using index_type = typename extents_type::index_type;
286fc487657SChristian Trott    using size_type = typename extents_type::size_type;
287fc487657SChristian Trott    using rank_type = typename extents_type::rank_type;
288fc487657SChristian Trott    using data_handle_type = typename accessor_type::data_handle_type;
289fc487657SChristian Trott    using reference = typename accessor_type::reference;
290fc487657SChristian Trott
291fc487657SChristian Trott    static constexpr rank_type rank() noexcept { return extents_type::rank(); }
292fc487657SChristian Trott    static constexpr rank_type rank_dynamic() noexcept { return extents_type::rank_dynamic(); }
293fc487657SChristian Trott    static constexpr size_t static_extent(rank_type r) noexcept
294fc487657SChristian Trott      { return extents_type::static_extent(r); }
295fc487657SChristian Trott    constexpr index_type extent(rank_type r) const noexcept { return extents().extent(r); }
296fc487657SChristian Trott
297fc487657SChristian Trott    // [mdspan.mdspan.cons], constructors
298fc487657SChristian Trott    constexpr mdspan();
299fc487657SChristian Trott    constexpr mdspan(const mdspan& rhs) = default;
300fc487657SChristian Trott    constexpr mdspan(mdspan&& rhs) = default;
301fc487657SChristian Trott
302fc487657SChristian Trott    template<class... OtherIndexTypes>
303fc487657SChristian Trott      constexpr explicit mdspan(data_handle_type ptr, OtherIndexTypes... exts);
304fc487657SChristian Trott    template<class OtherIndexType, size_t N>
305fc487657SChristian Trott      constexpr explicit(N != rank_dynamic())
306fc487657SChristian Trott        mdspan(data_handle_type p, span<OtherIndexType, N> exts);
307fc487657SChristian Trott    template<class OtherIndexType, size_t N>
308fc487657SChristian Trott      constexpr explicit(N != rank_dynamic())
309fc487657SChristian Trott        mdspan(data_handle_type p, const array<OtherIndexType, N>& exts);
310fc487657SChristian Trott    constexpr mdspan(data_handle_type p, const extents_type& ext);
311fc487657SChristian Trott    constexpr mdspan(data_handle_type p, const mapping_type& m);
312fc487657SChristian Trott    constexpr mdspan(data_handle_type p, const mapping_type& m, const accessor_type& a);
313fc487657SChristian Trott
314fc487657SChristian Trott    template<class OtherElementType, class OtherExtents,
315fc487657SChristian Trott             class OtherLayoutPolicy, class OtherAccessorPolicy>
316fc487657SChristian Trott      constexpr explicit(see below)
317fc487657SChristian Trott        mdspan(const mdspan<OtherElementType, OtherExtents,
318fc487657SChristian Trott                            OtherLayoutPolicy, OtherAccessorPolicy>& other);
319fc487657SChristian Trott
320fc487657SChristian Trott    constexpr mdspan& operator=(const mdspan& rhs) = default;
321fc487657SChristian Trott    constexpr mdspan& operator=(mdspan&& rhs) = default;
322fc487657SChristian Trott
323fc487657SChristian Trott    // [mdspan.mdspan.members], members
324fc487657SChristian Trott    template<class... OtherIndexTypes>
325fc487657SChristian Trott      constexpr reference operator[](OtherIndexTypes... indices) const;
326fc487657SChristian Trott    template<class OtherIndexType>
327fc487657SChristian Trott      constexpr reference operator[](span<OtherIndexType, rank()> indices) const;
328fc487657SChristian Trott    template<class OtherIndexType>
329fc487657SChristian Trott      constexpr reference operator[](const array<OtherIndexType, rank()>& indices) const;
330fc487657SChristian Trott
331fc487657SChristian Trott    constexpr size_type size() const noexcept;
332fc487657SChristian Trott    [[nodiscard]] constexpr bool empty() const noexcept;
333fc487657SChristian Trott
334fc487657SChristian Trott    friend constexpr void swap(mdspan& x, mdspan& y) noexcept;
335fc487657SChristian Trott
336fc487657SChristian Trott    constexpr const extents_type& extents() const noexcept { return map_.extents(); }
337fc487657SChristian Trott    constexpr const data_handle_type& data_handle() const noexcept { return ptr_; }
338fc487657SChristian Trott    constexpr const mapping_type& mapping() const noexcept { return map_; }
339fc487657SChristian Trott    constexpr const accessor_type& accessor() const noexcept { return acc_; }
340fc487657SChristian Trott
34167c40333SStephan T. Lavavej    // per LWG-4021 "mdspan::is_always_meow() should be noexcept"
34267c40333SStephan T. Lavavej    static constexpr bool is_always_unique() noexcept
343fc487657SChristian Trott      { return mapping_type::is_always_unique(); }
34467c40333SStephan T. Lavavej    static constexpr bool is_always_exhaustive() noexcept
345fc487657SChristian Trott      { return mapping_type::is_always_exhaustive(); }
34667c40333SStephan T. Lavavej    static constexpr bool is_always_strided() noexcept
347fc487657SChristian Trott      { return mapping_type::is_always_strided(); }
348fc487657SChristian Trott
349fc487657SChristian Trott    constexpr bool is_unique() const
350fc487657SChristian Trott      { return map_.is_unique(); }
351fc487657SChristian Trott    constexpr bool is_exhaustive() const
352fc487657SChristian Trott      { return map_.is_exhaustive(); }
353fc487657SChristian Trott    constexpr bool is_strided() const
354fc487657SChristian Trott      { return map_.is_strided(); }
355fc487657SChristian Trott    constexpr index_type stride(rank_type r) const
356fc487657SChristian Trott      { return map_.stride(r); }
357fc487657SChristian Trott
358fc487657SChristian Trott  private:
359fc487657SChristian Trott    accessor_type acc_;         // exposition only
360fc487657SChristian Trott    mapping_type map_;          // exposition only
361fc487657SChristian Trott    data_handle_type ptr_;      // exposition only
362fc487657SChristian Trott  };
363fc487657SChristian Trott
364fc487657SChristian Trott  template<class CArray>
365fc487657SChristian Trott    requires(is_array_v<CArray> && rank_v<CArray> == 1)
366fc487657SChristian Trott    mdspan(CArray&)
367fc487657SChristian Trott      -> mdspan<remove_all_extents_t<CArray>, extents<size_t, extent_v<CArray, 0>>>;
368fc487657SChristian Trott
369fc487657SChristian Trott  template<class Pointer>
370fc487657SChristian Trott    requires(is_pointer_v<remove_reference_t<Pointer>>)
371fc487657SChristian Trott    mdspan(Pointer&&)
372fc487657SChristian Trott      -> mdspan<remove_pointer_t<remove_reference_t<Pointer>>, extents<size_t>>;
373fc487657SChristian Trott
374fc487657SChristian Trott  template<class ElementType, class... Integrals>
375fc487657SChristian Trott    requires((is_convertible_v<Integrals, size_t> && ...) && sizeof...(Integrals) > 0)
376fc487657SChristian Trott    explicit mdspan(ElementType*, Integrals...)
3777cafe04eSXiaoyang Liu      -> mdspan<ElementType, dextents<size_t, sizeof...(Integrals)>>;            // until C++26
3787cafe04eSXiaoyang Liu  template<class ElementType, class... Integrals>
3797cafe04eSXiaoyang Liu    requires((is_convertible_v<Integrals, size_t> && ...) && sizeof...(Integrals) > 0)
3807cafe04eSXiaoyang Liu    explicit mdspan(ElementType*, Integrals...)
3817cafe04eSXiaoyang Liu      -> mdspan<ElementType, extents<size_t, maybe-static-ext<Integrals>...>>;  // since C++26
382fc487657SChristian Trott
383fc487657SChristian Trott  template<class ElementType, class OtherIndexType, size_t N>
384fc487657SChristian Trott    mdspan(ElementType*, span<OtherIndexType, N>)
385fc487657SChristian Trott      -> mdspan<ElementType, dextents<size_t, N>>;
386fc487657SChristian Trott
387fc487657SChristian Trott  template<class ElementType, class OtherIndexType, size_t N>
388fc487657SChristian Trott    mdspan(ElementType*, const array<OtherIndexType, N>&)
389fc487657SChristian Trott      -> mdspan<ElementType, dextents<size_t, N>>;
390fc487657SChristian Trott
391fc487657SChristian Trott  template<class ElementType, class IndexType, size_t... ExtentsPack>
392fc487657SChristian Trott    mdspan(ElementType*, const extents<IndexType, ExtentsPack...>&)
393fc487657SChristian Trott      -> mdspan<ElementType, extents<IndexType, ExtentsPack...>>;
394fc487657SChristian Trott
395fc487657SChristian Trott  template<class ElementType, class MappingType>
396fc487657SChristian Trott    mdspan(ElementType*, const MappingType&)
397fc487657SChristian Trott      -> mdspan<ElementType, typename MappingType::extents_type,
398fc487657SChristian Trott                typename MappingType::layout_type>;
399fc487657SChristian Trott
400fc487657SChristian Trott  template<class MappingType, class AccessorType>
401fc487657SChristian Trott    mdspan(const typename AccessorType::data_handle_type&, const MappingType&,
402fc487657SChristian Trott           const AccessorType&)
403fc487657SChristian Trott      -> mdspan<typename AccessorType::element_type, typename MappingType::extents_type,
404fc487657SChristian Trott                typename MappingType::layout_type, AccessorType>;
405fc487657SChristian Trott}
406fcaccf81SChristian Trott*/
407fcaccf81SChristian Trott
408fcaccf81SChristian Trott#ifndef _LIBCPP_MDSPAN
409fcaccf81SChristian Trott#define _LIBCPP_MDSPAN
410fcaccf81SChristian Trott
411*b9a2658aSNikolas Klauser#if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
412*b9a2658aSNikolas Klauser#  include <__cxx03/mdspan>
413*b9a2658aSNikolas Klauser#else
414fcaccf81SChristian Trott#  include <__config>
415dfddc0c4SNikolas Klauser
416dfddc0c4SNikolas Klauser#  if _LIBCPP_STD_VER >= 23
417cfa096d9SChristian Trott#    include <__fwd/mdspan.h>
41820c6b9d4SChristian Trott#    include <__mdspan/default_accessor.h>
419fcaccf81SChristian Trott#    include <__mdspan/extents.h>
420b4ff8938SChristian Trott#    include <__mdspan/layout_left.h>
421cfa096d9SChristian Trott#    include <__mdspan/layout_right.h>
422639a0986SChristian Trott#    include <__mdspan/layout_stride.h>
423fc487657SChristian Trott#    include <__mdspan/mdspan.h>
424dfddc0c4SNikolas Klauser#  endif
425dfddc0c4SNikolas Klauser
426639a0986SChristian Trott#  include <version>
427fcaccf81SChristian Trott
428fcaccf81SChristian Trott#  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
429fcaccf81SChristian Trott#    pragma GCC system_header
430fcaccf81SChristian Trott#  endif
431*b9a2658aSNikolas Klauser#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
432fcaccf81SChristian Trott
433fcaccf81SChristian Trott#endif // _LIBCPP_MDSPAN
434