brintos

brintos / llvm-project-archived public Read only

0
0
Text · 18.1 KiB · 5aeec1b Raw
475 lines · plain
1// -*- C++ -*-2//===----------------------------------------------------------------------===//3//4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.5// See https://llvm.org/LICENSE.txt for license information.6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception7//8//===---------------------------------------------------------------------===//9 10/*11 12// Overall mdspan synopsis13 14namespace std {15  // [mdspan.extents], class template extents16  template<class IndexType, size_t... Extents>17    class extents;18 19  // [mdspan.extents.dextents], alias template dextents20  template<class IndexType, size_t Rank>21    using dextents = see below;22 23  // [mdspan.extents.dims], alias template dims24  template<size_t Rank, class IndexType = size_t>25    using dims = see below; // since C++2626 27  // [mdspan.layout], layout mapping28  struct layout_left;29  struct layout_right;30  struct layout_stride;31 32  // [mdspan.accessor.default], class template default_accessor33  template<class ElementType>34    class default_accessor;35 36  // [mdspan.accessor.aligned], class template aligned_accessor37  template<class ElementType, size_t ByteAlignment>38    class aligned_accessor; // since C++2639 40  // [mdspan.mdspan], class template mdspan41  template<class ElementType, class Extents, class LayoutPolicy = layout_right,42           class AccessorPolicy = default_accessor<ElementType>>43    class mdspan;44}45 46// extents synopsis47 48namespace std {49  template<class _IndexType, size_t... _Extents>50  class extents {51  public:52    using index_type = _IndexType;53    using size_type = make_unsigned_t<index_type>;54    using rank_type = size_t;55 56    // [mdspan.extents.obs], observers of the multidimensional index space57    static constexpr rank_type rank() noexcept { return sizeof...(_Extents); }58    static constexpr rank_type rank_dynamic() noexcept { return dynamic-index(rank()); }59    static constexpr size_t static_extent(rank_type) noexcept;60    constexpr index_type extent(rank_type) const noexcept;61 62    // [mdspan.extents.cons], constructors63    constexpr extents() noexcept = default;64 65    template<class _OtherIndexType, size_t... _OtherExtents>66      constexpr explicit(see below)67        extents(const extents<_OtherIndexType, _OtherExtents...>&) noexcept;68    template<class... _OtherIndexTypes>69      constexpr explicit extents(_OtherIndexTypes...) noexcept;70    template<class _OtherIndexType, size_t N>71      constexpr explicit(N != rank_dynamic())72        extents(span<_OtherIndexType, N>) noexcept;73    template<class _OtherIndexType, size_t N>74      constexpr explicit(N != rank_dynamic())75        extents(const array<_OtherIndexType, N>&) noexcept;76 77    // [mdspan.extents.cmp], comparison operators78    template<class _OtherIndexType, size_t... _OtherExtents>79      friend constexpr bool operator==(const extents&,80                                       const extents<_OtherIndexType, _OtherExtents...>&) noexcept;81 82  private:83    // libcxx note: we do not use an array here, but we need to preserve the as-if behavior84    // for example the default constructor must zero initialize dynamic extents85    array<index_type, rank_dynamic()> dynamic-extents{};                // exposition only86  };87 88  template<class... Integrals>89    explicit extents(Integrals...)90      -> see below;91}92 93// layout_left synopsis94 95namespace std {96  template<class Extents>97  class layout_left::mapping {98  public:99    using extents_type = Extents;100    using index_type = typename extents_type::index_type;101    using size_type = typename extents_type::size_type;102    using rank_type = typename extents_type::rank_type;103    using layout_type = layout_left;104 105    // [mdspan.layout.right.cons], constructors106    constexpr mapping() noexcept = default;107    constexpr mapping(const mapping&) noexcept = default;108    constexpr mapping(const extents_type&) noexcept;109    template<class OtherExtents>110      constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)111        mapping(const mapping<OtherExtents>&) noexcept;112    template<class OtherExtents>113      constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)114        mapping(const layout_right::mapping<OtherExtents>&) noexcept;115    template<class OtherExtents>116      constexpr explicit(extents_type::rank() > 0)117        mapping(const layout_stride::mapping<OtherExtents>&) noexcept;118 119    constexpr mapping& operator=(const mapping&) noexcept = default;120 121    // [mdspan.layout.right.obs], observers122    constexpr const extents_type& extents() const noexcept { return extents_; }123 124    constexpr index_type required_span_size() const noexcept;125 126    template<class... Indices>127      constexpr index_type operator()(Indices...) const noexcept;128 129    static constexpr bool is_always_unique() noexcept { return true; }130    static constexpr bool is_always_exhaustive() noexcept { return true; }131    static constexpr bool is_always_strided() noexcept { return true; }132 133    static constexpr bool is_unique() noexcept { return true; }134    static constexpr bool is_exhaustive() noexcept { return true; }135    static constexpr bool is_strided() noexcept { return true; }136 137    constexpr index_type stride(rank_type) const noexcept;138 139    template<class OtherExtents>140      friend constexpr bool operator==(const mapping&, const mapping<OtherExtents>&) noexcept;141 142  private:143    extents_type extents_{};    // exposition only144  };145}146 147// layout_right synopsis148 149namespace std {150  template<class Extents>151  class layout_right::mapping {152  public:153    using extents_type = Extents;154    using index_type = typename extents_type::index_type;155    using size_type = typename extents_type::size_type;156    using rank_type = typename extents_type::rank_type;157    using layout_type = layout_right;158 159    // [mdspan.layout.right.cons], constructors160    constexpr mapping() noexcept = default;161    constexpr mapping(const mapping&) noexcept = default;162    constexpr mapping(const extents_type&) noexcept;163    template<class OtherExtents>164      constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)165        mapping(const mapping<OtherExtents>&) noexcept;166    template<class OtherExtents>167      constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)168        mapping(const layout_left::mapping<OtherExtents>&) noexcept;169    template<class OtherExtents>170      constexpr explicit(extents_type::rank() > 0)171        mapping(const layout_stride::mapping<OtherExtents>&) noexcept;172 173    constexpr mapping& operator=(const mapping&) noexcept = default;174 175    // [mdspan.layout.right.obs], observers176    constexpr const extents_type& extents() const noexcept { return extents_; }177 178    constexpr index_type required_span_size() const noexcept;179 180    template<class... Indices>181      constexpr index_type operator()(Indices...) const noexcept;182 183    static constexpr bool is_always_unique() noexcept { return true; }184    static constexpr bool is_always_exhaustive() noexcept { return true; }185    static constexpr bool is_always_strided() noexcept { return true; }186 187    static constexpr bool is_unique() noexcept { return true; }188    static constexpr bool is_exhaustive() noexcept { return true; }189    static constexpr bool is_strided() noexcept { return true; }190 191    constexpr index_type stride(rank_type) const noexcept;192 193    template<class OtherExtents>194      friend constexpr bool operator==(const mapping&, const mapping<OtherExtents>&) noexcept;195 196  private:197    extents_type extents_{};    // exposition only198  };199}200 201// layout_stride synopsis202 203namespace std {204  template<class Extents>205  class layout_stride::mapping {206  public:207    using extents_type = Extents;208    using index_type = typename extents_type::index_type;209    using size_type = typename extents_type::size_type;210    using rank_type = typename extents_type::rank_type;211    using layout_type = layout_stride;212 213  private:214    static constexpr rank_type rank_ = extents_type::rank();    // exposition only215 216  public:217    // [mdspan.layout.stride.cons], constructors218    constexpr mapping() noexcept;219    constexpr mapping(const mapping&) noexcept = default;220    template<class OtherIndexType>221      constexpr mapping(const extents_type&, span<OtherIndexType, rank_>) noexcept;222    template<class OtherIndexType>223      constexpr mapping(const extents_type&, const array<OtherIndexType, rank_>&) noexcept;224 225    template<class StridedLayoutMapping>226      constexpr explicit(see below) mapping(const StridedLayoutMapping&) noexcept;227 228    constexpr mapping& operator=(const mapping&) noexcept = default;229 230    // [mdspan.layout.stride.obs], observers231    constexpr const extents_type& extents() const noexcept { return extents_; }232    constexpr array<index_type, rank_> strides() const noexcept { return strides_; }233 234    constexpr index_type required_span_size() const noexcept;235 236    template<class... Indices>237      constexpr index_type operator()(Indices...) const noexcept;238 239    static constexpr bool is_always_unique() noexcept { return true; }240    static constexpr bool is_always_exhaustive() noexcept { return false; }241    static constexpr bool is_always_strided() noexcept { return true; }242 243    static constexpr bool is_unique() noexcept { return true; }244    constexpr bool is_exhaustive() const noexcept;245    static constexpr bool is_strided() noexcept { return true; }246 247    constexpr index_type stride(rank_type i) const noexcept { return strides_[i]; }248 249    template<class OtherMapping>250      friend constexpr bool operator==(const mapping&, const OtherMapping&) noexcept;251 252  private:253    extents_type extents_{};                    // exposition only254    array<index_type, rank_> strides_{};        // exposition only255  };256}257 258// default_accessor synopsis259 260namespace std {261  template<class ElementType>262  struct default_accessor {263    using offset_policy = default_accessor;264    using element_type = ElementType;265    using reference = ElementType&;266    using data_handle_type = ElementType*;267 268    constexpr default_accessor() noexcept = default;269    template<class OtherElementType>270      constexpr default_accessor(default_accessor<OtherElementType>) noexcept;271    constexpr reference access(data_handle_type p, size_t i) const noexcept;272    constexpr data_handle_type offset(data_handle_type p, size_t i) const noexcept;273  };274}275 276// aligned_accessor synopsis277 278namespace std {279  template<class ElementType, size_t ByteAlignment>280  struct aligned_accessor {281    using offset_policy = default_accessor<ElementType>;282    using element_type = ElementType;283    using reference = ElementType&;284    using data_handle_type = ElementType*;285 286    static constexpr size_t byte_alignment = ByteAlignment;287 288    constexpr aligned_accessor() noexcept = default;289 290    template<class OtherElementType, size_t OtherByteAlignment>291      constexpr aligned_accessor(292        aligned_accessor<OtherElementType, OtherByteAlignment>) noexcept;293 294    template<class OtherElementType>295      explicit constexpr aligned_accessor(296        default_accessor<OtherElementType>) noexcept;297 298    template<class OtherElementType>299    constexpr operator default_accessor<OtherElementType>() const noexcept;300 301    constexpr reference access(data_handle_type p, size_t i) const noexcept;302 303    constexpr typename offset_policy::data_handle_type304      offset(data_handle_type p, size_t i) const noexcept;305  };306}307 308// mdspan synopsis309 310namespace std {311  template<class ElementType, class Extents, class LayoutPolicy = layout_right,312           class AccessorPolicy = default_accessor<ElementType>>313  class mdspan {314  public:315    using extents_type = Extents;316    using layout_type = LayoutPolicy;317    using accessor_type = AccessorPolicy;318    using mapping_type = typename layout_type::template mapping<extents_type>;319    using element_type = ElementType;320    using value_type = remove_cv_t<element_type>;321    using index_type = typename extents_type::index_type;322    using size_type = typename extents_type::size_type;323    using rank_type = typename extents_type::rank_type;324    using data_handle_type = typename accessor_type::data_handle_type;325    using reference = typename accessor_type::reference;326 327    static constexpr rank_type rank() noexcept { return extents_type::rank(); }328    static constexpr rank_type rank_dynamic() noexcept { return extents_type::rank_dynamic(); }329    static constexpr size_t static_extent(rank_type r) noexcept330      { return extents_type::static_extent(r); }331    constexpr index_type extent(rank_type r) const noexcept { return extents().extent(r); }332 333    // [mdspan.mdspan.cons], constructors334    constexpr mdspan();335    constexpr mdspan(const mdspan& rhs) = default;336    constexpr mdspan(mdspan&& rhs) = default;337 338    template<class... OtherIndexTypes>339      constexpr explicit mdspan(data_handle_type ptr, OtherIndexTypes... exts);340    template<class OtherIndexType, size_t N>341      constexpr explicit(N != rank_dynamic())342        mdspan(data_handle_type p, span<OtherIndexType, N> exts);343    template<class OtherIndexType, size_t N>344      constexpr explicit(N != rank_dynamic())345        mdspan(data_handle_type p, const array<OtherIndexType, N>& exts);346    constexpr mdspan(data_handle_type p, const extents_type& ext);347    constexpr mdspan(data_handle_type p, const mapping_type& m);348    constexpr mdspan(data_handle_type p, const mapping_type& m, const accessor_type& a);349 350    template<class OtherElementType, class OtherExtents,351             class OtherLayoutPolicy, class OtherAccessorPolicy>352      constexpr explicit(see below)353        mdspan(const mdspan<OtherElementType, OtherExtents,354                            OtherLayoutPolicy, OtherAccessorPolicy>& other);355 356    constexpr mdspan& operator=(const mdspan& rhs) = default;357    constexpr mdspan& operator=(mdspan&& rhs) = default;358 359    // [mdspan.mdspan.members], members360    template<class... OtherIndexTypes>361      constexpr reference operator[](OtherIndexTypes... indices) const;362    template<class OtherIndexType>363      constexpr reference operator[](span<OtherIndexType, rank()> indices) const;364    template<class OtherIndexType>365      constexpr reference operator[](const array<OtherIndexType, rank()>& indices) const;366 367    constexpr size_type size() const noexcept;368    [[nodiscard]] constexpr bool empty() const noexcept;369 370    friend constexpr void swap(mdspan& x, mdspan& y) noexcept;371 372    constexpr const extents_type& extents() const noexcept { return map_.extents(); }373    constexpr const data_handle_type& data_handle() const noexcept { return ptr_; }374    constexpr const mapping_type& mapping() const noexcept { return map_; }375    constexpr const accessor_type& accessor() const noexcept { return acc_; }376 377    // per LWG-4021 "mdspan::is_always_meow() should be noexcept"378    static constexpr bool is_always_unique() noexcept379      { return mapping_type::is_always_unique(); }380    static constexpr bool is_always_exhaustive() noexcept381      { return mapping_type::is_always_exhaustive(); }382    static constexpr bool is_always_strided() noexcept383      { return mapping_type::is_always_strided(); }384 385    constexpr bool is_unique() const386      { return map_.is_unique(); }387    constexpr bool is_exhaustive() const388      { return map_.is_exhaustive(); }389    constexpr bool is_strided() const390      { return map_.is_strided(); }391    constexpr index_type stride(rank_type r) const392      { return map_.stride(r); }393 394  private:395    accessor_type acc_;         // exposition only396    mapping_type map_;          // exposition only397    data_handle_type ptr_;      // exposition only398  };399 400  template<class CArray>401    requires(is_array_v<CArray> && rank_v<CArray> == 1)402    mdspan(CArray&)403      -> mdspan<remove_all_extents_t<CArray>, extents<size_t, extent_v<CArray, 0>>>;404 405  template<class Pointer>406    requires(is_pointer_v<remove_reference_t<Pointer>>)407    mdspan(Pointer&&)408      -> mdspan<remove_pointer_t<remove_reference_t<Pointer>>, extents<size_t>>;409 410  template<class ElementType, class... Integrals>411    requires((is_convertible_v<Integrals, size_t> && ...) && sizeof...(Integrals) > 0)412    explicit mdspan(ElementType*, Integrals...)413      -> mdspan<ElementType, dextents<size_t, sizeof...(Integrals)>>;            // until C++26414  template<class ElementType, class... Integrals>415    requires((is_convertible_v<Integrals, size_t> && ...) && sizeof...(Integrals) > 0)416    explicit mdspan(ElementType*, Integrals...)417      -> mdspan<ElementType, extents<size_t, maybe-static-ext<Integrals>...>>;  // since C++26418 419  template<class ElementType, class OtherIndexType, size_t N>420    mdspan(ElementType*, span<OtherIndexType, N>)421      -> mdspan<ElementType, dextents<size_t, N>>;422 423  template<class ElementType, class OtherIndexType, size_t N>424    mdspan(ElementType*, const array<OtherIndexType, N>&)425      -> mdspan<ElementType, dextents<size_t, N>>;426 427  template<class ElementType, class IndexType, size_t... ExtentsPack>428    mdspan(ElementType*, const extents<IndexType, ExtentsPack...>&)429      -> mdspan<ElementType, extents<IndexType, ExtentsPack...>>;430 431  template<class ElementType, class MappingType>432    mdspan(ElementType*, const MappingType&)433      -> mdspan<ElementType, typename MappingType::extents_type,434                typename MappingType::layout_type>;435 436  template<class MappingType, class AccessorType>437    mdspan(const typename AccessorType::data_handle_type&, const MappingType&,438           const AccessorType&)439      -> mdspan<typename AccessorType::element_type, typename MappingType::extents_type,440                typename MappingType::layout_type, AccessorType>;441}442*/443 444#ifndef _LIBCPP_MDSPAN445#define _LIBCPP_MDSPAN446 447#if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)448#  include <__cxx03/__config>449#else450#  include <__config>451 452#  if _LIBCPP_STD_VER >= 23453#    include <__fwd/mdspan.h> // TODO(boomanaiden154): This is currently a454                              // non-standard extension to include455                              // std::dynamic_extent tracked by LWG issue 4275.456                              // This comment should be deleted or the include457                              // deleted upon resolution.458#    include <__fwd/span.h>459#    include <__mdspan/default_accessor.h>460#    include <__mdspan/extents.h>461#    include <__mdspan/layout_left.h>462#    include <__mdspan/layout_right.h>463#    include <__mdspan/layout_stride.h>464#    include <__mdspan/mdspan.h>465#  endif466 467#  include <version>468 469#  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)470#    pragma GCC system_header471#  endif472#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)473 474#endif // _LIBCPP_MDSPAN475