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 23*0fca6ea1SDimitry Andric // [mdspan.extents.dims], alias template dims 24*0fca6ea1SDimitry Andric template<size_t Rank, class IndexType = size_t> 25*0fca6ea1SDimitry Andric using dims = see below; // since C++26 26*0fca6ea1SDimitry Andric 2706c3fb27SDimitry Andric // [mdspan.layout], layout mapping 2806c3fb27SDimitry Andric struct layout_left; 2906c3fb27SDimitry Andric struct layout_right; 305f757f3fSDimitry Andric struct layout_stride; 3106c3fb27SDimitry Andric 3206c3fb27SDimitry Andric // [mdspan.accessor.default], class template default_accessor 3306c3fb27SDimitry Andric template<class ElementType> 3406c3fb27SDimitry Andric class default_accessor; 3506c3fb27SDimitry Andric 3606c3fb27SDimitry Andric // [mdspan.mdspan], class template mdspan 3706c3fb27SDimitry Andric template<class ElementType, class Extents, class LayoutPolicy = layout_right, 3806c3fb27SDimitry Andric class AccessorPolicy = default_accessor<ElementType>> 3906c3fb27SDimitry Andric class mdspan; // not implemented yet 4006c3fb27SDimitry Andric} 4106c3fb27SDimitry Andric 4206c3fb27SDimitry Andric// extents synopsis 4306c3fb27SDimitry Andric 4406c3fb27SDimitry Andricnamespace std { 4506c3fb27SDimitry Andric template<class _IndexType, size_t... _Extents> 4606c3fb27SDimitry Andric class extents { 4706c3fb27SDimitry Andric public: 4806c3fb27SDimitry Andric using index_type = _IndexType; 4906c3fb27SDimitry Andric using size_type = make_unsigned_t<index_type>; 5006c3fb27SDimitry Andric using rank_type = size_t; 5106c3fb27SDimitry Andric 5206c3fb27SDimitry Andric // [mdspan.extents.obs], observers of the multidimensional index space 5306c3fb27SDimitry Andric static constexpr rank_type rank() noexcept { return sizeof...(_Extents); } 5406c3fb27SDimitry Andric static constexpr rank_type rank_dynamic() noexcept { return dynamic-index(rank()); } 5506c3fb27SDimitry Andric static constexpr size_t static_extent(rank_type) noexcept; 5606c3fb27SDimitry Andric constexpr index_type extent(rank_type) const noexcept; 5706c3fb27SDimitry Andric 5806c3fb27SDimitry Andric // [mdspan.extents.cons], constructors 5906c3fb27SDimitry Andric constexpr extents() noexcept = default; 6006c3fb27SDimitry Andric 6106c3fb27SDimitry Andric template<class _OtherIndexType, size_t... _OtherExtents> 6206c3fb27SDimitry Andric constexpr explicit(see below) 6306c3fb27SDimitry Andric extents(const extents<_OtherIndexType, _OtherExtents...>&) noexcept; 6406c3fb27SDimitry Andric template<class... _OtherIndexTypes> 6506c3fb27SDimitry Andric constexpr explicit extents(_OtherIndexTypes...) noexcept; 6606c3fb27SDimitry Andric template<class _OtherIndexType, size_t N> 6706c3fb27SDimitry Andric constexpr explicit(N != rank_dynamic()) 6806c3fb27SDimitry Andric extents(span<_OtherIndexType, N>) noexcept; 6906c3fb27SDimitry Andric template<class _OtherIndexType, size_t N> 7006c3fb27SDimitry Andric constexpr explicit(N != rank_dynamic()) 7106c3fb27SDimitry Andric extents(const array<_OtherIndexType, N>&) noexcept; 7206c3fb27SDimitry Andric 7306c3fb27SDimitry Andric // [mdspan.extents.cmp], comparison operators 7406c3fb27SDimitry Andric template<class _OtherIndexType, size_t... _OtherExtents> 7506c3fb27SDimitry Andric friend constexpr bool operator==(const extents&, 7606c3fb27SDimitry Andric const extents<_OtherIndexType, _OtherExtents...>&) noexcept; 7706c3fb27SDimitry Andric 7806c3fb27SDimitry Andric private: 7906c3fb27SDimitry Andric // libcxx note: we do not use an array here, but we need to preserve the as-if behavior 8006c3fb27SDimitry Andric // for example the default constructor must zero initialize dynamic extents 8106c3fb27SDimitry Andric array<index_type, rank_dynamic()> dynamic-extents{}; // exposition only 8206c3fb27SDimitry Andric }; 8306c3fb27SDimitry Andric 8406c3fb27SDimitry Andric template<class... Integrals> 8506c3fb27SDimitry Andric explicit extents(Integrals...) 8606c3fb27SDimitry Andric -> see below; 8706c3fb27SDimitry Andric} 8806c3fb27SDimitry Andric 8906c3fb27SDimitry Andric// layout_left synopsis 9006c3fb27SDimitry Andric 9106c3fb27SDimitry Andricnamespace std { 9206c3fb27SDimitry Andric template<class Extents> 9306c3fb27SDimitry Andric class layout_left::mapping { 9406c3fb27SDimitry Andric public: 9506c3fb27SDimitry Andric using extents_type = Extents; 9606c3fb27SDimitry Andric using index_type = typename extents_type::index_type; 9706c3fb27SDimitry Andric using size_type = typename extents_type::size_type; 9806c3fb27SDimitry Andric using rank_type = typename extents_type::rank_type; 9906c3fb27SDimitry Andric using layout_type = layout_left; 10006c3fb27SDimitry Andric 10106c3fb27SDimitry Andric // [mdspan.layout.right.cons], constructors 10206c3fb27SDimitry Andric constexpr mapping() noexcept = default; 10306c3fb27SDimitry Andric constexpr mapping(const mapping&) noexcept = default; 10406c3fb27SDimitry Andric constexpr mapping(const extents_type&) noexcept; 10506c3fb27SDimitry Andric template<class OtherExtents> 10606c3fb27SDimitry Andric constexpr explicit(!is_convertible_v<OtherExtents, extents_type>) 10706c3fb27SDimitry Andric mapping(const mapping<OtherExtents>&) noexcept; 10806c3fb27SDimitry Andric template<class OtherExtents> 10906c3fb27SDimitry Andric constexpr explicit(!is_convertible_v<OtherExtents, extents_type>) 11006c3fb27SDimitry Andric mapping(const layout_right::mapping<OtherExtents>&) noexcept; 11106c3fb27SDimitry Andric template<class OtherExtents> 11206c3fb27SDimitry Andric constexpr explicit(extents_type::rank() > 0) 11306c3fb27SDimitry Andric mapping(const layout_stride::mapping<OtherExtents>&) noexcept; 11406c3fb27SDimitry Andric 11506c3fb27SDimitry Andric constexpr mapping& operator=(const mapping&) noexcept = default; 11606c3fb27SDimitry Andric 11706c3fb27SDimitry Andric // [mdspan.layout.right.obs], observers 11806c3fb27SDimitry Andric constexpr const extents_type& extents() const noexcept { return extents_; } 11906c3fb27SDimitry Andric 12006c3fb27SDimitry Andric constexpr index_type required_span_size() const noexcept; 12106c3fb27SDimitry Andric 12206c3fb27SDimitry Andric template<class... Indices> 12306c3fb27SDimitry Andric constexpr index_type operator()(Indices...) const noexcept; 12406c3fb27SDimitry Andric 12506c3fb27SDimitry Andric static constexpr bool is_always_unique() noexcept { return true; } 12606c3fb27SDimitry Andric static constexpr bool is_always_exhaustive() noexcept { return true; } 12706c3fb27SDimitry Andric static constexpr bool is_always_strided() noexcept { return true; } 12806c3fb27SDimitry Andric 12906c3fb27SDimitry Andric static constexpr bool is_unique() noexcept { return true; } 13006c3fb27SDimitry Andric static constexpr bool is_exhaustive() noexcept { return true; } 13106c3fb27SDimitry Andric static constexpr bool is_strided() noexcept { return true; } 13206c3fb27SDimitry Andric 13306c3fb27SDimitry Andric constexpr index_type stride(rank_type) const noexcept; 13406c3fb27SDimitry Andric 13506c3fb27SDimitry Andric template<class OtherExtents> 13606c3fb27SDimitry Andric friend constexpr bool operator==(const mapping&, const mapping<OtherExtents>&) noexcept; 13706c3fb27SDimitry Andric 13806c3fb27SDimitry Andric private: 13906c3fb27SDimitry Andric extents_type extents_{}; // exposition only 14006c3fb27SDimitry Andric }; 14106c3fb27SDimitry Andric} 14206c3fb27SDimitry Andric 14306c3fb27SDimitry Andric// layout_right synopsis 14406c3fb27SDimitry Andric 14506c3fb27SDimitry Andricnamespace std { 14606c3fb27SDimitry Andric template<class Extents> 14706c3fb27SDimitry Andric class layout_right::mapping { 14806c3fb27SDimitry Andric public: 14906c3fb27SDimitry Andric using extents_type = Extents; 15006c3fb27SDimitry Andric using index_type = typename extents_type::index_type; 15106c3fb27SDimitry Andric using size_type = typename extents_type::size_type; 15206c3fb27SDimitry Andric using rank_type = typename extents_type::rank_type; 15306c3fb27SDimitry Andric using layout_type = layout_right; 15406c3fb27SDimitry Andric 15506c3fb27SDimitry Andric // [mdspan.layout.right.cons], constructors 15606c3fb27SDimitry Andric constexpr mapping() noexcept = default; 15706c3fb27SDimitry Andric constexpr mapping(const mapping&) noexcept = default; 15806c3fb27SDimitry Andric constexpr mapping(const extents_type&) noexcept; 15906c3fb27SDimitry Andric template<class OtherExtents> 16006c3fb27SDimitry Andric constexpr explicit(!is_convertible_v<OtherExtents, extents_type>) 16106c3fb27SDimitry Andric mapping(const mapping<OtherExtents>&) noexcept; 16206c3fb27SDimitry Andric template<class OtherExtents> 16306c3fb27SDimitry Andric constexpr explicit(!is_convertible_v<OtherExtents, extents_type>) 16406c3fb27SDimitry Andric mapping(const layout_left::mapping<OtherExtents>&) noexcept; 16506c3fb27SDimitry Andric template<class OtherExtents> 16606c3fb27SDimitry Andric constexpr explicit(extents_type::rank() > 0) 16706c3fb27SDimitry Andric mapping(const layout_stride::mapping<OtherExtents>&) noexcept; 16806c3fb27SDimitry Andric 16906c3fb27SDimitry Andric constexpr mapping& operator=(const mapping&) noexcept = default; 17006c3fb27SDimitry Andric 17106c3fb27SDimitry Andric // [mdspan.layout.right.obs], observers 17206c3fb27SDimitry Andric constexpr const extents_type& extents() const noexcept { return extents_; } 17306c3fb27SDimitry Andric 17406c3fb27SDimitry Andric constexpr index_type required_span_size() const noexcept; 17506c3fb27SDimitry Andric 17606c3fb27SDimitry Andric template<class... Indices> 17706c3fb27SDimitry Andric constexpr index_type operator()(Indices...) const noexcept; 17806c3fb27SDimitry Andric 17906c3fb27SDimitry Andric static constexpr bool is_always_unique() noexcept { return true; } 18006c3fb27SDimitry Andric static constexpr bool is_always_exhaustive() noexcept { return true; } 18106c3fb27SDimitry Andric static constexpr bool is_always_strided() noexcept { return true; } 18206c3fb27SDimitry Andric 18306c3fb27SDimitry Andric static constexpr bool is_unique() noexcept { return true; } 18406c3fb27SDimitry Andric static constexpr bool is_exhaustive() noexcept { return true; } 18506c3fb27SDimitry Andric static constexpr bool is_strided() noexcept { return true; } 18606c3fb27SDimitry Andric 18706c3fb27SDimitry Andric constexpr index_type stride(rank_type) const noexcept; 18806c3fb27SDimitry Andric 18906c3fb27SDimitry Andric template<class OtherExtents> 19006c3fb27SDimitry Andric friend constexpr bool operator==(const mapping&, const mapping<OtherExtents>&) noexcept; 19106c3fb27SDimitry Andric 19206c3fb27SDimitry Andric private: 19306c3fb27SDimitry Andric extents_type extents_{}; // exposition only 19406c3fb27SDimitry Andric }; 19506c3fb27SDimitry Andric} 19606c3fb27SDimitry Andric 1975f757f3fSDimitry Andric// layout_stride synopsis 1985f757f3fSDimitry Andric 1995f757f3fSDimitry Andricnamespace std { 2005f757f3fSDimitry Andric template<class Extents> 2015f757f3fSDimitry Andric class layout_stride::mapping { 2025f757f3fSDimitry Andric public: 2035f757f3fSDimitry Andric using extents_type = Extents; 2045f757f3fSDimitry Andric using index_type = typename extents_type::index_type; 2055f757f3fSDimitry Andric using size_type = typename extents_type::size_type; 2065f757f3fSDimitry Andric using rank_type = typename extents_type::rank_type; 2075f757f3fSDimitry Andric using layout_type = layout_stride; 2085f757f3fSDimitry Andric 2095f757f3fSDimitry Andric private: 2105f757f3fSDimitry Andric static constexpr rank_type rank_ = extents_type::rank(); // exposition only 2115f757f3fSDimitry Andric 2125f757f3fSDimitry Andric public: 2135f757f3fSDimitry Andric // [mdspan.layout.stride.cons], constructors 2145f757f3fSDimitry Andric constexpr mapping() noexcept; 2155f757f3fSDimitry Andric constexpr mapping(const mapping&) noexcept = default; 2165f757f3fSDimitry Andric template<class OtherIndexType> 2175f757f3fSDimitry Andric constexpr mapping(const extents_type&, span<OtherIndexType, rank_>) noexcept; 2185f757f3fSDimitry Andric template<class OtherIndexType> 2195f757f3fSDimitry Andric constexpr mapping(const extents_type&, const array<OtherIndexType, rank_>&) noexcept; 2205f757f3fSDimitry Andric 2215f757f3fSDimitry Andric template<class StridedLayoutMapping> 2225f757f3fSDimitry Andric constexpr explicit(see below) mapping(const StridedLayoutMapping&) noexcept; 2235f757f3fSDimitry Andric 2245f757f3fSDimitry Andric constexpr mapping& operator=(const mapping&) noexcept = default; 2255f757f3fSDimitry Andric 2265f757f3fSDimitry Andric // [mdspan.layout.stride.obs], observers 2275f757f3fSDimitry Andric constexpr const extents_type& extents() const noexcept { return extents_; } 2285f757f3fSDimitry Andric constexpr array<index_type, rank_> strides() const noexcept { return strides_; } 2295f757f3fSDimitry Andric 2305f757f3fSDimitry Andric constexpr index_type required_span_size() const noexcept; 2315f757f3fSDimitry Andric 2325f757f3fSDimitry Andric template<class... Indices> 2335f757f3fSDimitry Andric constexpr index_type operator()(Indices...) const noexcept; 2345f757f3fSDimitry Andric 2355f757f3fSDimitry Andric static constexpr bool is_always_unique() noexcept { return true; } 2365f757f3fSDimitry Andric static constexpr bool is_always_exhaustive() noexcept { return false; } 2375f757f3fSDimitry Andric static constexpr bool is_always_strided() noexcept { return true; } 2385f757f3fSDimitry Andric 2395f757f3fSDimitry Andric static constexpr bool is_unique() noexcept { return true; } 2405f757f3fSDimitry Andric constexpr bool is_exhaustive() const noexcept; 2415f757f3fSDimitry Andric static constexpr bool is_strided() noexcept { return true; } 2425f757f3fSDimitry Andric 2435f757f3fSDimitry Andric constexpr index_type stride(rank_type i) const noexcept { return strides_[i]; } 2445f757f3fSDimitry Andric 2455f757f3fSDimitry Andric template<class OtherMapping> 2465f757f3fSDimitry Andric friend constexpr bool operator==(const mapping&, const OtherMapping&) noexcept; 2475f757f3fSDimitry Andric 2485f757f3fSDimitry Andric private: 2495f757f3fSDimitry Andric extents_type extents_{}; // exposition only 2505f757f3fSDimitry Andric array<index_type, rank_> strides_{}; // exposition only 2515f757f3fSDimitry Andric }; 2525f757f3fSDimitry Andric} 2535f757f3fSDimitry Andric 25406c3fb27SDimitry Andric// default_accessor synopsis 25506c3fb27SDimitry Andric 25606c3fb27SDimitry Andricnamespace std { 25706c3fb27SDimitry Andric template<class ElementType> 25806c3fb27SDimitry Andric struct default_accessor { 25906c3fb27SDimitry Andric using offset_policy = default_accessor; 26006c3fb27SDimitry Andric using element_type = ElementType; 26106c3fb27SDimitry Andric using reference = ElementType&; 26206c3fb27SDimitry Andric using data_handle_type = ElementType*; 26306c3fb27SDimitry Andric 26406c3fb27SDimitry Andric constexpr default_accessor() noexcept = default; 26506c3fb27SDimitry Andric template<class OtherElementType> 26606c3fb27SDimitry Andric constexpr default_accessor(default_accessor<OtherElementType>) noexcept; 26706c3fb27SDimitry Andric constexpr reference access(data_handle_type p, size_t i) const noexcept; 26806c3fb27SDimitry Andric constexpr data_handle_type offset(data_handle_type p, size_t i) const noexcept; 26906c3fb27SDimitry Andric }; 27006c3fb27SDimitry Andric} 27106c3fb27SDimitry Andric 2728a4dda33SDimitry Andric// mdspan synopsis 2738a4dda33SDimitry Andric 2748a4dda33SDimitry Andricnamespace std { 2758a4dda33SDimitry Andric template<class ElementType, class Extents, class LayoutPolicy = layout_right, 2768a4dda33SDimitry Andric class AccessorPolicy = default_accessor<ElementType>> 2778a4dda33SDimitry Andric class mdspan { 2788a4dda33SDimitry Andric public: 2798a4dda33SDimitry Andric using extents_type = Extents; 2808a4dda33SDimitry Andric using layout_type = LayoutPolicy; 2818a4dda33SDimitry Andric using accessor_type = AccessorPolicy; 2828a4dda33SDimitry Andric using mapping_type = typename layout_type::template mapping<extents_type>; 2838a4dda33SDimitry Andric using element_type = ElementType; 2848a4dda33SDimitry Andric using value_type = remove_cv_t<element_type>; 2858a4dda33SDimitry Andric using index_type = typename extents_type::index_type; 2868a4dda33SDimitry Andric using size_type = typename extents_type::size_type; 2878a4dda33SDimitry Andric using rank_type = typename extents_type::rank_type; 2888a4dda33SDimitry Andric using data_handle_type = typename accessor_type::data_handle_type; 2898a4dda33SDimitry Andric using reference = typename accessor_type::reference; 2908a4dda33SDimitry Andric 2918a4dda33SDimitry Andric static constexpr rank_type rank() noexcept { return extents_type::rank(); } 2928a4dda33SDimitry Andric static constexpr rank_type rank_dynamic() noexcept { return extents_type::rank_dynamic(); } 2938a4dda33SDimitry Andric static constexpr size_t static_extent(rank_type r) noexcept 2948a4dda33SDimitry Andric { return extents_type::static_extent(r); } 2958a4dda33SDimitry Andric constexpr index_type extent(rank_type r) const noexcept { return extents().extent(r); } 2968a4dda33SDimitry Andric 2978a4dda33SDimitry Andric // [mdspan.mdspan.cons], constructors 2988a4dda33SDimitry Andric constexpr mdspan(); 2998a4dda33SDimitry Andric constexpr mdspan(const mdspan& rhs) = default; 3008a4dda33SDimitry Andric constexpr mdspan(mdspan&& rhs) = default; 3018a4dda33SDimitry Andric 3028a4dda33SDimitry Andric template<class... OtherIndexTypes> 3038a4dda33SDimitry Andric constexpr explicit mdspan(data_handle_type ptr, OtherIndexTypes... exts); 3048a4dda33SDimitry Andric template<class OtherIndexType, size_t N> 3058a4dda33SDimitry Andric constexpr explicit(N != rank_dynamic()) 3068a4dda33SDimitry Andric mdspan(data_handle_type p, span<OtherIndexType, N> exts); 3078a4dda33SDimitry Andric template<class OtherIndexType, size_t N> 3088a4dda33SDimitry Andric constexpr explicit(N != rank_dynamic()) 3098a4dda33SDimitry Andric mdspan(data_handle_type p, const array<OtherIndexType, N>& exts); 3108a4dda33SDimitry Andric constexpr mdspan(data_handle_type p, const extents_type& ext); 3118a4dda33SDimitry Andric constexpr mdspan(data_handle_type p, const mapping_type& m); 3128a4dda33SDimitry Andric constexpr mdspan(data_handle_type p, const mapping_type& m, const accessor_type& a); 3138a4dda33SDimitry Andric 3148a4dda33SDimitry Andric template<class OtherElementType, class OtherExtents, 3158a4dda33SDimitry Andric class OtherLayoutPolicy, class OtherAccessorPolicy> 3168a4dda33SDimitry Andric constexpr explicit(see below) 3178a4dda33SDimitry Andric mdspan(const mdspan<OtherElementType, OtherExtents, 3188a4dda33SDimitry Andric OtherLayoutPolicy, OtherAccessorPolicy>& other); 3198a4dda33SDimitry Andric 3208a4dda33SDimitry Andric constexpr mdspan& operator=(const mdspan& rhs) = default; 3218a4dda33SDimitry Andric constexpr mdspan& operator=(mdspan&& rhs) = default; 3228a4dda33SDimitry Andric 3238a4dda33SDimitry Andric // [mdspan.mdspan.members], members 3248a4dda33SDimitry Andric template<class... OtherIndexTypes> 3258a4dda33SDimitry Andric constexpr reference operator[](OtherIndexTypes... indices) const; 3268a4dda33SDimitry Andric template<class OtherIndexType> 3278a4dda33SDimitry Andric constexpr reference operator[](span<OtherIndexType, rank()> indices) const; 3288a4dda33SDimitry Andric template<class OtherIndexType> 3298a4dda33SDimitry Andric constexpr reference operator[](const array<OtherIndexType, rank()>& indices) const; 3308a4dda33SDimitry Andric 3318a4dda33SDimitry Andric constexpr size_type size() const noexcept; 3328a4dda33SDimitry Andric [[nodiscard]] constexpr bool empty() const noexcept; 3338a4dda33SDimitry Andric 3348a4dda33SDimitry Andric friend constexpr void swap(mdspan& x, mdspan& y) noexcept; 3358a4dda33SDimitry Andric 3368a4dda33SDimitry Andric constexpr const extents_type& extents() const noexcept { return map_.extents(); } 3378a4dda33SDimitry Andric constexpr const data_handle_type& data_handle() const noexcept { return ptr_; } 3388a4dda33SDimitry Andric constexpr const mapping_type& mapping() const noexcept { return map_; } 3398a4dda33SDimitry Andric constexpr const accessor_type& accessor() const noexcept { return acc_; } 3408a4dda33SDimitry Andric 3415f757f3fSDimitry Andric // per LWG-4021 "mdspan::is_always_meow() should be noexcept" 3425f757f3fSDimitry Andric static constexpr bool is_always_unique() noexcept 3438a4dda33SDimitry Andric { return mapping_type::is_always_unique(); } 3445f757f3fSDimitry Andric static constexpr bool is_always_exhaustive() noexcept 3458a4dda33SDimitry Andric { return mapping_type::is_always_exhaustive(); } 3465f757f3fSDimitry Andric static constexpr bool is_always_strided() noexcept 3478a4dda33SDimitry Andric { return mapping_type::is_always_strided(); } 3488a4dda33SDimitry Andric 3498a4dda33SDimitry Andric constexpr bool is_unique() const 3508a4dda33SDimitry Andric { return map_.is_unique(); } 3518a4dda33SDimitry Andric constexpr bool is_exhaustive() const 3528a4dda33SDimitry Andric { return map_.is_exhaustive(); } 3538a4dda33SDimitry Andric constexpr bool is_strided() const 3548a4dda33SDimitry Andric { return map_.is_strided(); } 3558a4dda33SDimitry Andric constexpr index_type stride(rank_type r) const 3568a4dda33SDimitry Andric { return map_.stride(r); } 3578a4dda33SDimitry Andric 3588a4dda33SDimitry Andric private: 3598a4dda33SDimitry Andric accessor_type acc_; // exposition only 3608a4dda33SDimitry Andric mapping_type map_; // exposition only 3618a4dda33SDimitry Andric data_handle_type ptr_; // exposition only 3628a4dda33SDimitry Andric }; 3638a4dda33SDimitry Andric 3648a4dda33SDimitry Andric template<class CArray> 3658a4dda33SDimitry Andric requires(is_array_v<CArray> && rank_v<CArray> == 1) 3668a4dda33SDimitry Andric mdspan(CArray&) 3678a4dda33SDimitry Andric -> mdspan<remove_all_extents_t<CArray>, extents<size_t, extent_v<CArray, 0>>>; 3688a4dda33SDimitry Andric 3698a4dda33SDimitry Andric template<class Pointer> 3708a4dda33SDimitry Andric requires(is_pointer_v<remove_reference_t<Pointer>>) 3718a4dda33SDimitry Andric mdspan(Pointer&&) 3728a4dda33SDimitry Andric -> mdspan<remove_pointer_t<remove_reference_t<Pointer>>, extents<size_t>>; 3738a4dda33SDimitry Andric 3748a4dda33SDimitry Andric template<class ElementType, class... Integrals> 3758a4dda33SDimitry Andric requires((is_convertible_v<Integrals, size_t> && ...) && sizeof...(Integrals) > 0) 3768a4dda33SDimitry Andric explicit mdspan(ElementType*, Integrals...) 377*0fca6ea1SDimitry Andric -> mdspan<ElementType, dextents<size_t, sizeof...(Integrals)>>; // until C++26 378*0fca6ea1SDimitry Andric template<class ElementType, class... Integrals> 379*0fca6ea1SDimitry Andric requires((is_convertible_v<Integrals, size_t> && ...) && sizeof...(Integrals) > 0) 380*0fca6ea1SDimitry Andric explicit mdspan(ElementType*, Integrals...) 381*0fca6ea1SDimitry Andric -> mdspan<ElementType, extents<size_t, maybe-static-ext<Integrals>...>>; // since C++26 3828a4dda33SDimitry Andric 3838a4dda33SDimitry Andric template<class ElementType, class OtherIndexType, size_t N> 3848a4dda33SDimitry Andric mdspan(ElementType*, span<OtherIndexType, N>) 3858a4dda33SDimitry Andric -> mdspan<ElementType, dextents<size_t, N>>; 3868a4dda33SDimitry Andric 3878a4dda33SDimitry Andric template<class ElementType, class OtherIndexType, size_t N> 3888a4dda33SDimitry Andric mdspan(ElementType*, const array<OtherIndexType, N>&) 3898a4dda33SDimitry Andric -> mdspan<ElementType, dextents<size_t, N>>; 3908a4dda33SDimitry Andric 3918a4dda33SDimitry Andric template<class ElementType, class IndexType, size_t... ExtentsPack> 3928a4dda33SDimitry Andric mdspan(ElementType*, const extents<IndexType, ExtentsPack...>&) 3938a4dda33SDimitry Andric -> mdspan<ElementType, extents<IndexType, ExtentsPack...>>; 3948a4dda33SDimitry Andric 3958a4dda33SDimitry Andric template<class ElementType, class MappingType> 3968a4dda33SDimitry Andric mdspan(ElementType*, const MappingType&) 3978a4dda33SDimitry Andric -> mdspan<ElementType, typename MappingType::extents_type, 3988a4dda33SDimitry Andric typename MappingType::layout_type>; 3998a4dda33SDimitry Andric 4008a4dda33SDimitry Andric template<class MappingType, class AccessorType> 4018a4dda33SDimitry Andric mdspan(const typename AccessorType::data_handle_type&, const MappingType&, 4028a4dda33SDimitry Andric const AccessorType&) 4038a4dda33SDimitry Andric -> mdspan<typename AccessorType::element_type, typename MappingType::extents_type, 4048a4dda33SDimitry Andric typename MappingType::layout_type, AccessorType>; 4058a4dda33SDimitry Andric} 40606c3fb27SDimitry Andric*/ 40706c3fb27SDimitry Andric 40806c3fb27SDimitry Andric#ifndef _LIBCPP_MDSPAN 40906c3fb27SDimitry Andric#define _LIBCPP_MDSPAN 41006c3fb27SDimitry Andric 41106c3fb27SDimitry Andric#include <__config> 412*0fca6ea1SDimitry Andric 413*0fca6ea1SDimitry Andric#if _LIBCPP_STD_VER >= 23 41406c3fb27SDimitry Andric# include <__fwd/mdspan.h> 41506c3fb27SDimitry Andric# include <__mdspan/default_accessor.h> 41606c3fb27SDimitry Andric# include <__mdspan/extents.h> 41706c3fb27SDimitry Andric# include <__mdspan/layout_left.h> 41806c3fb27SDimitry Andric# include <__mdspan/layout_right.h> 4195f757f3fSDimitry Andric# include <__mdspan/layout_stride.h> 4208a4dda33SDimitry Andric# include <__mdspan/mdspan.h> 421*0fca6ea1SDimitry Andric#endif 422*0fca6ea1SDimitry Andric 4235f757f3fSDimitry Andric#include <version> 42406c3fb27SDimitry Andric 42506c3fb27SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 42606c3fb27SDimitry Andric# pragma GCC system_header 42706c3fb27SDimitry Andric#endif 42806c3fb27SDimitry Andric 429*0fca6ea1SDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 430*0fca6ea1SDimitry Andric# include <array> 431*0fca6ea1SDimitry Andric# include <cinttypes> 432*0fca6ea1SDimitry Andric# include <concepts> 433*0fca6ea1SDimitry Andric# include <cstddef> 434*0fca6ea1SDimitry Andric# include <limits> 435*0fca6ea1SDimitry Andric# include <span> 436*0fca6ea1SDimitry Andric#endif 437*0fca6ea1SDimitry Andric 43806c3fb27SDimitry Andric#endif // _LIBCPP_MDSPAN 439