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