xref: /freebsd-src/contrib/llvm-project/libcxx/include/mdspan (revision 8a4dda33d67586ca2624f2a38417baa03a533a7f)
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;
2606c3fb27SDimitry Andric  struct layout_stride; // not implemented yet
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
19306c3fb27SDimitry Andric// default_accessor synopsis
19406c3fb27SDimitry Andric
19506c3fb27SDimitry Andricnamespace std {
19606c3fb27SDimitry Andric  template<class ElementType>
19706c3fb27SDimitry Andric  struct default_accessor {
19806c3fb27SDimitry Andric    using offset_policy = default_accessor;
19906c3fb27SDimitry Andric    using element_type = ElementType;
20006c3fb27SDimitry Andric    using reference = ElementType&;
20106c3fb27SDimitry Andric    using data_handle_type = ElementType*;
20206c3fb27SDimitry Andric
20306c3fb27SDimitry Andric    constexpr default_accessor() noexcept = default;
20406c3fb27SDimitry Andric    template<class OtherElementType>
20506c3fb27SDimitry Andric      constexpr default_accessor(default_accessor<OtherElementType>) noexcept;
20606c3fb27SDimitry Andric    constexpr reference access(data_handle_type p, size_t i) const noexcept;
20706c3fb27SDimitry Andric    constexpr data_handle_type offset(data_handle_type p, size_t i) const noexcept;
20806c3fb27SDimitry Andric  };
20906c3fb27SDimitry Andric}
21006c3fb27SDimitry Andric
211*8a4dda33SDimitry Andric// mdspan synopsis
212*8a4dda33SDimitry Andric
213*8a4dda33SDimitry Andricnamespace std {
214*8a4dda33SDimitry Andric  template<class ElementType, class Extents, class LayoutPolicy = layout_right,
215*8a4dda33SDimitry Andric           class AccessorPolicy = default_accessor<ElementType>>
216*8a4dda33SDimitry Andric  class mdspan {
217*8a4dda33SDimitry Andric  public:
218*8a4dda33SDimitry Andric    using extents_type = Extents;
219*8a4dda33SDimitry Andric    using layout_type = LayoutPolicy;
220*8a4dda33SDimitry Andric    using accessor_type = AccessorPolicy;
221*8a4dda33SDimitry Andric    using mapping_type = typename layout_type::template mapping<extents_type>;
222*8a4dda33SDimitry Andric    using element_type = ElementType;
223*8a4dda33SDimitry Andric    using value_type = remove_cv_t<element_type>;
224*8a4dda33SDimitry Andric    using index_type = typename extents_type::index_type;
225*8a4dda33SDimitry Andric    using size_type = typename extents_type::size_type;
226*8a4dda33SDimitry Andric    using rank_type = typename extents_type::rank_type;
227*8a4dda33SDimitry Andric    using data_handle_type = typename accessor_type::data_handle_type;
228*8a4dda33SDimitry Andric    using reference = typename accessor_type::reference;
229*8a4dda33SDimitry Andric
230*8a4dda33SDimitry Andric    static constexpr rank_type rank() noexcept { return extents_type::rank(); }
231*8a4dda33SDimitry Andric    static constexpr rank_type rank_dynamic() noexcept { return extents_type::rank_dynamic(); }
232*8a4dda33SDimitry Andric    static constexpr size_t static_extent(rank_type r) noexcept
233*8a4dda33SDimitry Andric      { return extents_type::static_extent(r); }
234*8a4dda33SDimitry Andric    constexpr index_type extent(rank_type r) const noexcept { return extents().extent(r); }
235*8a4dda33SDimitry Andric
236*8a4dda33SDimitry Andric    // [mdspan.mdspan.cons], constructors
237*8a4dda33SDimitry Andric    constexpr mdspan();
238*8a4dda33SDimitry Andric    constexpr mdspan(const mdspan& rhs) = default;
239*8a4dda33SDimitry Andric    constexpr mdspan(mdspan&& rhs) = default;
240*8a4dda33SDimitry Andric
241*8a4dda33SDimitry Andric    template<class... OtherIndexTypes>
242*8a4dda33SDimitry Andric      constexpr explicit mdspan(data_handle_type ptr, OtherIndexTypes... exts);
243*8a4dda33SDimitry Andric    template<class OtherIndexType, size_t N>
244*8a4dda33SDimitry Andric      constexpr explicit(N != rank_dynamic())
245*8a4dda33SDimitry Andric        mdspan(data_handle_type p, span<OtherIndexType, N> exts);
246*8a4dda33SDimitry Andric    template<class OtherIndexType, size_t N>
247*8a4dda33SDimitry Andric      constexpr explicit(N != rank_dynamic())
248*8a4dda33SDimitry Andric        mdspan(data_handle_type p, const array<OtherIndexType, N>& exts);
249*8a4dda33SDimitry Andric    constexpr mdspan(data_handle_type p, const extents_type& ext);
250*8a4dda33SDimitry Andric    constexpr mdspan(data_handle_type p, const mapping_type& m);
251*8a4dda33SDimitry Andric    constexpr mdspan(data_handle_type p, const mapping_type& m, const accessor_type& a);
252*8a4dda33SDimitry Andric
253*8a4dda33SDimitry Andric    template<class OtherElementType, class OtherExtents,
254*8a4dda33SDimitry Andric             class OtherLayoutPolicy, class OtherAccessorPolicy>
255*8a4dda33SDimitry Andric      constexpr explicit(see below)
256*8a4dda33SDimitry Andric        mdspan(const mdspan<OtherElementType, OtherExtents,
257*8a4dda33SDimitry Andric                            OtherLayoutPolicy, OtherAccessorPolicy>& other);
258*8a4dda33SDimitry Andric
259*8a4dda33SDimitry Andric    constexpr mdspan& operator=(const mdspan& rhs) = default;
260*8a4dda33SDimitry Andric    constexpr mdspan& operator=(mdspan&& rhs) = default;
261*8a4dda33SDimitry Andric
262*8a4dda33SDimitry Andric    // [mdspan.mdspan.members], members
263*8a4dda33SDimitry Andric    template<class... OtherIndexTypes>
264*8a4dda33SDimitry Andric      constexpr reference operator[](OtherIndexTypes... indices) const;
265*8a4dda33SDimitry Andric    template<class OtherIndexType>
266*8a4dda33SDimitry Andric      constexpr reference operator[](span<OtherIndexType, rank()> indices) const;
267*8a4dda33SDimitry Andric    template<class OtherIndexType>
268*8a4dda33SDimitry Andric      constexpr reference operator[](const array<OtherIndexType, rank()>& indices) const;
269*8a4dda33SDimitry Andric
270*8a4dda33SDimitry Andric    constexpr size_type size() const noexcept;
271*8a4dda33SDimitry Andric    [[nodiscard]] constexpr bool empty() const noexcept;
272*8a4dda33SDimitry Andric
273*8a4dda33SDimitry Andric    friend constexpr void swap(mdspan& x, mdspan& y) noexcept;
274*8a4dda33SDimitry Andric
275*8a4dda33SDimitry Andric    constexpr const extents_type& extents() const noexcept { return map_.extents(); }
276*8a4dda33SDimitry Andric    constexpr const data_handle_type& data_handle() const noexcept { return ptr_; }
277*8a4dda33SDimitry Andric    constexpr const mapping_type& mapping() const noexcept { return map_; }
278*8a4dda33SDimitry Andric    constexpr const accessor_type& accessor() const noexcept { return acc_; }
279*8a4dda33SDimitry Andric
280*8a4dda33SDimitry Andric    static constexpr bool is_always_unique()
281*8a4dda33SDimitry Andric      { return mapping_type::is_always_unique(); }
282*8a4dda33SDimitry Andric    static constexpr bool is_always_exhaustive()
283*8a4dda33SDimitry Andric      { return mapping_type::is_always_exhaustive(); }
284*8a4dda33SDimitry Andric    static constexpr bool is_always_strided()
285*8a4dda33SDimitry Andric      { return mapping_type::is_always_strided(); }
286*8a4dda33SDimitry Andric
287*8a4dda33SDimitry Andric    constexpr bool is_unique() const
288*8a4dda33SDimitry Andric      { return map_.is_unique(); }
289*8a4dda33SDimitry Andric    constexpr bool is_exhaustive() const
290*8a4dda33SDimitry Andric      { return map_.is_exhaustive(); }
291*8a4dda33SDimitry Andric    constexpr bool is_strided() const
292*8a4dda33SDimitry Andric      { return map_.is_strided(); }
293*8a4dda33SDimitry Andric    constexpr index_type stride(rank_type r) const
294*8a4dda33SDimitry Andric      { return map_.stride(r); }
295*8a4dda33SDimitry Andric
296*8a4dda33SDimitry Andric  private:
297*8a4dda33SDimitry Andric    accessor_type acc_;         // exposition only
298*8a4dda33SDimitry Andric    mapping_type map_;          // exposition only
299*8a4dda33SDimitry Andric    data_handle_type ptr_;      // exposition only
300*8a4dda33SDimitry Andric  };
301*8a4dda33SDimitry Andric
302*8a4dda33SDimitry Andric  template<class CArray>
303*8a4dda33SDimitry Andric    requires(is_array_v<CArray> && rank_v<CArray> == 1)
304*8a4dda33SDimitry Andric    mdspan(CArray&)
305*8a4dda33SDimitry Andric      -> mdspan<remove_all_extents_t<CArray>, extents<size_t, extent_v<CArray, 0>>>;
306*8a4dda33SDimitry Andric
307*8a4dda33SDimitry Andric  template<class Pointer>
308*8a4dda33SDimitry Andric    requires(is_pointer_v<remove_reference_t<Pointer>>)
309*8a4dda33SDimitry Andric    mdspan(Pointer&&)
310*8a4dda33SDimitry Andric      -> mdspan<remove_pointer_t<remove_reference_t<Pointer>>, extents<size_t>>;
311*8a4dda33SDimitry Andric
312*8a4dda33SDimitry Andric  template<class ElementType, class... Integrals>
313*8a4dda33SDimitry Andric    requires((is_convertible_v<Integrals, size_t> && ...) && sizeof...(Integrals) > 0)
314*8a4dda33SDimitry Andric    explicit mdspan(ElementType*, Integrals...)
315*8a4dda33SDimitry Andric      -> mdspan<ElementType, dextents<size_t, sizeof...(Integrals)>>;
316*8a4dda33SDimitry Andric
317*8a4dda33SDimitry Andric  template<class ElementType, class OtherIndexType, size_t N>
318*8a4dda33SDimitry Andric    mdspan(ElementType*, span<OtherIndexType, N>)
319*8a4dda33SDimitry Andric      -> mdspan<ElementType, dextents<size_t, N>>;
320*8a4dda33SDimitry Andric
321*8a4dda33SDimitry Andric  template<class ElementType, class OtherIndexType, size_t N>
322*8a4dda33SDimitry Andric    mdspan(ElementType*, const array<OtherIndexType, N>&)
323*8a4dda33SDimitry Andric      -> mdspan<ElementType, dextents<size_t, N>>;
324*8a4dda33SDimitry Andric
325*8a4dda33SDimitry Andric  template<class ElementType, class IndexType, size_t... ExtentsPack>
326*8a4dda33SDimitry Andric    mdspan(ElementType*, const extents<IndexType, ExtentsPack...>&)
327*8a4dda33SDimitry Andric      -> mdspan<ElementType, extents<IndexType, ExtentsPack...>>;
328*8a4dda33SDimitry Andric
329*8a4dda33SDimitry Andric  template<class ElementType, class MappingType>
330*8a4dda33SDimitry Andric    mdspan(ElementType*, const MappingType&)
331*8a4dda33SDimitry Andric      -> mdspan<ElementType, typename MappingType::extents_type,
332*8a4dda33SDimitry Andric                typename MappingType::layout_type>;
333*8a4dda33SDimitry Andric
334*8a4dda33SDimitry Andric  template<class MappingType, class AccessorType>
335*8a4dda33SDimitry Andric    mdspan(const typename AccessorType::data_handle_type&, const MappingType&,
336*8a4dda33SDimitry Andric           const AccessorType&)
337*8a4dda33SDimitry Andric      -> mdspan<typename AccessorType::element_type, typename MappingType::extents_type,
338*8a4dda33SDimitry Andric                typename MappingType::layout_type, AccessorType>;
339*8a4dda33SDimitry Andric}
34006c3fb27SDimitry Andric*/
34106c3fb27SDimitry Andric
34206c3fb27SDimitry Andric#ifndef _LIBCPP_MDSPAN
34306c3fb27SDimitry Andric#define _LIBCPP_MDSPAN
34406c3fb27SDimitry Andric
34506c3fb27SDimitry Andric#include <__config>
34606c3fb27SDimitry Andric#include <__fwd/mdspan.h>
34706c3fb27SDimitry Andric#include <__mdspan/default_accessor.h>
34806c3fb27SDimitry Andric#include <__mdspan/extents.h>
34906c3fb27SDimitry Andric#include <__mdspan/layout_left.h>
35006c3fb27SDimitry Andric#include <__mdspan/layout_right.h>
351*8a4dda33SDimitry Andric#include <__mdspan/mdspan.h>
35206c3fb27SDimitry Andric
35306c3fb27SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
35406c3fb27SDimitry Andric#  pragma GCC system_header
35506c3fb27SDimitry Andric#endif
35606c3fb27SDimitry Andric
35706c3fb27SDimitry Andric#endif // _LIBCPP_MDSPAN
358