19 #include "default_accessor.hpp" 20 #include "layout_right.hpp" 21 #include "extents.hpp" 22 #include "trait_backports.hpp" 23 #include "compressed_pair.hpp" 26 namespace experimental {
31 class LayoutPolicy = layout_right,
32 class AccessorPolicy = default_accessor<ElementType>
37 static_assert(detail::__is_extents_v<Extents>,
"std::experimental::mdspan's Extents template parameter must be a specialization of std::experimental::extents.");
41 struct __deduction_workaround;
43 template <
size_t... Idxs>
44 struct __deduction_workaround<index_sequence<Idxs...>>
46 MDSPAN_FORCE_INLINE_FUNCTION
static constexpr
47 size_t __size(
mdspan const& __self) noexcept {
48 return _MDSPAN_FOLD_TIMES_RIGHT((__self.__mapping_ref().extents().extent(Idxs)),
size_t(1));
50 MDSPAN_FORCE_INLINE_FUNCTION
static constexpr
51 bool __empty(
mdspan const& __self) noexcept {
52 return (__self.rank()>0) && _MDSPAN_FOLD_OR((__self.__mapping_ref().extents().extent(Idxs)==index_type(0)));
54 template <
class ReferenceType,
class SizeType,
size_t N>
55 MDSPAN_FORCE_INLINE_FUNCTION
static constexpr
56 ReferenceType __callop(
mdspan const& __self,
const array<SizeType, N>& indices) noexcept {
57 return __self.__accessor_ref().access(__self.__ptr_ref(), __self.__mapping_ref()(indices[Idxs]...));
60 template <
class ReferenceType,
class SizeType>
61 MDSPAN_FORCE_INLINE_FUNCTION
static constexpr
62 ReferenceType __callop(
mdspan const& __self,
const span<SizeType, Extents::rank()>& indices) noexcept {
63 return __self.__accessor_ref().access(__self.__ptr_ref(), __self.__mapping_ref()(indices[Idxs]...));
73 using extents_type = Extents;
74 using layout_type = LayoutPolicy;
75 using accessor_type = AccessorPolicy;
76 using mapping_type =
typename layout_type::template mapping<extents_type>;
77 using element_type = ElementType;
78 using value_type = remove_cv_t<element_type>;
79 using index_type =
typename extents_type::index_type;
80 using size_type =
typename extents_type::size_type;
81 using rank_type =
typename extents_type::rank_type;
82 using data_handle_type =
typename accessor_type::data_handle_type;
83 using reference =
typename accessor_type::reference;
85 MDSPAN_INLINE_FUNCTION
static constexpr
size_t rank() noexcept {
return extents_type::rank(); }
86 MDSPAN_INLINE_FUNCTION
static constexpr
size_t rank_dynamic() noexcept {
return extents_type::rank_dynamic(); }
87 MDSPAN_INLINE_FUNCTION
static constexpr
size_t static_extent(
size_t r) noexcept {
return extents_type::static_extent(r); }
88 MDSPAN_INLINE_FUNCTION constexpr index_type extent(
size_t r)
const noexcept {
return __mapping_ref().extents().extent(r); };
93 using __impl = __deduction_workaround<make_index_sequence<extents_type::rank()>>;
102 #if !MDSPAN_HAS_CXX_20 103 MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr
mdspan() =
default;
105 MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr
mdspan()
108 (extents_type::rank_dynamic() > 0) &&
109 _MDSPAN_TRAIT(is_default_constructible, data_handle_type) &&
110 _MDSPAN_TRAIT(is_default_constructible, mapping_type) &&
111 _MDSPAN_TRAIT(is_default_constructible, accessor_type)
114 MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr
mdspan(
const mdspan&) =
default;
115 MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr
mdspan(
mdspan&&) =
default;
117 MDSPAN_TEMPLATE_REQUIRES(
120 _MDSPAN_FOLD_AND(_MDSPAN_TRAIT(is_convertible, SizeTypes, index_type) ) &&
121 _MDSPAN_FOLD_AND(_MDSPAN_TRAIT(is_nothrow_constructible, index_type, SizeTypes) ) &&
122 ((
sizeof...(SizeTypes) == rank()) || (
sizeof...(SizeTypes) == rank_dynamic())) &&
123 _MDSPAN_TRAIT(is_constructible, mapping_type, extents_type) &&
124 _MDSPAN_TRAIT(is_default_constructible, accessor_type)
127 MDSPAN_INLINE_FUNCTION
128 explicit constexpr
mdspan(data_handle_type p, SizeTypes... dynamic_extents)
130 : __members(std::move(p),
__map_acc_pair_t(mapping_type(extents_type(static_cast<index_type>(std::move(dynamic_extents))...)), accessor_type()))
133 MDSPAN_TEMPLATE_REQUIRES(
134 class SizeType,
size_t N,
136 _MDSPAN_TRAIT(is_convertible, SizeType, index_type) &&
137 _MDSPAN_TRAIT(is_nothrow_constructible, index_type, SizeType) &&
138 ((N == rank()) || (N == rank_dynamic())) &&
139 _MDSPAN_TRAIT(is_constructible, mapping_type, extents_type) &&
140 _MDSPAN_TRAIT(is_default_constructible, accessor_type)
143 MDSPAN_CONDITIONAL_EXPLICIT(N != rank_dynamic())
144 MDSPAN_INLINE_FUNCTION
145 constexpr mdspan(data_handle_type p,
const array<SizeType, N>& dynamic_extents)
146 : __members(std::move(p),
__map_acc_pair_t(mapping_type(extents_type(dynamic_extents)), accessor_type()))
149 #ifdef __cpp_lib_span 150 MDSPAN_TEMPLATE_REQUIRES(
151 class SizeType,
size_t N,
153 _MDSPAN_TRAIT(is_convertible, SizeType, index_type) &&
154 _MDSPAN_TRAIT(is_nothrow_constructible, index_type, SizeType) &&
155 ((N == rank()) || (N == rank_dynamic())) &&
156 _MDSPAN_TRAIT(is_constructible, mapping_type, extents_type) &&
157 _MDSPAN_TRAIT(is_default_constructible, accessor_type)
160 MDSPAN_CONDITIONAL_EXPLICIT(N != rank_dynamic())
161 MDSPAN_INLINE_FUNCTION
162 constexpr mdspan(data_handle_type p, span<SizeType, N> dynamic_extents)
163 : __members(std::move(p),
__map_acc_pair_t(mapping_type(extents_type(as_const(dynamic_extents))), accessor_type()))
167 MDSPAN_FUNCTION_REQUIRES(
168 (MDSPAN_INLINE_FUNCTION constexpr),
169 mdspan, (data_handle_type p,
const extents_type& exts), ,
170 (_MDSPAN_TRAIT(is_default_constructible, accessor_type) &&
171 _MDSPAN_TRAIT(is_constructible, mapping_type, extents_type))
172 ) : __members(std::move(p),
__map_acc_pair_t(mapping_type(exts), accessor_type()))
175 MDSPAN_FUNCTION_REQUIRES(
176 (MDSPAN_INLINE_FUNCTION constexpr),
177 mdspan, (data_handle_type p,
const mapping_type& m), ,
178 (_MDSPAN_TRAIT(is_default_constructible, accessor_type))
182 MDSPAN_INLINE_FUNCTION
183 constexpr mdspan(data_handle_type p,
const mapping_type& m,
const accessor_type& a)
187 MDSPAN_TEMPLATE_REQUIRES(
188 class OtherElementType,
class OtherExtents,
class OtherLayoutPolicy,
class OtherAccessor,
190 _MDSPAN_TRAIT(is_constructible, mapping_type,
typename OtherLayoutPolicy::template mapping<OtherExtents>) &&
191 _MDSPAN_TRAIT(is_constructible, accessor_type, OtherAccessor)
194 MDSPAN_INLINE_FUNCTION
196 : __members(other.__ptr_ref(),
__map_acc_pair_t(other.__mapping_ref(), other.__accessor_ref()))
198 static_assert(_MDSPAN_TRAIT(is_constructible, data_handle_type,
typename OtherAccessor::data_handle_type),
"Incompatible data_handle_type for mdspan construction");
199 static_assert(_MDSPAN_TRAIT(is_constructible, extents_type, OtherExtents),
"Incompatible extents for mdspan construction");
211 MDSPAN_INLINE_FUNCTION_DEFAULTED _MDSPAN_CONSTEXPR_14_DEFAULTED mdspan& operator=(
const mdspan&) =
default;
212 MDSPAN_INLINE_FUNCTION_DEFAULTED _MDSPAN_CONSTEXPR_14_DEFAULTED mdspan& operator=(mdspan&&) =
default;
218 #if MDSPAN_USE_BRACKET_OPERATOR 219 MDSPAN_TEMPLATE_REQUIRES(
222 _MDSPAN_FOLD_AND(_MDSPAN_TRAIT(is_convertible, SizeTypes, index_type) ) &&
223 _MDSPAN_FOLD_AND(_MDSPAN_TRAIT(is_nothrow_constructible, index_type, SizeTypes) ) &&
224 (rank() ==
sizeof...(SizeTypes))
227 MDSPAN_FORCE_INLINE_FUNCTION
228 constexpr reference operator[](SizeTypes... indices)
const 230 return __accessor_ref().access(__ptr_ref(), __mapping_ref()(static_cast<index_type>(std::move(indices))...));
234 MDSPAN_TEMPLATE_REQUIRES(
237 _MDSPAN_TRAIT(is_convertible, SizeType, index_type) &&
238 _MDSPAN_TRAIT(is_nothrow_constructible, index_type, SizeType)
241 MDSPAN_FORCE_INLINE_FUNCTION
242 constexpr reference operator[](
const array<SizeType, rank()>& indices)
const 244 return __impl::template __callop<reference>(*
this, indices);
247 #if defined (__cpp_lib_span) or defined (OPENKALMAN_COMPATIBILITY_SPAN) 248 MDSPAN_TEMPLATE_REQUIRES(
251 _MDSPAN_TRAIT(is_convertible, SizeType, index_type) &&
252 _MDSPAN_TRAIT(is_nothrow_constructible, index_type, SizeType)
255 MDSPAN_FORCE_INLINE_FUNCTION
256 constexpr reference operator[](span<SizeType, rank()> indices)
const 258 return __impl::template __callop<reference>(*
this, indices);
260 #endif // __cpp_lib_span 262 #if !MDSPAN_USE_BRACKET_OPERATOR 263 MDSPAN_TEMPLATE_REQUIRES(
266 _MDSPAN_TRAIT(is_convertible, Index, index_type) &&
267 _MDSPAN_TRAIT(is_nothrow_constructible, index_type, Index) &&
268 extents_type::rank() == 1
271 MDSPAN_FORCE_INLINE_FUNCTION
272 constexpr reference operator[](Index idx)
const 274 return __accessor_ref().access(__ptr_ref(), __mapping_ref()(static_cast<index_type>(std::move(idx))));
278 #if MDSPAN_USE_PAREN_OPERATOR 279 MDSPAN_TEMPLATE_REQUIRES(
282 _MDSPAN_FOLD_AND(_MDSPAN_TRAIT(is_convertible, SizeTypes, index_type) ) &&
283 _MDSPAN_FOLD_AND(_MDSPAN_TRAIT(is_nothrow_constructible, index_type, SizeTypes) ) &&
284 extents_type::rank() ==
sizeof...(SizeTypes)
287 MDSPAN_FORCE_INLINE_FUNCTION
288 constexpr reference operator()(SizeTypes... indices)
const 290 return __accessor_ref().access(__ptr_ref(), __mapping_ref()(static_cast<index_type>(std::move(indices))...));
293 MDSPAN_TEMPLATE_REQUIRES(
296 _MDSPAN_TRAIT(is_convertible, SizeType, index_type) &&
297 _MDSPAN_TRAIT(is_nothrow_constructible, index_type, SizeType)
300 MDSPAN_FORCE_INLINE_FUNCTION
301 constexpr reference operator()(
const array<SizeType, rank()>& indices)
const 303 return __impl::template __callop<reference>(*
this, indices);
306 #ifdef __cpp_lib_span 307 MDSPAN_TEMPLATE_REQUIRES(
310 _MDSPAN_TRAIT(is_convertible, SizeType, index_type) &&
311 _MDSPAN_TRAIT(is_nothrow_constructible, index_type, SizeType)
314 MDSPAN_FORCE_INLINE_FUNCTION
315 constexpr reference operator()(span<SizeType, rank()> indices)
const 317 return __impl::template __callop<reference>(*
this, indices);
319 #endif // __cpp_lib_span 320 #endif // MDSPAN_USE_PAREN_OPERATOR 322 MDSPAN_INLINE_FUNCTION constexpr
size_t size()
const noexcept {
323 return __impl::__size(*
this);
326 MDSPAN_INLINE_FUNCTION constexpr
bool empty()
const noexcept {
327 return __impl::__empty(*
this);
330 MDSPAN_INLINE_FUNCTION
331 friend constexpr
void swap(mdspan& x, mdspan& y) noexcept {
333 #if !defined(_MDSPAN_HAS_HIP) && !defined(_MDSPAN_HAS_CUDA) 334 swap(x.__ptr_ref(), y.__ptr_ref());
335 swap(x.__mapping_ref(), y.__mapping_ref());
336 swap(x.__accessor_ref(), y.__accessor_ref());
348 MDSPAN_INLINE_FUNCTION constexpr
const extents_type&
extents()
const noexcept {
return __mapping_ref().extents(); };
349 MDSPAN_INLINE_FUNCTION constexpr
const data_handle_type& data_handle()
const noexcept {
return __ptr_ref(); };
350 MDSPAN_INLINE_FUNCTION constexpr
const mapping_type& mapping()
const noexcept {
return __mapping_ref(); };
351 MDSPAN_INLINE_FUNCTION constexpr
const accessor_type& accessor()
const noexcept {
return __accessor_ref(); };
356 MDSPAN_INLINE_FUNCTION
static constexpr
bool is_always_unique() noexcept {
return mapping_type::is_always_unique(); };
357 MDSPAN_INLINE_FUNCTION
static constexpr
bool is_always_exhaustive() noexcept {
return mapping_type::is_always_exhaustive(); };
358 MDSPAN_INLINE_FUNCTION
static constexpr
bool is_always_strided() noexcept {
return mapping_type::is_always_strided(); };
360 MDSPAN_INLINE_FUNCTION constexpr
bool is_unique()
const noexcept {
return __mapping_ref().is_unique(); };
361 MDSPAN_INLINE_FUNCTION constexpr
bool is_exhaustive()
const noexcept {
return __mapping_ref().is_exhaustive(); };
362 MDSPAN_INLINE_FUNCTION constexpr
bool is_strided()
const noexcept {
return __mapping_ref().is_strided(); };
363 MDSPAN_INLINE_FUNCTION constexpr index_type stride(
size_t r)
const {
return __mapping_ref().stride(r); };
369 MDSPAN_FORCE_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 data_handle_type& __ptr_ref() noexcept {
return __members.__first(); }
370 MDSPAN_FORCE_INLINE_FUNCTION constexpr data_handle_type
const& __ptr_ref()
const noexcept {
return __members.__first(); }
371 MDSPAN_FORCE_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 mapping_type& __mapping_ref() noexcept {
return __members.__second().__first(); }
372 MDSPAN_FORCE_INLINE_FUNCTION constexpr mapping_type
const& __mapping_ref()
const noexcept {
return __members.__second().__first(); }
373 MDSPAN_FORCE_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 accessor_type& __accessor_ref() noexcept {
return __members.__second().__second(); }
374 MDSPAN_FORCE_INLINE_FUNCTION constexpr accessor_type
const& __accessor_ref()
const noexcept {
return __members.__second().__second(); }
376 template <
class,
class,
class,
class>
381 #if defined(_MDSPAN_USE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION) 382 MDSPAN_TEMPLATE_REQUIRES(
383 class ElementType,
class... SizeTypes,
384 _MDSPAN_FOLD_AND(_MDSPAN_TRAIT(is_integral, SizeTypes) ) &&
385 (
sizeof...(SizeTypes) > 0)
387 MDSPAN_DEDUCTION_GUIDE
explicit mdspan(ElementType*, SizeTypes...)
388 ->
mdspan<ElementType, ::std::experimental::dextents<size_t,
sizeof...(SizeTypes)>>;
390 MDSPAN_TEMPLATE_REQUIRES(
392 (_MDSPAN_TRAIT(is_pointer, std::remove_reference_t<Pointer>))
396 MDSPAN_TEMPLATE_REQUIRES(
398 (_MDSPAN_TRAIT(is_array, CArray) && (rank_v<CArray> == 1))
402 template <
class ElementType,
class SizeType,
size_t N>
403 MDSPAN_DEDUCTION_GUIDE
mdspan(ElementType*, const ::std::array<SizeType, N>&)
406 #ifdef __cpp_lib_span 407 template <
class ElementType,
class SizeType,
size_t N>
408 MDSPAN_DEDUCTION_GUIDE
mdspan(ElementType*, ::std::span<SizeType, N>)
415 template <
class ElementType,
class SizeType,
size_t... ExtentsPack>
419 template <
class ElementType,
class MappingType>
420 MDSPAN_DEDUCTION_GUIDE
mdspan(ElementType*,
const MappingType&)
423 template <
class MappingType,
class AccessorType>
424 MDSPAN_DEDUCTION_GUIDE
mdspan(
const typename AccessorType::data_handle_type,
const MappingType&,
const AccessorType&)
Definition: compressed_pair.hpp:31
Definition: mdspan.hpp:34
Definition: extents.hpp:372