18 #include "dynamic_extent.hpp" 28 namespace experimental {
33 template <
size_t... Extents,
size_t... OtherExtents>
34 static constexpr std::integral_constant<bool, false> __check_compatible_extents(
35 std::integral_constant<bool, false>,
42 template <
size_t Lhs,
size_t Rhs>
44 Lhs == dynamic_extent ||
45 Rhs == dynamic_extent ||
49 template <
size_t... Extents,
size_t... OtherExtents>
50 static constexpr std::integral_constant<
52 __check_compatible_extents(
53 std::integral_constant<bool, true>,
69 template <
size_t R,
class T, T FirstExt, T... Extents>
71 MDSPAN_INLINE_FUNCTION
72 constexpr
static T
get(
size_t r) {
78 template <
size_t r> MDSPAN_INLINE_FUNCTION constexpr
static T
get() {
91 template <
size_t R,
class T, T FirstExt>
93 MDSPAN_INLINE_FUNCTION
94 constexpr
static T
get(size_t) {
return FirstExt; }
95 template <
size_t> MDSPAN_INLINE_FUNCTION constexpr
static T
get() {
102 MDSPAN_INLINE_FUNCTION
103 constexpr
static T
get(size_t) {
return T(); }
104 template <
size_t> MDSPAN_INLINE_FUNCTION constexpr
static T
get() {
114 using value_type = T;
116 MDSPAN_INLINE_FUNCTION
117 constexpr
static size_t size() {
return sizeof...(Values); }
131 template <
size_t R,
size_t FirstVal,
size_t... Values>
133 MDSPAN_INLINE_FUNCTION
134 constexpr
static size_t get(
size_t r) {
142 template <
size_t R,
size_t FirstVal>
144 #if defined(__NVCC__) || defined(__NVCOMPILER) 147 MDSPAN_INLINE_FUNCTION
148 constexpr
static size_t get(
size_t r) {
149 return static_cast<int64_t
>(R) > static_cast<int64_t>(r) ? FirstVal : 0;
152 MDSPAN_INLINE_FUNCTION
153 constexpr
static size_t get(
size_t r) {
return R > r ? FirstVal : 0; }
157 MDSPAN_INLINE_FUNCTION
158 constexpr
static size_t get(size_t) {
return 0; }
172 MDSPAN_INLINE_FUNCTION
173 constexpr T &operator[](
size_t r) {
return vals[r]; }
174 MDSPAN_INLINE_FUNCTION
175 constexpr
const T &operator[](
size_t r)
const {
return vals[r]; }
179 MDSPAN_INLINE_FUNCTION
180 constexpr T operator[](
size_t) {
return T(); }
181 MDSPAN_INLINE_FUNCTION
182 constexpr
const T operator[](
size_t)
const {
return T(); }
193 template <
class TDynamic,
class TStatic, TStatic dyn_tag, TStatic... Values>
202 constexpr
static size_t m_size =
sizeof...(Values);
203 constexpr
static size_t m_size_dynamic =
204 _MDSPAN_FOLD_PLUS_RIGHT((Values == dyn_tag), 0);
215 using value_type = TDynamic;
216 using static_value_type = TStatic;
218 constexpr
static static_value_type tag_value = dyn_tag;
224 MDSPAN_TEMPLATE_REQUIRES(
class... Vals,
225 ((m_size_dynamic == 0) &&
226 (
sizeof...(Vals) > 0)))
227 MDSPAN_INLINE_FUNCTION
231 MDSPAN_TEMPLATE_REQUIRES(
class... DynVals,
232 (
sizeof...(DynVals) ==
235 MDSPAN_INLINE_FUNCTION
236 constexpr maybe_static_array(DynVals... vals)
237 : m_dyn_vals{
static_cast<TDynamic
>(vals)...} {}
240 MDSPAN_TEMPLATE_REQUIRES(
class T,
size_t N,
241 (N == m_size_dynamic && N > 0))
242 MDSPAN_INLINE_FUNCTION
243 constexpr maybe_static_array(
const std::array<T, N> &vals) {
244 for (
size_t r = 0; r < N; r++)
245 m_dyn_vals[r] = static_cast<TDynamic>(vals[r]);
248 MDSPAN_TEMPLATE_REQUIRES(
class T,
size_t N,
249 (N == m_size_dynamic && N == 0))
250 MDSPAN_INLINE_FUNCTION
251 constexpr maybe_static_array(
const std::array<T, N> &) : m_dyn_vals{} {}
253 #ifdef __cpp_lib_span 254 MDSPAN_TEMPLATE_REQUIRES(
class T,
size_t N,
255 (N == m_size_dynamic))
256 MDSPAN_INLINE_FUNCTION
257 constexpr maybe_static_array(
const std::span<T, N> &vals) {
258 for (
size_t r = 0; r < N; r++)
259 m_dyn_vals[r] = static_cast<TDynamic>(vals[r]);
264 MDSPAN_TEMPLATE_REQUIRES(
class... DynVals,
265 (
sizeof...(DynVals) !=
268 MDSPAN_INLINE_FUNCTION
269 constexpr maybe_static_array(DynVals... vals) {
270 static_assert((
sizeof...(DynVals) == m_size),
"Invalid number of values.");
271 TDynamic values[m_size]{
static_cast<TDynamic
>(vals)...};
272 for (
size_t r = 0; r < m_size; r++) {
274 if (static_val == dyn_tag) {
280 assert(values[r] == static_cast<TDynamic>(static_val));
286 MDSPAN_TEMPLATE_REQUIRES(
288 (N != m_size_dynamic && m_size_dynamic > 0))
289 MDSPAN_INLINE_FUNCTION
290 constexpr maybe_static_array(
const std::array<T, N> &vals) {
291 static_assert((N == m_size),
"Invalid number of values.");
296 for (
size_t r = 0; r < m_size; r++) {
298 if (static_val == dyn_tag) {
304 assert(static_cast<TDynamic>(vals[r]) ==
305 static_cast<TDynamic>(static_val));
311 #ifdef __cpp_lib_span 312 MDSPAN_TEMPLATE_REQUIRES(
314 (N != m_size_dynamic && m_size_dynamic > 0))
315 MDSPAN_INLINE_FUNCTION
316 constexpr maybe_static_array(
const std::span<T, N> &vals) {
317 static_assert((N == m_size) || (m_size == dynamic_extent));
321 for (
size_t r = 0; r < m_size; r++) {
323 if (static_val == dyn_tag) {
328 assert(static_cast<TDynamic>(vals[r]) ==
329 static_cast<TDynamic>(static_val));
337 MDSPAN_INLINE_FUNCTION
340 MDSPAN_INLINE_FUNCTION
341 constexpr TDynamic
value(
size_t r)
const {
344 :
static_cast<TDynamic
>(static_val);
346 MDSPAN_INLINE_FUNCTION
347 constexpr TDynamic operator[](
size_t r)
const {
return value(r); }
351 MDSPAN_INLINE_FUNCTION
352 constexpr
static size_t size() {
return m_size; }
353 MDSPAN_INLINE_FUNCTION
354 constexpr
static size_t size_dynamic() {
return m_size_dynamic; }
362 namespace experimental {
372 template <
class IndexType,
size_t... Extents>
class extents {
375 using index_type = IndexType;
376 using size_type = make_unsigned_t<index_type>;
377 using rank_type = size_t;
380 "extents::index_type must be a signed or unsigned integer type");
382 constexpr
static rank_type m_rank =
sizeof...(Extents);
383 constexpr
static rank_type m_rank_dynamic =
384 _MDSPAN_FOLD_PLUS_RIGHT((Extents == dynamic_extent), 0);
389 _MDSPAN_NO_UNIQUE_ADDRESS
vals_t m_vals;
393 MDSPAN_INLINE_FUNCTION
394 constexpr
static rank_type rank() noexcept {
return m_rank; }
395 MDSPAN_INLINE_FUNCTION
396 constexpr
static rank_type rank_dynamic() noexcept {
return m_rank_dynamic; }
398 MDSPAN_INLINE_FUNCTION
399 constexpr index_type extent(rank_type r)
const noexcept {
return m_vals.value(r); }
400 MDSPAN_INLINE_FUNCTION
401 constexpr
static size_t static_extent(rank_type r) noexcept {
402 return vals_t::static_value(r);
406 MDSPAN_INLINE_FUNCTION_DEFAULTED
407 constexpr
extents() noexcept =
default;
411 MDSPAN_TEMPLATE_REQUIRES(
412 class... OtherIndexTypes,
414 _MDSPAN_FOLD_AND(_MDSPAN_TRAIT(is_convertible, OtherIndexTypes,
416 _MDSPAN_FOLD_AND(_MDSPAN_TRAIT(is_nothrow_constructible, index_type,
417 OtherIndexTypes) ) &&
418 (
sizeof...(OtherIndexTypes) == m_rank ||
419 sizeof...(OtherIndexTypes) == m_rank_dynamic)))
420 MDSPAN_INLINE_FUNCTION
421 constexpr
explicit extents(OtherIndexTypes... dynvals) noexcept
422 : m_vals(static_cast<index_type>(dynvals)...) {}
424 MDSPAN_TEMPLATE_REQUIRES(
425 class OtherIndexType,
size_t N,
428 _MDSPAN_TRAIT(is_convertible, OtherIndexType, index_type) &&
429 _MDSPAN_TRAIT(is_nothrow_constructible, index_type,
431 (N == m_rank || N == m_rank_dynamic)))
432 MDSPAN_INLINE_FUNCTION
433 MDSPAN_CONDITIONAL_EXPLICIT(N != m_rank_dynamic)
434 constexpr
extents(
const array<OtherIndexType, N> &exts) noexcept
435 : m_vals(std::move(exts)) {}
437 #ifdef __cpp_lib_span 438 MDSPAN_TEMPLATE_REQUIRES(
439 class OtherIndexType,
size_t N,
441 (_MDSPAN_TRAIT(is_convertible, OtherIndexType, index_type) &&
442 _MDSPAN_TRAIT(is_nothrow_constructible, index_type, OtherIndexType) &&
443 (N == m_rank || N == m_rank_dynamic)))
444 MDSPAN_INLINE_FUNCTION
445 MDSPAN_CONDITIONAL_EXPLICIT(N != m_rank_dynamic)
446 constexpr
extents(
const span<OtherIndexType, N> &exts) noexcept
447 : m_vals(std::move(exts)) {}
455 MDSPAN_TEMPLATE_REQUIRES(
456 size_t DynCount,
size_t R,
class OtherExtents,
class... DynamicValues,
457 ((R < m_rank) && (static_extent(R) == dynamic_extent)))
458 MDSPAN_INLINE_FUNCTION
459 vals_t __construct_vals_from_extents(std::integral_constant<size_t, DynCount>,
460 std::integral_constant<size_t, R>,
461 const OtherExtents &exts,
462 DynamicValues... dynamic_values) noexcept {
463 return __construct_vals_from_extents(
464 std::integral_constant<size_t, DynCount + 1>(),
465 std::integral_constant<size_t, R + 1>(), exts, dynamic_values...,
469 MDSPAN_TEMPLATE_REQUIRES(
470 size_t DynCount,
size_t R,
class OtherExtents,
class... DynamicValues,
471 ((R < m_rank) && (static_extent(R) != dynamic_extent)))
472 MDSPAN_INLINE_FUNCTION
473 vals_t __construct_vals_from_extents(std::integral_constant<size_t, DynCount>,
474 std::integral_constant<size_t, R>,
475 const OtherExtents &exts,
476 DynamicValues... dynamic_values) noexcept {
477 return __construct_vals_from_extents(
478 std::integral_constant<size_t, DynCount>(),
479 std::integral_constant<size_t, R + 1>(), exts, dynamic_values...);
482 MDSPAN_TEMPLATE_REQUIRES(
483 size_t DynCount,
size_t R,
class OtherExtents,
class... DynamicValues,
484 ((R == m_rank) && (DynCount == m_rank_dynamic)))
485 MDSPAN_INLINE_FUNCTION
486 vals_t __construct_vals_from_extents(std::integral_constant<size_t, DynCount>,
487 std::integral_constant<size_t, R>,
488 const OtherExtents &,
489 DynamicValues... dynamic_values) noexcept {
490 return vals_t{
static_cast<index_type
>(dynamic_values)...};
496 MDSPAN_TEMPLATE_REQUIRES(
497 class OtherIndexType,
size_t... OtherExtents,
502 decltype(detail::__check_compatible_extents(
503 std::integral_constant<
bool,
sizeof...(Extents) ==
504 sizeof...(OtherExtents)>{},
507 MDSPAN_INLINE_FUNCTION
508 MDSPAN_CONDITIONAL_EXPLICIT((((Extents != dynamic_extent) &&
509 (OtherExtents == dynamic_extent)) ||
511 (std::numeric_limits<index_type>::max() <
512 std::numeric_limits<OtherIndexType>::max()))
514 : m_vals(__construct_vals_from_extents(
515 std::integral_constant<size_t, 0>(),
516 std::integral_constant<size_t, 0>(), other)) {}
519 template <
class OtherIndexType,
size_t... OtherExtents>
520 MDSPAN_INLINE_FUNCTION
friend constexpr
bool 524 for (size_type r = 0; r < m_rank; r++)
525 value &= rhs.extent(r) == lhs.extent(r);
529 #if !(MDSPAN_HAS_CXX_20) 530 template <
class OtherIndexType,
size_t... OtherExtents>
531 MDSPAN_INLINE_FUNCTION
friend constexpr
bool 534 return !(lhs == rhs);
542 template <
class IndexType,
size_t Rank,
546 template <
class IndexType,
size_t Rank,
size_t... ExtentsPack>
552 ::std::experimental::dynamic_extent,
553 ExtentsPack...>>::type;
556 template <
class IndexType,
size_t... ExtentsPack>
565 template <
class IndexType,
size_t Rank>
569 #if defined(_MDSPAN_USE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION) 570 template <
class... IndexTypes>
573 size_t((IndexTypes(), ::std::experimental::dynamic_extent))...>;
581 template <
class IndexType,
size_t... ExtentsPack>
583 : ::std::true_type {};
586 #if MDSPAN_HAS_CXX_17 constexpr detail_get::get_impl< i > get
A generalization of std::get, where the index is known at compile time.
Definition: get.hpp:50
Definition: extents.hpp:129
Definition: extents.hpp:579
constexpr bool value
T is a fixed or dynamic value that is reducible to a number.
Definition: value.hpp:45
constexpr bool size
T is either an index representing a size, or unbounded_size_t, which indicates that the size is unbou...
Definition: size.hpp:65
Definition: extents.hpp:194
Definition: extents.hpp:67
Definition: extents.hpp:544
Definition: trait_backports.hpp:64
Definition: extents.hpp:110
Definition: extents.hpp:170
Definition: extents.hpp:43
Definition: extents.hpp:372