19 #include "trait_backports.hpp" 20 #include "extents.hpp" 22 #include "layout_stride.hpp" 25 namespace experimental {
28 template <
class Extents>
31 using extents_type = Extents;
32 using index_type =
typename extents_type::index_type;
33 using size_type =
typename extents_type::size_type;
34 using rank_type =
typename extents_type::rank_type;
38 static_assert(detail::__is_extents_v<extents_type>,
"std::experimental::layout_right::mapping must be instantiated with a specialization of std::experimental::extents.");
44 template <
size_t r,
size_t Rank>
45 struct __rank_count {};
47 template <
size_t r,
size_t Rank,
class I,
class... Indices>
49 constexpr index_type __compute_offset(
50 index_type offset, __rank_count<r,Rank>,
const I& i, Indices... idx)
const {
51 return __compute_offset(offset * __extents.extent(r) + i,__rank_count<r+1,Rank>(), idx...);
54 template<
class I,
class ... Indices>
56 constexpr index_type __compute_offset(
57 __rank_count<0,extents_type::rank()>,
const I& i, Indices... idx)
const {
58 return __compute_offset(i,__rank_count<1,extents_type::rank()>(),idx...);
62 constexpr index_type __compute_offset(
size_t offset, __rank_count<extents_type::rank(), extents_type::rank()>)
const {
63 return static_cast<index_type
>(offset);
67 constexpr index_type __compute_offset(__rank_count<0,0>)
const {
return 0; }
73 MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr
mapping() noexcept =
default;
74 MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr
mapping(
mapping const&) noexcept =
default;
77 constexpr
mapping(extents_type
const& __exts) noexcept
81 MDSPAN_TEMPLATE_REQUIRES(
84 _MDSPAN_TRAIT(is_constructible, extents_type, OtherExtents)
88 MDSPAN_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14
90 :__extents(other.extents())
98 MDSPAN_TEMPLATE_REQUIRES(
101 _MDSPAN_TRAIT(is_constructible, extents_type, OtherExtents) &&
102 (extents_type::rank() <= 1)
106 MDSPAN_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14
108 :__extents(other.extents())
116 MDSPAN_TEMPLATE_REQUIRES(
119 _MDSPAN_TRAIT(is_constructible, extents_type, OtherExtents)
122 MDSPAN_CONDITIONAL_EXPLICIT((extents_type::rank() > 0))
123 MDSPAN_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14
125 :__extents(other.extents())
131 #if !defined(_MDSPAN_HAS_CUDA) && !defined(_MDSPAN_HAS_HIP) && !defined(NDEBUG) 132 index_type stride = 1;
133 for(rank_type r=__extents.rank(); r>0; r--) {
134 if(stride != static_cast<index_type>(other.stride(r-1))) {
136 throw std::runtime_error(
"Assigning layout_stride to layout_right with invalid strides.");
138 stride *= __extents.extent(r-1);
143 MDSPAN_INLINE_FUNCTION_DEFAULTED _MDSPAN_CONSTEXPR_14_DEFAULTED
mapping& operator=(
mapping const&) noexcept =
default;
145 MDSPAN_INLINE_FUNCTION
146 constexpr
const extents_type&
extents()
const noexcept {
150 MDSPAN_INLINE_FUNCTION
151 constexpr index_type required_span_size()
const noexcept {
152 index_type
value = 1;
153 for(rank_type r=0; r != extents_type::rank(); ++r) value*=__extents.extent(r);
159 MDSPAN_TEMPLATE_REQUIRES(
162 (
sizeof...(Indices) == extents_type::rank()) &&
164 (_MDSPAN_TRAIT(is_convertible, Indices, index_type) &&
165 _MDSPAN_TRAIT(is_nothrow_constructible, index_type, Indices))
170 constexpr index_type operator()(Indices... idxs)
const noexcept {
171 return __compute_offset(__rank_count<0, extents_type::rank()>(), static_cast<index_type>(idxs)...);
174 MDSPAN_INLINE_FUNCTION
static constexpr
bool is_always_unique() noexcept {
return true; }
175 MDSPAN_INLINE_FUNCTION
static constexpr
bool is_always_exhaustive() noexcept {
return true; }
176 MDSPAN_INLINE_FUNCTION
static constexpr
bool is_always_strided() noexcept {
return true; }
177 MDSPAN_INLINE_FUNCTION constexpr
bool is_unique()
const noexcept {
return true; }
178 MDSPAN_INLINE_FUNCTION constexpr
bool is_exhaustive()
const noexcept {
return true; }
179 MDSPAN_INLINE_FUNCTION constexpr
bool is_strided()
const noexcept {
return true; }
181 MDSPAN_INLINE_FUNCTION
182 constexpr index_type stride(rank_type i)
const noexcept
183 #if MDSPAN_HAS_CXX_20 184 requires ( Extents::rank() > 0 )
187 index_type
value = 1;
188 for(rank_type r=extents_type::rank()-1; r>i; r--) value*=__extents.extent(r);
192 template<
class OtherExtents>
193 MDSPAN_INLINE_FUNCTION
195 return lhs.extents() == rhs.extents();
199 #if !(MDSPAN_HAS_CXX_20) 200 template<
class OtherExtents>
201 MDSPAN_INLINE_FUNCTION
203 return lhs.extents() != rhs.extents();
208 template<
size_t N,
class SizeType,
size_t ... E,
size_t ... Idx>
210 return _MDSPAN_FOLD_TIMES_RIGHT((Idx>N? __extents.template __extent<Idx>():1),1);
213 constexpr index_type __stride()
const noexcept {
214 return __get_stride<N>(__extents, make_index_sequence<extents_type::rank()>());
218 _MDSPAN_NO_UNIQUE_ADDRESS extents_type __extents{};
Definition: layout_stride.hpp:44
Definition: layout_right.hpp:29
Definition: layout_stride.hpp:70
constexpr bool value
T is a fixed or dynamic value that is reducible to a number.
Definition: value.hpp:45
Definition: trait_backports.hpp:64
Definition: layout_left.hpp:28
Definition: extents.hpp:372