18a4dda33SDimitry Andric // -*- C++ -*- 28a4dda33SDimitry Andric //===----------------------------------------------------------------------===// 38a4dda33SDimitry Andric // 48a4dda33SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 58a4dda33SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 68a4dda33SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 78a4dda33SDimitry Andric // 88a4dda33SDimitry Andric // Kokkos v. 4.0 98a4dda33SDimitry Andric // Copyright (2022) National Technology & Engineering 108a4dda33SDimitry Andric // Solutions of Sandia, LLC (NTESS). 118a4dda33SDimitry Andric // 128a4dda33SDimitry Andric // Under the terms of Contract DE-NA0003525 with NTESS, 138a4dda33SDimitry Andric // the U.S. Government retains certain rights in this software. 148a4dda33SDimitry Andric // 158a4dda33SDimitry Andric //===---------------------------------------------------------------------===// 168a4dda33SDimitry Andric 178a4dda33SDimitry Andric #ifndef _LIBCPP___MDSPAN_MDSPAN_H 188a4dda33SDimitry Andric #define _LIBCPP___MDSPAN_MDSPAN_H 198a4dda33SDimitry Andric 208a4dda33SDimitry Andric #include <__assert> 218a4dda33SDimitry Andric #include <__config> 228a4dda33SDimitry Andric #include <__fwd/mdspan.h> 238a4dda33SDimitry Andric #include <__mdspan/default_accessor.h> 248a4dda33SDimitry Andric #include <__mdspan/extents.h> 258a4dda33SDimitry Andric #include <__type_traits/extent.h> 268a4dda33SDimitry Andric #include <__type_traits/is_abstract.h> 278a4dda33SDimitry Andric #include <__type_traits/is_array.h> 288a4dda33SDimitry Andric #include <__type_traits/is_constructible.h> 298a4dda33SDimitry Andric #include <__type_traits/is_convertible.h> 308a4dda33SDimitry Andric #include <__type_traits/is_nothrow_constructible.h> 318a4dda33SDimitry Andric #include <__type_traits/is_pointer.h> 328a4dda33SDimitry Andric #include <__type_traits/is_same.h> 338a4dda33SDimitry Andric #include <__type_traits/rank.h> 348a4dda33SDimitry Andric #include <__type_traits/remove_all_extents.h> 358a4dda33SDimitry Andric #include <__type_traits/remove_cv.h> 368a4dda33SDimitry Andric #include <__type_traits/remove_pointer.h> 378a4dda33SDimitry Andric #include <__type_traits/remove_reference.h> 388a4dda33SDimitry Andric #include <__utility/integer_sequence.h> 398a4dda33SDimitry Andric #include <array> 408a4dda33SDimitry Andric #include <cinttypes> 418a4dda33SDimitry Andric #include <cstddef> 428a4dda33SDimitry Andric #include <limits> 438a4dda33SDimitry Andric #include <span> 448a4dda33SDimitry Andric 458a4dda33SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 468a4dda33SDimitry Andric # pragma GCC system_header 478a4dda33SDimitry Andric #endif 488a4dda33SDimitry Andric 498a4dda33SDimitry Andric _LIBCPP_PUSH_MACROS 508a4dda33SDimitry Andric #include <__undef_macros> 518a4dda33SDimitry Andric 528a4dda33SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 538a4dda33SDimitry Andric 548a4dda33SDimitry Andric #if _LIBCPP_STD_VER >= 23 558a4dda33SDimitry Andric 568a4dda33SDimitry Andric // Helper for lightweight test checking that one did pass a layout policy as LayoutPolicy template argument 578a4dda33SDimitry Andric namespace __mdspan_detail { 588a4dda33SDimitry Andric template <class _Layout, class _Extents> 598a4dda33SDimitry Andric concept __has_invalid_mapping = !requires { typename _Layout::template mapping<_Extents>; }; 608a4dda33SDimitry Andric } // namespace __mdspan_detail 618a4dda33SDimitry Andric 628a4dda33SDimitry Andric template <class _ElementType, 638a4dda33SDimitry Andric class _Extents, 648a4dda33SDimitry Andric class _LayoutPolicy = layout_right, 658a4dda33SDimitry Andric class _AccessorPolicy = default_accessor<_ElementType> > 668a4dda33SDimitry Andric class mdspan { 678a4dda33SDimitry Andric private: 688a4dda33SDimitry Andric static_assert(__mdspan_detail::__is_extents_v<_Extents>, 698a4dda33SDimitry Andric "mdspan: Extents template parameter must be a specialization of extents."); 708a4dda33SDimitry Andric static_assert(!is_array_v<_ElementType>, "mdspan: ElementType template parameter may not be an array type"); 718a4dda33SDimitry Andric static_assert(!is_abstract_v<_ElementType>, "mdspan: ElementType template parameter may not be an abstract class"); 728a4dda33SDimitry Andric static_assert(is_same_v<_ElementType, typename _AccessorPolicy::element_type>, 738a4dda33SDimitry Andric "mdspan: ElementType template parameter must match AccessorPolicy::element_type"); 748a4dda33SDimitry Andric static_assert(!__mdspan_detail::__has_invalid_mapping<_LayoutPolicy, _Extents>, 758a4dda33SDimitry Andric "mdspan: LayoutPolicy template parameter is invalid. A common mistake is to pass a layout mapping " 768a4dda33SDimitry Andric "instead of a layout policy"); 778a4dda33SDimitry Andric 788a4dda33SDimitry Andric public: 798a4dda33SDimitry Andric using extents_type = _Extents; 808a4dda33SDimitry Andric using layout_type = _LayoutPolicy; 818a4dda33SDimitry Andric using accessor_type = _AccessorPolicy; 828a4dda33SDimitry Andric using mapping_type = typename layout_type::template mapping<extents_type>; 838a4dda33SDimitry Andric using element_type = _ElementType; 848a4dda33SDimitry Andric using value_type = remove_cv_t<element_type>; 858a4dda33SDimitry Andric using index_type = typename extents_type::index_type; 868a4dda33SDimitry Andric using size_type = typename extents_type::size_type; 878a4dda33SDimitry Andric using rank_type = typename extents_type::rank_type; 888a4dda33SDimitry Andric using data_handle_type = typename accessor_type::data_handle_type; 898a4dda33SDimitry Andric using reference = typename accessor_type::reference; 908a4dda33SDimitry Andric 918a4dda33SDimitry Andric _LIBCPP_HIDE_FROM_ABI static constexpr rank_type rank() noexcept { return extents_type::rank(); } 928a4dda33SDimitry Andric _LIBCPP_HIDE_FROM_ABI static constexpr rank_type rank_dynamic() noexcept { return extents_type::rank_dynamic(); } 938a4dda33SDimitry Andric _LIBCPP_HIDE_FROM_ABI static constexpr size_t static_extent(rank_type __r) noexcept { 948a4dda33SDimitry Andric return extents_type::static_extent(__r); 958a4dda33SDimitry Andric } 968a4dda33SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr index_type extent(rank_type __r) const noexcept { 978a4dda33SDimitry Andric return __map_.extents().extent(__r); 988a4dda33SDimitry Andric }; 998a4dda33SDimitry Andric 1008a4dda33SDimitry Andric public: 1018a4dda33SDimitry Andric //-------------------------------------------------------------------------------- 1028a4dda33SDimitry Andric // [mdspan.mdspan.cons], mdspan constructors, assignment, and destructor 1038a4dda33SDimitry Andric 1048a4dda33SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr mdspan() 1058a4dda33SDimitry Andric requires((extents_type::rank_dynamic() > 0) && is_default_constructible_v<data_handle_type> && 1068a4dda33SDimitry Andric is_default_constructible_v<mapping_type> && is_default_constructible_v<accessor_type>) 1078a4dda33SDimitry Andric = default; 1088a4dda33SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr mdspan(const mdspan&) = default; 1098a4dda33SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr mdspan(mdspan&&) = default; 1108a4dda33SDimitry Andric 1118a4dda33SDimitry Andric template <class... _OtherIndexTypes> 1128a4dda33SDimitry Andric requires((is_convertible_v<_OtherIndexTypes, index_type> && ...) && 1138a4dda33SDimitry Andric (is_nothrow_constructible_v<index_type, _OtherIndexTypes> && ...) && 1148a4dda33SDimitry Andric ((sizeof...(_OtherIndexTypes) == rank()) || (sizeof...(_OtherIndexTypes) == rank_dynamic())) && 1158a4dda33SDimitry Andric is_constructible_v<mapping_type, extents_type> && is_default_constructible_v<accessor_type>) 1168a4dda33SDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit constexpr mdspan(data_handle_type __p, _OtherIndexTypes... __exts) 1178a4dda33SDimitry Andric : __ptr_(std::move(__p)), __map_(extents_type(static_cast<index_type>(std::move(__exts))...)), __acc_{} {} 1188a4dda33SDimitry Andric 1198a4dda33SDimitry Andric template <class _OtherIndexType, size_t _Size> 1208a4dda33SDimitry Andric requires(is_convertible_v<const _OtherIndexType&, index_type> && 1218a4dda33SDimitry Andric is_nothrow_constructible_v<index_type, const _OtherIndexType&> && 1228a4dda33SDimitry Andric ((_Size == rank()) || (_Size == rank_dynamic())) && is_constructible_v<mapping_type, extents_type> && 1238a4dda33SDimitry Andric is_default_constructible_v<accessor_type>) 1248a4dda33SDimitry Andric explicit(_Size != rank_dynamic()) 1258a4dda33SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr mdspan(data_handle_type __p, const array<_OtherIndexType, _Size>& __exts) 1268a4dda33SDimitry Andric : __ptr_(std::move(__p)), __map_(extents_type(__exts)), __acc_{} {} 1278a4dda33SDimitry Andric 1288a4dda33SDimitry Andric template <class _OtherIndexType, size_t _Size> 1298a4dda33SDimitry Andric requires(is_convertible_v<const _OtherIndexType&, index_type> && 1308a4dda33SDimitry Andric is_nothrow_constructible_v<index_type, const _OtherIndexType&> && 1318a4dda33SDimitry Andric ((_Size == rank()) || (_Size == rank_dynamic())) && is_constructible_v<mapping_type, extents_type> && 1328a4dda33SDimitry Andric is_default_constructible_v<accessor_type>) 1338a4dda33SDimitry Andric explicit(_Size != rank_dynamic()) 1348a4dda33SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr mdspan(data_handle_type __p, span<_OtherIndexType, _Size> __exts) 1358a4dda33SDimitry Andric : __ptr_(std::move(__p)), __map_(extents_type(__exts)), __acc_{} {} 1368a4dda33SDimitry Andric 1378a4dda33SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr mdspan(data_handle_type __p, const extents_type& __exts) 1388a4dda33SDimitry Andric requires(is_default_constructible_v<accessor_type> && is_constructible_v<mapping_type, const extents_type&>) 1398a4dda33SDimitry Andric : __ptr_(std::move(__p)), __map_(__exts), __acc_{} {} 1408a4dda33SDimitry Andric 1418a4dda33SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr mdspan(data_handle_type __p, const mapping_type& __m) 1428a4dda33SDimitry Andric requires(is_default_constructible_v<accessor_type>) 1438a4dda33SDimitry Andric : __ptr_(std::move(__p)), __map_(__m), __acc_{} {} 1448a4dda33SDimitry Andric 1458a4dda33SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr mdspan(data_handle_type __p, const mapping_type& __m, const accessor_type& __a) 1468a4dda33SDimitry Andric : __ptr_(std::move(__p)), __map_(__m), __acc_(__a) {} 1478a4dda33SDimitry Andric 1488a4dda33SDimitry Andric template <class _OtherElementType, class _OtherExtents, class _OtherLayoutPolicy, class _OtherAccessor> 1498a4dda33SDimitry Andric requires(is_constructible_v<mapping_type, const typename _OtherLayoutPolicy::template mapping<_OtherExtents>&> && 1508a4dda33SDimitry Andric is_constructible_v<accessor_type, const _OtherAccessor&>) 1518a4dda33SDimitry Andric explicit(!is_convertible_v<const typename _OtherLayoutPolicy::template mapping<_OtherExtents>&, mapping_type> || 1528a4dda33SDimitry Andric !is_convertible_v<const _OtherAccessor&, accessor_type>) 1538a4dda33SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr mdspan( 1548a4dda33SDimitry Andric const mdspan<_OtherElementType, _OtherExtents, _OtherLayoutPolicy, _OtherAccessor>& __other) 1558a4dda33SDimitry Andric : __ptr_(__other.__ptr_), __map_(__other.__map_), __acc_(__other.__acc_) { 1568a4dda33SDimitry Andric static_assert(is_constructible_v<data_handle_type, const typename _OtherAccessor::data_handle_type&>, 1578a4dda33SDimitry Andric "mdspan: incompatible data_handle_type for mdspan construction"); 1588a4dda33SDimitry Andric static_assert( 1598a4dda33SDimitry Andric is_constructible_v<extents_type, _OtherExtents>, "mdspan: incompatible extents for mdspan construction"); 1608a4dda33SDimitry Andric 1618a4dda33SDimitry Andric // The following precondition is part of the standard, but is unlikely to be triggered. 1628a4dda33SDimitry Andric // The extents constructor checks this and the mapping must be storing the extents, since 1638a4dda33SDimitry Andric // its extents() function returns a const reference to extents_type. 1648a4dda33SDimitry Andric // The only way this can be triggered is if the mapping conversion constructor would for example 1658a4dda33SDimitry Andric // always construct its extents() only from the dynamic extents, instead of from the other extents. 1668a4dda33SDimitry Andric if constexpr (rank() > 0) { 1678a4dda33SDimitry Andric for (size_t __r = 0; __r < rank(); __r++) { 1688a4dda33SDimitry Andric // Not catching this could lead to out of bounds errors later 1698a4dda33SDimitry Andric // e.g. mdspan<int, dextents<char,1>, non_checking_layout> m = 1708a4dda33SDimitry Andric // mdspan<int, dextents<unsigned, 1>, non_checking_layout>(ptr, 200); leads to an extent of -56 on m 1718a4dda33SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 1728a4dda33SDimitry Andric (static_extent(__r) == dynamic_extent) || 1738a4dda33SDimitry Andric (static_cast<index_type>(__other.extent(__r)) == static_cast<index_type>(static_extent(__r))), 1748a4dda33SDimitry Andric "mdspan: conversion mismatch of source dynamic extents with static extents"); 1758a4dda33SDimitry Andric } 1768a4dda33SDimitry Andric } 1778a4dda33SDimitry Andric } 1788a4dda33SDimitry Andric 1798a4dda33SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr mdspan& operator=(const mdspan&) = default; 1808a4dda33SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr mdspan& operator=(mdspan&&) = default; 1818a4dda33SDimitry Andric 1828a4dda33SDimitry Andric //-------------------------------------------------------------------------------- 1838a4dda33SDimitry Andric // [mdspan.mdspan.members], members 1848a4dda33SDimitry Andric 1858a4dda33SDimitry Andric template <class... _OtherIndexTypes> 1868a4dda33SDimitry Andric requires((is_convertible_v<_OtherIndexTypes, index_type> && ...) && 1878a4dda33SDimitry Andric (is_nothrow_constructible_v<index_type, _OtherIndexTypes> && ...) && 1888a4dda33SDimitry Andric (sizeof...(_OtherIndexTypes) == rank())) 1898a4dda33SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](_OtherIndexTypes... __indices) const { 1908a4dda33SDimitry Andric // Note the standard layouts would also check this, but user provided ones may not, so we 1918a4dda33SDimitry Andric // check the precondition here 1928a4dda33SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__mdspan_detail::__is_multidimensional_index_in(extents(), __indices...), 1938a4dda33SDimitry Andric "mdspan: operator[] out of bounds access"); 1948a4dda33SDimitry Andric return __acc_.access(__ptr_, __map_(static_cast<index_type>(std::move(__indices))...)); 1958a4dda33SDimitry Andric } 1968a4dda33SDimitry Andric 1978a4dda33SDimitry Andric template <class _OtherIndexType> 1988a4dda33SDimitry Andric requires(is_convertible_v<const _OtherIndexType&, index_type> && 1998a4dda33SDimitry Andric is_nothrow_constructible_v<index_type, const _OtherIndexType&>) 2008a4dda33SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](const array< _OtherIndexType, rank()>& __indices) const { 2018a4dda33SDimitry Andric return __acc_.access(__ptr_, [&]<size_t... _Idxs>(index_sequence<_Idxs...>) { 2028a4dda33SDimitry Andric return __map_(__indices[_Idxs]...); 2038a4dda33SDimitry Andric }(make_index_sequence<rank()>())); 2048a4dda33SDimitry Andric } 2058a4dda33SDimitry Andric 2068a4dda33SDimitry Andric template <class _OtherIndexType> 2078a4dda33SDimitry Andric requires(is_convertible_v<const _OtherIndexType&, index_type> && 2088a4dda33SDimitry Andric is_nothrow_constructible_v<index_type, const _OtherIndexType&>) 2098a4dda33SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](span<_OtherIndexType, rank()> __indices) const { 2108a4dda33SDimitry Andric return __acc_.access(__ptr_, [&]<size_t... _Idxs>(index_sequence<_Idxs...>) { 2118a4dda33SDimitry Andric return __map_(__indices[_Idxs]...); 2128a4dda33SDimitry Andric }(make_index_sequence<rank()>())); 2138a4dda33SDimitry Andric } 2148a4dda33SDimitry Andric 2158a4dda33SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr size_type size() const noexcept { 2168a4dda33SDimitry Andric // Could leave this as only checked in debug mode: semantically size() is never 2178a4dda33SDimitry Andric // guaranteed to be related to any accessible range 2188a4dda33SDimitry Andric _LIBCPP_ASSERT_UNCATEGORIZED( 2198a4dda33SDimitry Andric false == ([&]<size_t... _Idxs>(index_sequence<_Idxs...>) { 2208a4dda33SDimitry Andric size_type __prod = 1; 2218a4dda33SDimitry Andric return (__builtin_mul_overflow(__prod, extent(_Idxs), &__prod) || ... || false); 2228a4dda33SDimitry Andric }(make_index_sequence<rank()>())), 2238a4dda33SDimitry Andric "mdspan: size() is not representable as size_type"); 2248a4dda33SDimitry Andric return [&]<size_t... _Idxs>(index_sequence<_Idxs...>) { 2258a4dda33SDimitry Andric return ((static_cast<size_type>(__map_.extents().extent(_Idxs))) * ... * size_type(1)); 2268a4dda33SDimitry Andric }(make_index_sequence<rank()>()); 2278a4dda33SDimitry Andric } 2288a4dda33SDimitry Andric 2298a4dda33SDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const noexcept { 2308a4dda33SDimitry Andric return [&]<size_t... _Idxs>(index_sequence<_Idxs...>) { 2318a4dda33SDimitry Andric return (rank() > 0) && ((__map_.extents().extent(_Idxs) == index_type(0)) || ... || false); 2328a4dda33SDimitry Andric }(make_index_sequence<rank()>()); 2338a4dda33SDimitry Andric } 2348a4dda33SDimitry Andric 2358a4dda33SDimitry Andric _LIBCPP_HIDE_FROM_ABI friend constexpr void swap(mdspan& __x, mdspan& __y) noexcept { 2368a4dda33SDimitry Andric swap(__x.__ptr_, __y.__ptr_); 2378a4dda33SDimitry Andric swap(__x.__map_, __y.__map_); 2388a4dda33SDimitry Andric swap(__x.__acc_, __y.__acc_); 2398a4dda33SDimitry Andric } 2408a4dda33SDimitry Andric 2418a4dda33SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr const extents_type& extents() const noexcept { return __map_.extents(); }; 2428a4dda33SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr const data_handle_type& data_handle() const noexcept { return __ptr_; }; 2438a4dda33SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr const mapping_type& mapping() const noexcept { return __map_; }; 2448a4dda33SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr const accessor_type& accessor() const noexcept { return __acc_; }; 2458a4dda33SDimitry Andric 2465f757f3fSDimitry Andric // per LWG-4021 "mdspan::is_always_meow() should be noexcept" 2475f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_unique() noexcept { return mapping_type::is_always_unique(); }; 2485f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_exhaustive() noexcept { 2495f757f3fSDimitry Andric return mapping_type::is_always_exhaustive(); 2505f757f3fSDimitry Andric }; 2515f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_strided() noexcept { 2525f757f3fSDimitry Andric return mapping_type::is_always_strided(); 2535f757f3fSDimitry Andric }; 2548a4dda33SDimitry Andric 2558a4dda33SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr bool is_unique() const { return __map_.is_unique(); }; 2568a4dda33SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr bool is_exhaustive() const { return __map_.is_exhaustive(); }; 2578a4dda33SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr bool is_strided() const { return __map_.is_strided(); }; 2588a4dda33SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr index_type stride(rank_type __r) const { return __map_.stride(__r); }; 2598a4dda33SDimitry Andric 2608a4dda33SDimitry Andric private: 2618a4dda33SDimitry Andric _LIBCPP_NO_UNIQUE_ADDRESS data_handle_type __ptr_{}; 2628a4dda33SDimitry Andric _LIBCPP_NO_UNIQUE_ADDRESS mapping_type __map_{}; 2638a4dda33SDimitry Andric _LIBCPP_NO_UNIQUE_ADDRESS accessor_type __acc_{}; 2648a4dda33SDimitry Andric 2658a4dda33SDimitry Andric template <class, class, class, class> 2668a4dda33SDimitry Andric friend class mdspan; 2678a4dda33SDimitry Andric }; 2688a4dda33SDimitry Andric 269*0fca6ea1SDimitry Andric # if _LIBCPP_STD_VER >= 26 2708a4dda33SDimitry Andric template <class _ElementType, class... _OtherIndexTypes> 2718a4dda33SDimitry Andric requires((is_convertible_v<_OtherIndexTypes, size_t> && ...) && (sizeof...(_OtherIndexTypes) > 0)) 272*0fca6ea1SDimitry Andric explicit mdspan(_ElementType*, 273*0fca6ea1SDimitry Andric _OtherIndexTypes...) -> mdspan<_ElementType, extents<size_t, __maybe_static_ext<_OtherIndexTypes>...>>; 274*0fca6ea1SDimitry Andric # else 275*0fca6ea1SDimitry Andric template <class _ElementType, class... _OtherIndexTypes> 276*0fca6ea1SDimitry Andric requires((is_convertible_v<_OtherIndexTypes, size_t> && ...) && (sizeof...(_OtherIndexTypes) > 0)) 277*0fca6ea1SDimitry Andric explicit mdspan(_ElementType*, 278*0fca6ea1SDimitry Andric _OtherIndexTypes...) -> mdspan<_ElementType, dextents<size_t, sizeof...(_OtherIndexTypes)>>; 279*0fca6ea1SDimitry Andric # endif 2808a4dda33SDimitry Andric 2818a4dda33SDimitry Andric template <class _Pointer> 2828a4dda33SDimitry Andric requires(is_pointer_v<remove_reference_t<_Pointer>>) 2838a4dda33SDimitry Andric mdspan(_Pointer&&) -> mdspan<remove_pointer_t<remove_reference_t<_Pointer>>, extents<size_t>>; 2848a4dda33SDimitry Andric 2858a4dda33SDimitry Andric template <class _CArray> 2868a4dda33SDimitry Andric requires(is_array_v<_CArray> && (rank_v<_CArray> == 1)) 2878a4dda33SDimitry Andric mdspan(_CArray&) -> mdspan<remove_all_extents_t<_CArray>, extents<size_t, extent_v<_CArray, 0>>>; 2888a4dda33SDimitry Andric 2898a4dda33SDimitry Andric template <class _ElementType, class _OtherIndexType, size_t _Size> 2908a4dda33SDimitry Andric mdspan(_ElementType*, const array<_OtherIndexType, _Size>&) -> mdspan<_ElementType, dextents<size_t, _Size>>; 2918a4dda33SDimitry Andric 2928a4dda33SDimitry Andric template <class _ElementType, class _OtherIndexType, size_t _Size> 2938a4dda33SDimitry Andric mdspan(_ElementType*, span<_OtherIndexType, _Size>) -> mdspan<_ElementType, dextents<size_t, _Size>>; 2948a4dda33SDimitry Andric 2958a4dda33SDimitry Andric // This one is necessary because all the constructors take `data_handle_type`s, not 2968a4dda33SDimitry Andric // `_ElementType*`s, and `data_handle_type` is taken from `accessor_type::data_handle_type`, which 2978a4dda33SDimitry Andric // seems to throw off automatic deduction guides. 2988a4dda33SDimitry Andric template <class _ElementType, class _OtherIndexType, size_t... _ExtentsPack> 2998a4dda33SDimitry Andric mdspan(_ElementType*, const extents<_OtherIndexType, _ExtentsPack...>&) 3008a4dda33SDimitry Andric -> mdspan<_ElementType, extents<_OtherIndexType, _ExtentsPack...>>; 3018a4dda33SDimitry Andric 3028a4dda33SDimitry Andric template <class _ElementType, class _MappingType> 3038a4dda33SDimitry Andric mdspan(_ElementType*, const _MappingType&) 3048a4dda33SDimitry Andric -> mdspan<_ElementType, typename _MappingType::extents_type, typename _MappingType::layout_type>; 3058a4dda33SDimitry Andric 3068a4dda33SDimitry Andric template <class _MappingType, class _AccessorType> 3078a4dda33SDimitry Andric mdspan(const typename _AccessorType::data_handle_type, const _MappingType&, const _AccessorType&) 3088a4dda33SDimitry Andric -> mdspan<typename _AccessorType::element_type, 3098a4dda33SDimitry Andric typename _MappingType::extents_type, 3108a4dda33SDimitry Andric typename _MappingType::layout_type, 3118a4dda33SDimitry Andric _AccessorType>; 3128a4dda33SDimitry Andric 3138a4dda33SDimitry Andric #endif // _LIBCPP_STD_VER >= 23 3148a4dda33SDimitry Andric 3158a4dda33SDimitry Andric _LIBCPP_END_NAMESPACE_STD 3168a4dda33SDimitry Andric 3178a4dda33SDimitry Andric _LIBCPP_POP_MACROS 3188a4dda33SDimitry Andric 3198a4dda33SDimitry Andric #endif // _LIBCPP___MDSPAN_MDSPAN_H 320