Christian Trott cfa096d9c9 [libc++][mdspan] Implement layout_right
This commit implements layout_right in support of C++23 mdspan
(https://wg21.link/p0009). layout_right is a layout mapping policy
whose index mapping corresponds to the memory layout of multidimensional
C-arrays, and is thus also referred to as the C-layout.

Co-authored-by: Damien L-G <dalg24@gmail.com>

Differential Revision: https://reviews.llvm.org/D151267
2023-06-29 10:12:17 -04:00

154 lines
5.3 KiB
Plaintext

// -*-C++ - *-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===---------------------------------------------------------------------===//
/*
// Overall mdspan synopsis
namespace std {
// [mdspan.extents], class template extents
template<class IndexType, size_t... Extents>
class extents;
// [mdspan.extents.dextents], alias template dextents
template<class IndexType, size_t Rank>
using dextents = see below;
// [mdspan.layout], layout mapping
struct layout_left; // not implemented yet
struct layout_right;
struct layout_stride; // not implemented yet
// [mdspan.accessor.default], class template default_accessor
template<class ElementType>
class default_accessor; // not implemented yet
// [mdspan.mdspan], class template mdspan
template<class ElementType, class Extents, class LayoutPolicy = layout_right,
class AccessorPolicy = default_accessor<ElementType>>
class mdspan; // not implemented yet
}
// extents synopsis
namespace std {
template<class _IndexType, size_t... _Extents>
class extents {
public:
using index_type = _IndexType;
using size_type = make_unsigned_t<index_type>;
using rank_type = size_t;
// [mdspan.extents.obs], observers of the multidimensional index space
static constexpr rank_type rank() noexcept { return sizeof...(_Extents); }
static constexpr rank_type rank_dynamic() noexcept { return dynamic-index(rank()); }
static constexpr size_t static_extent(rank_type) noexcept;
constexpr index_type extent(rank_type) const noexcept;
// [mdspan.extents.cons], constructors
constexpr extents() noexcept = default;
template<class _OtherIndexType, size_t... _OtherExtents>
constexpr explicit(see below)
extents(const extents<_OtherIndexType, _OtherExtents...>&) noexcept;
template<class... _OtherIndexTypes>
constexpr explicit extents(_OtherIndexTypes...) noexcept;
template<class _OtherIndexType, size_t N>
constexpr explicit(N != rank_dynamic())
extents(span<_OtherIndexType, N>) noexcept;
template<class _OtherIndexType, size_t N>
constexpr explicit(N != rank_dynamic())
extents(const array<_OtherIndexType, N>&) noexcept;
// [mdspan.extents.cmp], comparison operators
template<class _OtherIndexType, size_t... _OtherExtents>
friend constexpr bool operator==(const extents&,
const extents<_OtherIndexType, _OtherExtents...>&) noexcept;
private:
// libcxx note: we do not use an array here, but we need to preserve the as-if behavior
// for example the default constructor must zero initialize dynamic extents
array<index_type, rank_dynamic()> dynamic-extents{}; // exposition only
};
template<class... Integrals>
explicit extents(Integrals...)
-> see below;
}
// layout_right synopsis
namespace std {
template<class Extents>
class layout_right::mapping {
public:
using extents_type = Extents;
using index_type = typename extents_type::index_type;
using size_type = typename extents_type::size_type;
using rank_type = typename extents_type::rank_type;
using layout_type = layout_right;
// [mdspan.layout.right.cons], constructors
constexpr mapping() noexcept = default;
constexpr mapping(const mapping&) noexcept = default;
constexpr mapping(const extents_type&) noexcept;
template<class OtherExtents>
constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
mapping(const mapping<OtherExtents>&) noexcept;
template<class OtherExtents>
constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
mapping(const layout_left::mapping<OtherExtents>&) noexcept;
template<class OtherExtents>
constexpr explicit(extents_type::rank() > 0)
mapping(const layout_stride::mapping<OtherExtents>&) noexcept;
constexpr mapping& operator=(const mapping&) noexcept = default;
// [mdspan.layout.right.obs], observers
constexpr const extents_type& extents() const noexcept { return extents_; }
constexpr index_type required_span_size() const noexcept;
template<class... Indices>
constexpr index_type operator()(Indices...) const noexcept;
static constexpr bool is_always_unique() noexcept { return true; }
static constexpr bool is_always_exhaustive() noexcept { return true; }
static constexpr bool is_always_strided() noexcept { return true; }
static constexpr bool is_unique() noexcept { return true; }
static constexpr bool is_exhaustive() noexcept { return true; }
static constexpr bool is_strided() noexcept { return true; }
constexpr index_type stride(rank_type) const noexcept;
template<class OtherExtents>
friend constexpr bool operator==(const mapping&, const mapping<OtherExtents>&) noexcept;
private:
extents_type extents_{}; // exposition only
};
}
*/
#ifndef _LIBCPP_MDSPAN
#define _LIBCPP_MDSPAN
#include <__config>
#include <__fwd/mdspan.h>
#include <__mdspan/extents.h>
#include <__mdspan/layout_right.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
#endif // _LIBCPP_MDSPAN