1*06c3fb27SDimitry Andric// -*-C++ - *- 2*06c3fb27SDimitry Andric//===----------------------------------------------------------------------===// 3*06c3fb27SDimitry Andric// 4*06c3fb27SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5*06c3fb27SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 6*06c3fb27SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7*06c3fb27SDimitry Andric// 8*06c3fb27SDimitry Andric//===---------------------------------------------------------------------===// 9*06c3fb27SDimitry Andric 10*06c3fb27SDimitry Andric/* 11*06c3fb27SDimitry Andric 12*06c3fb27SDimitry Andric// Overall mdspan synopsis 13*06c3fb27SDimitry Andric 14*06c3fb27SDimitry Andricnamespace std { 15*06c3fb27SDimitry Andric // [mdspan.extents], class template extents 16*06c3fb27SDimitry Andric template<class IndexType, size_t... Extents> 17*06c3fb27SDimitry Andric class extents; 18*06c3fb27SDimitry Andric 19*06c3fb27SDimitry Andric // [mdspan.extents.dextents], alias template dextents 20*06c3fb27SDimitry Andric template<class IndexType, size_t Rank> 21*06c3fb27SDimitry Andric using dextents = see below; 22*06c3fb27SDimitry Andric 23*06c3fb27SDimitry Andric // [mdspan.layout], layout mapping 24*06c3fb27SDimitry Andric struct layout_left; 25*06c3fb27SDimitry Andric struct layout_right; 26*06c3fb27SDimitry Andric struct layout_stride; // not implemented yet 27*06c3fb27SDimitry Andric 28*06c3fb27SDimitry Andric // [mdspan.accessor.default], class template default_accessor 29*06c3fb27SDimitry Andric template<class ElementType> 30*06c3fb27SDimitry Andric class default_accessor; 31*06c3fb27SDimitry Andric 32*06c3fb27SDimitry Andric // [mdspan.mdspan], class template mdspan 33*06c3fb27SDimitry Andric template<class ElementType, class Extents, class LayoutPolicy = layout_right, 34*06c3fb27SDimitry Andric class AccessorPolicy = default_accessor<ElementType>> 35*06c3fb27SDimitry Andric class mdspan; // not implemented yet 36*06c3fb27SDimitry Andric} 37*06c3fb27SDimitry Andric 38*06c3fb27SDimitry Andric// extents synopsis 39*06c3fb27SDimitry Andric 40*06c3fb27SDimitry Andricnamespace std { 41*06c3fb27SDimitry Andric template<class _IndexType, size_t... _Extents> 42*06c3fb27SDimitry Andric class extents { 43*06c3fb27SDimitry Andric public: 44*06c3fb27SDimitry Andric using index_type = _IndexType; 45*06c3fb27SDimitry Andric using size_type = make_unsigned_t<index_type>; 46*06c3fb27SDimitry Andric using rank_type = size_t; 47*06c3fb27SDimitry Andric 48*06c3fb27SDimitry Andric // [mdspan.extents.obs], observers of the multidimensional index space 49*06c3fb27SDimitry Andric static constexpr rank_type rank() noexcept { return sizeof...(_Extents); } 50*06c3fb27SDimitry Andric static constexpr rank_type rank_dynamic() noexcept { return dynamic-index(rank()); } 51*06c3fb27SDimitry Andric static constexpr size_t static_extent(rank_type) noexcept; 52*06c3fb27SDimitry Andric constexpr index_type extent(rank_type) const noexcept; 53*06c3fb27SDimitry Andric 54*06c3fb27SDimitry Andric // [mdspan.extents.cons], constructors 55*06c3fb27SDimitry Andric constexpr extents() noexcept = default; 56*06c3fb27SDimitry Andric 57*06c3fb27SDimitry Andric template<class _OtherIndexType, size_t... _OtherExtents> 58*06c3fb27SDimitry Andric constexpr explicit(see below) 59*06c3fb27SDimitry Andric extents(const extents<_OtherIndexType, _OtherExtents...>&) noexcept; 60*06c3fb27SDimitry Andric template<class... _OtherIndexTypes> 61*06c3fb27SDimitry Andric constexpr explicit extents(_OtherIndexTypes...) noexcept; 62*06c3fb27SDimitry Andric template<class _OtherIndexType, size_t N> 63*06c3fb27SDimitry Andric constexpr explicit(N != rank_dynamic()) 64*06c3fb27SDimitry Andric extents(span<_OtherIndexType, N>) noexcept; 65*06c3fb27SDimitry Andric template<class _OtherIndexType, size_t N> 66*06c3fb27SDimitry Andric constexpr explicit(N != rank_dynamic()) 67*06c3fb27SDimitry Andric extents(const array<_OtherIndexType, N>&) noexcept; 68*06c3fb27SDimitry Andric 69*06c3fb27SDimitry Andric // [mdspan.extents.cmp], comparison operators 70*06c3fb27SDimitry Andric template<class _OtherIndexType, size_t... _OtherExtents> 71*06c3fb27SDimitry Andric friend constexpr bool operator==(const extents&, 72*06c3fb27SDimitry Andric const extents<_OtherIndexType, _OtherExtents...>&) noexcept; 73*06c3fb27SDimitry Andric 74*06c3fb27SDimitry Andric private: 75*06c3fb27SDimitry Andric // libcxx note: we do not use an array here, but we need to preserve the as-if behavior 76*06c3fb27SDimitry Andric // for example the default constructor must zero initialize dynamic extents 77*06c3fb27SDimitry Andric array<index_type, rank_dynamic()> dynamic-extents{}; // exposition only 78*06c3fb27SDimitry Andric }; 79*06c3fb27SDimitry Andric 80*06c3fb27SDimitry Andric template<class... Integrals> 81*06c3fb27SDimitry Andric explicit extents(Integrals...) 82*06c3fb27SDimitry Andric -> see below; 83*06c3fb27SDimitry Andric} 84*06c3fb27SDimitry Andric 85*06c3fb27SDimitry Andric// layout_left synopsis 86*06c3fb27SDimitry Andric 87*06c3fb27SDimitry Andricnamespace std { 88*06c3fb27SDimitry Andric template<class Extents> 89*06c3fb27SDimitry Andric class layout_left::mapping { 90*06c3fb27SDimitry Andric public: 91*06c3fb27SDimitry Andric using extents_type = Extents; 92*06c3fb27SDimitry Andric using index_type = typename extents_type::index_type; 93*06c3fb27SDimitry Andric using size_type = typename extents_type::size_type; 94*06c3fb27SDimitry Andric using rank_type = typename extents_type::rank_type; 95*06c3fb27SDimitry Andric using layout_type = layout_left; 96*06c3fb27SDimitry Andric 97*06c3fb27SDimitry Andric // [mdspan.layout.right.cons], constructors 98*06c3fb27SDimitry Andric constexpr mapping() noexcept = default; 99*06c3fb27SDimitry Andric constexpr mapping(const mapping&) noexcept = default; 100*06c3fb27SDimitry Andric constexpr mapping(const extents_type&) noexcept; 101*06c3fb27SDimitry Andric template<class OtherExtents> 102*06c3fb27SDimitry Andric constexpr explicit(!is_convertible_v<OtherExtents, extents_type>) 103*06c3fb27SDimitry Andric mapping(const mapping<OtherExtents>&) noexcept; 104*06c3fb27SDimitry Andric template<class OtherExtents> 105*06c3fb27SDimitry Andric constexpr explicit(!is_convertible_v<OtherExtents, extents_type>) 106*06c3fb27SDimitry Andric mapping(const layout_right::mapping<OtherExtents>&) noexcept; 107*06c3fb27SDimitry Andric template<class OtherExtents> 108*06c3fb27SDimitry Andric constexpr explicit(extents_type::rank() > 0) 109*06c3fb27SDimitry Andric mapping(const layout_stride::mapping<OtherExtents>&) noexcept; 110*06c3fb27SDimitry Andric 111*06c3fb27SDimitry Andric constexpr mapping& operator=(const mapping&) noexcept = default; 112*06c3fb27SDimitry Andric 113*06c3fb27SDimitry Andric // [mdspan.layout.right.obs], observers 114*06c3fb27SDimitry Andric constexpr const extents_type& extents() const noexcept { return extents_; } 115*06c3fb27SDimitry Andric 116*06c3fb27SDimitry Andric constexpr index_type required_span_size() const noexcept; 117*06c3fb27SDimitry Andric 118*06c3fb27SDimitry Andric template<class... Indices> 119*06c3fb27SDimitry Andric constexpr index_type operator()(Indices...) const noexcept; 120*06c3fb27SDimitry Andric 121*06c3fb27SDimitry Andric static constexpr bool is_always_unique() noexcept { return true; } 122*06c3fb27SDimitry Andric static constexpr bool is_always_exhaustive() noexcept { return true; } 123*06c3fb27SDimitry Andric static constexpr bool is_always_strided() noexcept { return true; } 124*06c3fb27SDimitry Andric 125*06c3fb27SDimitry Andric static constexpr bool is_unique() noexcept { return true; } 126*06c3fb27SDimitry Andric static constexpr bool is_exhaustive() noexcept { return true; } 127*06c3fb27SDimitry Andric static constexpr bool is_strided() noexcept { return true; } 128*06c3fb27SDimitry Andric 129*06c3fb27SDimitry Andric constexpr index_type stride(rank_type) const noexcept; 130*06c3fb27SDimitry Andric 131*06c3fb27SDimitry Andric template<class OtherExtents> 132*06c3fb27SDimitry Andric friend constexpr bool operator==(const mapping&, const mapping<OtherExtents>&) noexcept; 133*06c3fb27SDimitry Andric 134*06c3fb27SDimitry Andric private: 135*06c3fb27SDimitry Andric extents_type extents_{}; // exposition only 136*06c3fb27SDimitry Andric }; 137*06c3fb27SDimitry Andric} 138*06c3fb27SDimitry Andric 139*06c3fb27SDimitry Andric// layout_right synopsis 140*06c3fb27SDimitry Andric 141*06c3fb27SDimitry Andricnamespace std { 142*06c3fb27SDimitry Andric template<class Extents> 143*06c3fb27SDimitry Andric class layout_right::mapping { 144*06c3fb27SDimitry Andric public: 145*06c3fb27SDimitry Andric using extents_type = Extents; 146*06c3fb27SDimitry Andric using index_type = typename extents_type::index_type; 147*06c3fb27SDimitry Andric using size_type = typename extents_type::size_type; 148*06c3fb27SDimitry Andric using rank_type = typename extents_type::rank_type; 149*06c3fb27SDimitry Andric using layout_type = layout_right; 150*06c3fb27SDimitry Andric 151*06c3fb27SDimitry Andric // [mdspan.layout.right.cons], constructors 152*06c3fb27SDimitry Andric constexpr mapping() noexcept = default; 153*06c3fb27SDimitry Andric constexpr mapping(const mapping&) noexcept = default; 154*06c3fb27SDimitry Andric constexpr mapping(const extents_type&) noexcept; 155*06c3fb27SDimitry Andric template<class OtherExtents> 156*06c3fb27SDimitry Andric constexpr explicit(!is_convertible_v<OtherExtents, extents_type>) 157*06c3fb27SDimitry Andric mapping(const mapping<OtherExtents>&) noexcept; 158*06c3fb27SDimitry Andric template<class OtherExtents> 159*06c3fb27SDimitry Andric constexpr explicit(!is_convertible_v<OtherExtents, extents_type>) 160*06c3fb27SDimitry Andric mapping(const layout_left::mapping<OtherExtents>&) noexcept; 161*06c3fb27SDimitry Andric template<class OtherExtents> 162*06c3fb27SDimitry Andric constexpr explicit(extents_type::rank() > 0) 163*06c3fb27SDimitry Andric mapping(const layout_stride::mapping<OtherExtents>&) noexcept; 164*06c3fb27SDimitry Andric 165*06c3fb27SDimitry Andric constexpr mapping& operator=(const mapping&) noexcept = default; 166*06c3fb27SDimitry Andric 167*06c3fb27SDimitry Andric // [mdspan.layout.right.obs], observers 168*06c3fb27SDimitry Andric constexpr const extents_type& extents() const noexcept { return extents_; } 169*06c3fb27SDimitry Andric 170*06c3fb27SDimitry Andric constexpr index_type required_span_size() const noexcept; 171*06c3fb27SDimitry Andric 172*06c3fb27SDimitry Andric template<class... Indices> 173*06c3fb27SDimitry Andric constexpr index_type operator()(Indices...) const noexcept; 174*06c3fb27SDimitry Andric 175*06c3fb27SDimitry Andric static constexpr bool is_always_unique() noexcept { return true; } 176*06c3fb27SDimitry Andric static constexpr bool is_always_exhaustive() noexcept { return true; } 177*06c3fb27SDimitry Andric static constexpr bool is_always_strided() noexcept { return true; } 178*06c3fb27SDimitry Andric 179*06c3fb27SDimitry Andric static constexpr bool is_unique() noexcept { return true; } 180*06c3fb27SDimitry Andric static constexpr bool is_exhaustive() noexcept { return true; } 181*06c3fb27SDimitry Andric static constexpr bool is_strided() noexcept { return true; } 182*06c3fb27SDimitry Andric 183*06c3fb27SDimitry Andric constexpr index_type stride(rank_type) const noexcept; 184*06c3fb27SDimitry Andric 185*06c3fb27SDimitry Andric template<class OtherExtents> 186*06c3fb27SDimitry Andric friend constexpr bool operator==(const mapping&, const mapping<OtherExtents>&) noexcept; 187*06c3fb27SDimitry Andric 188*06c3fb27SDimitry Andric private: 189*06c3fb27SDimitry Andric extents_type extents_{}; // exposition only 190*06c3fb27SDimitry Andric }; 191*06c3fb27SDimitry Andric} 192*06c3fb27SDimitry Andric 193*06c3fb27SDimitry Andric// default_accessor synopsis 194*06c3fb27SDimitry Andric 195*06c3fb27SDimitry Andricnamespace std { 196*06c3fb27SDimitry Andric template<class ElementType> 197*06c3fb27SDimitry Andric struct default_accessor { 198*06c3fb27SDimitry Andric using offset_policy = default_accessor; 199*06c3fb27SDimitry Andric using element_type = ElementType; 200*06c3fb27SDimitry Andric using reference = ElementType&; 201*06c3fb27SDimitry Andric using data_handle_type = ElementType*; 202*06c3fb27SDimitry Andric 203*06c3fb27SDimitry Andric constexpr default_accessor() noexcept = default; 204*06c3fb27SDimitry Andric template<class OtherElementType> 205*06c3fb27SDimitry Andric constexpr default_accessor(default_accessor<OtherElementType>) noexcept; 206*06c3fb27SDimitry Andric constexpr reference access(data_handle_type p, size_t i) const noexcept; 207*06c3fb27SDimitry Andric constexpr data_handle_type offset(data_handle_type p, size_t i) const noexcept; 208*06c3fb27SDimitry Andric }; 209*06c3fb27SDimitry Andric} 210*06c3fb27SDimitry Andric 211*06c3fb27SDimitry Andric*/ 212*06c3fb27SDimitry Andric 213*06c3fb27SDimitry Andric#ifndef _LIBCPP_MDSPAN 214*06c3fb27SDimitry Andric#define _LIBCPP_MDSPAN 215*06c3fb27SDimitry Andric 216*06c3fb27SDimitry Andric#include <__config> 217*06c3fb27SDimitry Andric#include <__fwd/mdspan.h> 218*06c3fb27SDimitry Andric#include <__mdspan/default_accessor.h> 219*06c3fb27SDimitry Andric#include <__mdspan/extents.h> 220*06c3fb27SDimitry Andric#include <__mdspan/layout_left.h> 221*06c3fb27SDimitry Andric#include <__mdspan/layout_right.h> 222*06c3fb27SDimitry Andric 223*06c3fb27SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 224*06c3fb27SDimitry Andric# pragma GCC system_header 225*06c3fb27SDimitry Andric#endif 226*06c3fb27SDimitry Andric 227*06c3fb27SDimitry Andric#endif // _LIBCPP_MDSPAN 228