summaryrefslogtreecommitdiff
path: root/ext/mdspan/include/experimental/__p2642_bits
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ideasonboard.com>2025-12-18 12:28:37 +0200
committerTomi Valkeinen <tomi.valkeinen@ideasonboard.com>2025-12-18 12:35:28 +0200
commit06ebb8835022b92ea64c5b10bdb3f5afbad0e5f8 (patch)
tree49066a5d691626d097169e9c8c5b051b7bf423e4 /ext/mdspan/include/experimental/__p2642_bits
parent44e660203bcbab509b0ad08b0038192ec471a8de (diff)
Update mdspan headers to 546d4dd63697c6a331554adb6fe650e09b690812
Diffstat (limited to 'ext/mdspan/include/experimental/__p2642_bits')
-rw-r--r--ext/mdspan/include/experimental/__p2642_bits/layout_padded.hpp496
-rw-r--r--ext/mdspan/include/experimental/__p2642_bits/layout_padded_fwd.hpp86
2 files changed, 401 insertions, 181 deletions
diff --git a/ext/mdspan/include/experimental/__p2642_bits/layout_padded.hpp b/ext/mdspan/include/experimental/__p2642_bits/layout_padded.hpp
index a714090..d91313b 100644
--- a/ext/mdspan/include/experimental/__p2642_bits/layout_padded.hpp
+++ b/ext/mdspan/include/experimental/__p2642_bits/layout_padded.hpp
@@ -27,36 +27,43 @@
namespace MDSPAN_IMPL_STANDARD_NAMESPACE {
namespace MDSPAN_IMPL_PROPOSED_NAMESPACE {
-
namespace detail {
-template<class _T>
+template<class T, class U>
MDSPAN_INLINE_FUNCTION
-constexpr _T
-find_next_multiple(_T alignment, _T offset)
+constexpr T
+find_next_multiple(T alignment, U offset)
{
- if ( alignment == 0 ) {
- return _T(0);
+ if ( alignment == T(0) ) {
+ return T(0);
} else {
return ( ( offset + alignment - 1 ) / alignment) * alignment;
}
}
-template <class _ExtentsType, size_t _PaddingValue, size_t _ExtentToPadIdx>
+template <class ExtentsType, size_t PaddingValue, size_t ExtentToPadIdx>
MDSPAN_INLINE_FUNCTION constexpr size_t get_actual_static_padding_value() {
- constexpr auto rank = _ExtentsType::rank();
+ using MDSPAN_IMPL_STANDARD_NAMESPACE::detail::in_range;
+ constexpr auto rank = ExtentsType::rank();
- if constexpr (rank <= typename _ExtentsType::rank_type(1)) {
+ if constexpr (rank <= typename ExtentsType::rank_type(1)) {
return 0;
- } else if constexpr (_PaddingValue != dynamic_extent &&
- _ExtentsType::static_extent(_ExtentToPadIdx) !=
+ } else if constexpr (PaddingValue != dynamic_extent &&
+ ExtentsType::static_extent(ExtentToPadIdx) !=
dynamic_extent) {
static_assert(
- (_PaddingValue != 0) ||
- (_ExtentsType::static_extent(_ExtentToPadIdx) == 0),
+ (PaddingValue != 0) ||
+ (ExtentsType::static_extent(ExtentToPadIdx) == 0),
"padding stride can be 0 only if "
"extents_type::static_extent(extent-to-pad) is 0 or dynamic_extent");
- return find_next_multiple(_PaddingValue,
- _ExtentsType::static_extent(_ExtentToPadIdx));
+ constexpr auto ret = find_next_multiple(
+ PaddingValue, ExtentsType::static_extent(ExtentToPadIdx));
+
+ using index_type = typename ExtentsType::index_type;
+ static_assert(in_range<index_type>(ret),
+ "The least multiple of padding_value and first-static-extent "
+ "must be representable by index_type");
+
+ return ret;
} else {
return dynamic_extent;
}
@@ -66,44 +73,46 @@ MDSPAN_INLINE_FUNCTION constexpr size_t get_actual_static_padding_value() {
#endif
}
-template <size_t _PaddingValue, typename _Extents, size_t _ExtentToPadIdx, size_t _Rank, typename Enabled = void>
-struct static_array_type_for_padded_extent
-{
- static constexpr size_t padding_value = _PaddingValue;
- using index_type = typename _Extents::index_type;
- using extents_type = _Extents;
+template <size_t PaddingValue, typename Extents, size_t ExtentToPadIdx,
+ size_t Rank, typename Enabled = void>
+struct static_array_type_for_padded_extent {
+ static constexpr size_t padding_value = PaddingValue;
+ using index_type = typename Extents::index_type;
+ using extents_type = Extents;
using type = ::MDSPAN_IMPL_STANDARD_NAMESPACE::detail::maybe_static_array<
index_type, size_t, dynamic_extent,
- ::MDSPAN_IMPL_STANDARD_NAMESPACE::MDSPAN_IMPL_PROPOSED_NAMESPACE::detail::get_actual_static_padding_value<extents_type, _PaddingValue,
- _ExtentToPadIdx>()>;
+ ::MDSPAN_IMPL_STANDARD_NAMESPACE::MDSPAN_IMPL_PROPOSED_NAMESPACE::detail::
+ get_actual_static_padding_value<extents_type, PaddingValue,
+ ExtentToPadIdx>()>;
};
-template <size_t _PaddingValue, typename _Extents, size_t _ExtentToPadIdx, size_t Rank>
-struct static_array_type_for_padded_extent<_PaddingValue, _Extents,
- _ExtentToPadIdx, Rank, std::enable_if_t<Rank <= 1>> {
- using index_type = typename _Extents::index_type;
- using extents_type = _Extents;
- using type =
- ::MDSPAN_IMPL_STANDARD_NAMESPACE::detail::maybe_static_array<
- index_type, size_t, dynamic_extent, 0>;
+template <size_t PaddingValue, typename Extents, size_t ExtentToPadIdx,
+ size_t Rank>
+struct static_array_type_for_padded_extent<
+ PaddingValue, Extents, ExtentToPadIdx, Rank, std::enable_if_t<Rank <= 1>> {
+ using index_type = typename Extents::index_type;
+ using extents_type = Extents;
+ using type = ::MDSPAN_IMPL_STANDARD_NAMESPACE::detail::maybe_static_array<
+ index_type, size_t, dynamic_extent, 0>;
};
-template <size_t _PaddingValue, typename _Extents, size_t _ExtentToPadIdx>
+template <size_t PaddingValue, typename Extents, size_t ExtentToPadIdx>
struct padded_extent {
- static constexpr size_t padding_value = _PaddingValue;
- using index_type = typename _Extents::index_type;
- using extents_type = _Extents;
+ static constexpr size_t padding_value = PaddingValue;
+ using index_type = typename Extents::index_type;
+ using extents_type = Extents;
using static_array_type = typename static_array_type_for_padded_extent<
- padding_value, _Extents, _ExtentToPadIdx, _Extents::rank()>::type;
+ padding_value, Extents, ExtentToPadIdx, Extents::rank()>::type;
MDSPAN_INLINE_FUNCTION
- static constexpr auto static_value() { return static_array_type::static_value(0); }
+ static constexpr auto static_value() {
+ return static_array_type::static_value(0);
+ }
MDSPAN_INLINE_FUNCTION
- static constexpr static_array_type
- init_padding(const _Extents &exts) {
- if constexpr ((_Extents::rank() > 1) && (padding_value == dynamic_extent)) {
- return {exts.extent(_ExtentToPadIdx)};
+ static constexpr static_array_type init_padding(const Extents &exts) {
+ if constexpr ((Extents::rank() > 1) && (padding_value == dynamic_extent)) {
+ return {exts.extent(ExtentToPadIdx)};
} else {
return init_padding(exts, padding_value);
}
@@ -114,11 +123,13 @@ struct padded_extent {
}
MDSPAN_INLINE_FUNCTION static constexpr static_array_type
- init_padding([[maybe_unused]] const _Extents &exts,
- [[maybe_unused]] index_type pv) {
- if constexpr (_Extents::rank() > 1) {
- return {find_next_multiple(pv,
- exts.extent(_ExtentToPadIdx))};
+ init_padding([[maybe_unused]] const Extents &exts,
+ [[maybe_unused]] size_t pv) {
+ using MDSPAN_IMPL_STANDARD_NAMESPACE::detail::in_range;
+ if constexpr (Extents::rank() > 1) {
+ auto strd = find_next_multiple(pv, exts.extent(ExtentToPadIdx));
+ MDSPAN_IMPL_PRECONDITION(in_range<index_type>(strd));
+ return {strd};
} else {
return {};
}
@@ -128,12 +139,12 @@ struct padded_extent {
#endif
}
- template <typename _Mapping, size_t _PaddingStrideIdx>
+ template <typename Mapping, size_t PaddingStrideIdx>
MDSPAN_INLINE_FUNCTION static constexpr static_array_type
- init_padding([[maybe_unused]] const _Mapping &other_mapping,
- std::integral_constant<size_t, _PaddingStrideIdx>) {
- if constexpr (_Extents::rank() > 1) {
- return {other_mapping.stride(_PaddingStrideIdx)};
+ init_padding([[maybe_unused]] const Mapping &other_mapping,
+ std::integral_constant<size_t, PaddingStrideIdx>) {
+ if constexpr (Extents::rank() > 1) {
+ return {other_mapping.stride(PaddingStrideIdx)};
} else {
return {};
}
@@ -143,6 +154,148 @@ struct padded_extent {
#endif
}
};
+
+template <typename Extents>
+MDSPAN_INLINE_FUNCTION constexpr bool
+check_static_extents_representability() {
+ using MDSPAN_IMPL_STANDARD_NAMESPACE::detail::check_mul_result_is_nonnegative_and_representable;
+ // We cannot check statically for sure if the extents are representable
+ // if we have dynamic values -- this can only be checked by a precondition
+ // We can check if the product of only the static extents is representable though...
+ using index_type = typename Extents::index_type;
+
+ // get rid of NVCC warning "pointless comparison of unsigned integer with zero"
+ if constexpr ( Extents::rank() > 0 ) {
+ auto prod = index_type(1);
+ for (size_t i = 0; i < Extents::rank(); ++i) {
+ if (Extents::static_extent(i) == dynamic_extent)
+ continue;
+ if (!check_mul_result_is_nonnegative_and_representable(
+ prod, static_cast<index_type>(Extents::static_extent(i))))
+ return false;
+ prod *= Extents::static_extent(i);
+ }
+ }
+
+ return true;
+}
+
+template <typename Extents>
+MDSPAN_INLINE_FUNCTION constexpr bool
+check_extents_representability(const Extents &exts) {
+ using MDSPAN_IMPL_STANDARD_NAMESPACE::detail::check_mul_result_is_nonnegative_and_representable;
+ using index_type = typename Extents::index_type;
+
+ // get rid of NVCC warning "pointless comparison of unsigned integer with zero"
+ if constexpr ( Extents::rank() > 0 ) {
+ auto prod = index_type(1);
+ for (size_t i = 0; i < Extents::rank(); ++i) {
+ if (!check_mul_result_is_nonnegative_and_representable(
+ prod, static_cast<index_type>(exts.extent(i))))
+ return false;
+ prod *= exts.extent(i);
+ }
+ }
+
+ return true;
+}
+
+template <typename CheckType, size_t StaticPaddingValue, typename Extents>
+MDSPAN_INLINE_FUNCTION constexpr bool
+check_static_extents_and_left_padding_representability() {
+ using MDSPAN_IMPL_STANDARD_NAMESPACE::detail::check_mul_result_is_nonnegative_and_representable;
+ if constexpr (Extents::rank() < 2) {
+ return true;
+ }
+
+ // We cannot check statically for sure if the product of the extents and padding value
+ // are representable if we have dynamic values -- this can only be checked by a precondition
+ // We can check if the product of only the static extents and potentially the padding value (if it is static)
+ // is representable though...
+ // We already checked that StaticPaddingValue is representable by index_type
+
+ // get rid of NVCC warning "pointless comparison of unsigned integer with zero"
+ if constexpr ( Extents::rank() > 0 ) {
+ auto prod = (StaticPaddingValue != dynamic_extent) ? static_cast< CheckType >(StaticPaddingValue) : CheckType(1);
+ for (size_t i = 1; i < Extents::rank(); ++i) {
+ if (Extents::static_extent(i) == dynamic_extent)
+ continue;
+ if (!check_mul_result_is_nonnegative_and_representable(prod, static_cast< CheckType >(Extents::static_extent(i))))
+ return false;
+ prod *= Extents::static_extent(i);
+ }
+ }
+
+ return true;
+}
+
+template <typename CheckType, typename Extents>
+MDSPAN_INLINE_FUNCTION constexpr bool
+check_extents_and_left_padding_representability(const Extents &exts,
+ [[maybe_unused]] size_t dynamic_padding_value) {
+ using MDSPAN_IMPL_STANDARD_NAMESPACE::detail::check_mul_result_is_nonnegative_and_representable;
+
+ // get rid of NVCC warning "pointless comparison of unsigned integer with zero"
+ // And also a rank 1 layout cannot overflow
+ if constexpr ( Extents::rank() > 1 ) {
+ auto prod = static_cast<CheckType>(dynamic_padding_value);
+ for (size_t i = 1; i < Extents::rank(); ++i) {
+ if (!check_mul_result_is_nonnegative_and_representable(
+ prod, static_cast<CheckType>(exts.extent(i))))
+ return false;
+ prod *= exts.extent(i);
+ }
+ }
+
+ return true;
+}
+
+template <typename CheckType, size_t StaticPaddingValue, typename Extents>
+MDSPAN_INLINE_FUNCTION constexpr bool
+check_static_extents_and_right_padding_representability() {
+ using MDSPAN_IMPL_STANDARD_NAMESPACE::detail::check_mul_result_is_nonnegative_and_representable;
+
+ // We cannot check statically for sure if the product of the extents and padding value
+ // are representable if we have dynamic values -- this can only be checked by a precondition
+ // We can check if the product of only the static extents and potentially the padding value (if it is static)
+ // is representable though...
+ // We already checked that StaticPaddingValue is representable by index_type
+
+ // get rid of NVCC warning "pointless comparison of unsigned integer with zero"
+ // And also a rank 1 layout cannot overflow
+ if constexpr ( Extents::rank() > 1 ) {
+ auto prod = (StaticPaddingValue != dynamic_extent) ? static_cast< CheckType >(StaticPaddingValue) : CheckType(1);
+ for (size_t i = 0; i < Extents::rank() - 1; ++i) {
+ if (Extents::static_extent(i) == dynamic_extent)
+ continue;
+ if (!check_mul_result_is_nonnegative_and_representable(prod, static_cast< CheckType >(Extents::static_extent(i))))
+ return false;
+ prod *= Extents::static_extent(i);
+ }
+ }
+
+ return true;
+}
+
+template <typename CheckType, typename Extents>
+MDSPAN_INLINE_FUNCTION constexpr bool
+check_extents_and_right_padding_representability(const Extents &exts,
+ [[maybe_unused]] size_t dynamic_padding_value) {
+ using MDSPAN_IMPL_STANDARD_NAMESPACE::detail::check_mul_result_is_nonnegative_and_representable;
+
+ // get rid of NVCC warning "pointless comparison of unsigned integer with zero"
+ // And also a rank 1 layout cannot overflow
+ if constexpr ( Extents::rank() > 1 ) {
+ auto prod = static_cast<CheckType>(dynamic_padding_value);
+ for (size_t i = 0; i < Extents::rank() - 1; ++i) {
+ if (!check_mul_result_is_nonnegative_and_representable(prod, static_cast< CheckType >(exts.extent(i))))
+ return false;
+ prod *= exts.extent(i);
+ }
+ }
+
+ return true;
+}
} // namespace detail
template <size_t PaddingValue>
@@ -168,11 +321,17 @@ private:
|| (extents_type::static_extent(extent_to_pad_idx) == 0)
|| (extents_type::static_extent(extent_to_pad_idx) == dynamic_extent),
"out of bounds access for rank 0");
+ static_assert(detail::check_static_extents_representability<extents_type>(), "The size of the muiltidimensional index space given by the extents must be representable as a value of index_type");
+ static_assert((padding_value == dynamic_extent) || MDSPAN_IMPL_STANDARD_NAMESPACE::detail::in_range<index_type>(padding_value), "padding_value must be representable as a value of type index_type");
using padded_stride_type = detail::padded_extent< padding_value, extents_type, extent_to_pad_idx >;
static constexpr size_t static_padding_stride = padded_stride_type::static_value();
+ static_assert(detail::check_static_extents_and_left_padding_representability<index_type, static_padding_stride, extents_type>()
+ && detail::check_static_extents_and_left_padding_representability<size_t, static_padding_stride, extents_type>(),
+ "the product of static_padding_stride and static extents 1 through rank must be representable as a value of type size_t and index_type");
+
typename padded_stride_type::static_array_type padded_stride = {};
extents_type exts = {};
@@ -233,7 +392,12 @@ public:
MDSPAN_INLINE_FUNCTION
constexpr mapping(const extents_type& ext)
: padded_stride(padded_stride_type::init_padding(ext)), exts(ext)
- {}
+ {
+ MDSPAN_IMPL_PRECONDITION(detail::check_extents_representability(ext));
+ MDSPAN_IMPL_PRECONDITION(
+ detail::check_extents_and_left_padding_representability<index_type>(
+ ext, padded_stride.value(0)));
+ }
/**
* Initializes the mapping with the given extents and the specified padding value.
@@ -245,17 +409,21 @@ public:
* \param padding_value the padding value
*/
MDSPAN_TEMPLATE_REQUIRES(
- class _Size,
+ class Size,
/* requires */ (
- std::is_convertible_v<_Size, index_type>
- && std::is_nothrow_constructible_v<index_type, _Size>
+ std::is_convertible_v<Size, index_type>
+ && std::is_nothrow_constructible_v<index_type, Size>
)
)
MDSPAN_INLINE_FUNCTION
- constexpr mapping(const extents_type &ext, _Size dynamic_padding_value)
+ constexpr mapping(const extents_type &ext, Size dynamic_padding_value)
: padded_stride(padded_stride_type::init_padding(ext, dynamic_padding_value)), exts(ext)
{
assert((padding_value == dynamic_extent) || (static_cast<index_type>(padding_value) == static_cast<index_type>(dynamic_padding_value)));
+ MDSPAN_IMPL_PRECONDITION(detail::check_extents_representability(ext));
+ MDSPAN_IMPL_PRECONDITION(
+ detail::check_extents_and_left_padding_representability<index_type>(
+ ext, dynamic_padding_value));
}
/**
@@ -269,22 +437,26 @@ public:
* `padding_value` greater than or equal to `extents_type::static_extent(0)`
*/
MDSPAN_TEMPLATE_REQUIRES(
- class _OtherExtents,
- /* requires */ (std::is_constructible_v<extents_type, _OtherExtents>))
+ class OtherExtents,
+ /* requires */ (std::is_constructible_v<extents_type, OtherExtents>))
MDSPAN_CONDITIONAL_EXPLICIT(
- (!std::is_convertible_v<_OtherExtents, extents_type>))
+ (!std::is_convertible_v<OtherExtents, extents_type>))
MDSPAN_INLINE_FUNCTION
- constexpr mapping(const layout_left::mapping<_OtherExtents> &other_mapping)
+ constexpr mapping(const layout_left::mapping<OtherExtents> &other_mapping)
: padded_stride(padded_stride_type::init_padding(
other_mapping,
std::integral_constant<size_t, padded_stride_idx>{})),
exts(other_mapping.extents()) {
static_assert(
- (_OtherExtents::rank() > 1) ||
+ (OtherExtents::rank() > 1) ||
(static_padding_stride != dynamic_extent) ||
- (_OtherExtents::static_extent(extent_to_pad_idx) != dynamic_extent) ||
+ (OtherExtents::static_extent(extent_to_pad_idx) != dynamic_extent) ||
(static_padding_stride ==
- _OtherExtents::static_extent(extent_to_pad_idx)));
+ OtherExtents::static_extent(extent_to_pad_idx)));
+ MDSPAN_IMPL_PRECONDITION(detail::check_extents_representability(exts));
+ MDSPAN_IMPL_PRECONDITION(
+ detail::check_extents_and_left_padding_representability<index_type>(
+ exts, padded_stride.value(0)));
}
/**
@@ -294,15 +466,20 @@ public:
* `is_constructible_v<extents_type, OtherExtents>` is true
*/
MDSPAN_TEMPLATE_REQUIRES(
- class _OtherExtents,
- /* requires */ (std::is_constructible_v<extents_type, _OtherExtents>))
+ class OtherExtents,
+ /* requires */ (std::is_constructible_v<extents_type, OtherExtents>))
MDSPAN_CONDITIONAL_EXPLICIT((extents_type::rank() > 0))
MDSPAN_INLINE_FUNCTION
- constexpr mapping(const layout_stride::mapping<_OtherExtents> &other_mapping)
+ constexpr mapping(const layout_stride::mapping<OtherExtents> &other_mapping)
: padded_stride(padded_stride_type::init_padding(
other_mapping,
std::integral_constant<size_t, padded_stride_idx>{})),
- exts(other_mapping.extents()) {}
+ exts(other_mapping.extents()) {
+ MDSPAN_IMPL_PRECONDITION(detail::check_extents_representability(exts));
+ MDSPAN_IMPL_PRECONDITION(
+ detail::check_extents_and_left_padding_representability<index_type>(
+ exts, padded_stride.value(0)));
+ }
/**
* Converting constructor from `layout_left_padded::mapping`.
@@ -313,22 +490,26 @@ public:
* `padding_value == OtherPaddingStride`.
*/
MDSPAN_TEMPLATE_REQUIRES(
- class _Mapping,
- /* requires */ (detail::is_layout_left_padded_mapping<_Mapping>::value
+ class Mapping,
+ /* requires */ (detail::is_layout_left_padded_mapping<Mapping>::value
&&std::is_constructible_v<
- extents_type, typename _Mapping::extents_type>))
+ extents_type, typename Mapping::extents_type>))
MDSPAN_CONDITIONAL_EXPLICIT((extents_type::rank() > 1 &&
(padding_value == dynamic_extent ||
- _Mapping::padding_value == dynamic_extent)))
+ Mapping::padding_value == dynamic_extent)))
MDSPAN_INLINE_FUNCTION
- constexpr mapping(const _Mapping &other_mapping)
+ constexpr mapping(const Mapping &other_mapping)
: padded_stride(padded_stride_type::init_padding(
other_mapping,
std::integral_constant<size_t, padded_stride_idx>{})),
exts(other_mapping.extents()) {
static_assert(padding_value == dynamic_extent ||
- _Mapping::padding_value == dynamic_extent ||
- padding_value == _Mapping::padding_value);
+ Mapping::padding_value == dynamic_extent ||
+ padding_value == Mapping::padding_value);
+ MDSPAN_IMPL_PRECONDITION(detail::check_extents_representability(exts));
+ MDSPAN_IMPL_PRECONDITION(
+ detail::check_extents_and_left_padding_representability<index_type>(
+ exts, padded_stride.value(0)));
}
/**
@@ -339,19 +520,24 @@ public:
* OtherExtents>` is `true`.
*/
MDSPAN_TEMPLATE_REQUIRES(
- class _Mapping,
- /* requires */ (detail::is_layout_right_padded_mapping<_Mapping>::value
+ class Mapping,
+ /* requires */ (detail::is_layout_right_padded_mapping<Mapping>::value
&&extents_type::rank() <= 1 &&
std::is_constructible_v<extents_type,
- typename _Mapping::extents_type>))
+ typename Mapping::extents_type>))
MDSPAN_CONDITIONAL_EXPLICIT(
- (!std::is_convertible_v<typename _Mapping::extents_type, extents_type>))
+ (!std::is_convertible_v<typename Mapping::extents_type, extents_type>))
MDSPAN_INLINE_FUNCTION
- constexpr mapping(const _Mapping &other_mapping) noexcept
+ constexpr mapping(const Mapping &other_mapping) noexcept
: padded_stride(padded_stride_type::init_padding(
static_cast<extents_type>(other_mapping.extents()),
other_mapping.extents().extent(extent_to_pad_idx))),
- exts(other_mapping.extents()) {}
+ exts(other_mapping.extents()) {
+ MDSPAN_IMPL_PRECONDITION(detail::check_extents_representability(exts));
+ MDSPAN_IMPL_PRECONDITION(
+ detail::check_extents_and_left_padding_representability<index_type>(
+ exts, padded_stride.value(0)));
+ }
MDSPAN_INLINE_FUNCTION constexpr const extents_type &
extents() const noexcept {
@@ -390,7 +576,7 @@ public:
for (rank_type r = 1; r < extents_type::rank(); ++r) {
value *= exts.extent(r);
}
- return value;
+ return value == 0 ? 0 : value + exts.extent(0) - padded_stride.value(0);
}
}
@@ -403,17 +589,17 @@ public:
* - (is_nothrow_constructible_v<index_type, Indices> && ...) is true.
*/
MDSPAN_TEMPLATE_REQUIRES(
- class... _Indices,
- /* requires */ (sizeof...(_Indices) == extents_type::rank() &&
+ class... Indices,
+ /* requires */ (sizeof...(Indices) == extents_type::rank() &&
(::MDSPAN_IMPL_STANDARD_NAMESPACE::detail::
- are_valid_indices<index_type, _Indices...>())))
+ are_valid_indices<index_type, Indices...>())))
MDSPAN_INLINE_FUNCTION constexpr size_t
- operator()(_Indices... idxs) const noexcept {
+ operator()(Indices... idxs) const noexcept {
#if !defined(NDEBUG)
::MDSPAN_IMPL_STANDARD_NAMESPACE::detail::check_all_indices(this->extents(),
idxs...);
#endif // ! NDEBUG
- return compute_offset(std::index_sequence_for<_Indices...>{}, idxs...);
+ return compute_offset(std::index_sequence_for<Indices...>{}, idxs...);
}
MDSPAN_INLINE_FUNCTION static constexpr bool is_always_unique() noexcept {
@@ -464,11 +650,11 @@ public:
* Extents>`. However, this makes `padding_value` non-deducible.
*/
MDSPAN_TEMPLATE_REQUIRES(
- class _Mapping,
- /* requires */ (detail::is_layout_left_padded_mapping<_Mapping>::value &&
- (_Mapping::extents_type::rank() == extents_type::rank())))
+ class Mapping,
+ /* requires */ (detail::is_layout_left_padded_mapping<Mapping>::value &&
+ (Mapping::extents_type::rank() == extents_type::rank())))
MDSPAN_INLINE_FUNCTION friend constexpr bool
- operator==(const mapping &left, const _Mapping &right) noexcept {
+ operator==(const mapping &left, const Mapping &right) noexcept {
// Workaround for some compilers not short-circuiting properly with
// compile-time checks i.e. we can't access stride(_padding_stride_idx) of a
// rank 0 mapping
@@ -488,11 +674,11 @@ public:
* `OtherExtents::rank() == extents_type::rank()`.
*/
MDSPAN_TEMPLATE_REQUIRES(
- class _Mapping,
- /* requires */ (detail::is_layout_left_padded_mapping<_Mapping>::value &&
- (_Mapping::extents_type::rank() == extents_type::rank())))
+ class Mapping,
+ /* requires */ (detail::is_layout_left_padded_mapping<Mapping>::value &&
+ (Mapping::extents_type::rank() == extents_type::rank())))
MDSPAN_INLINE_FUNCTION friend constexpr bool
- operator!=(const mapping &left, const _Mapping &right) noexcept {
+ operator!=(const mapping &left, const Mapping &right) noexcept {
return !(left == right);
}
#endif
@@ -534,10 +720,17 @@ public:
|| (extents_type::static_extent(extent_to_pad_idx) == 0)
|| (extents_type::static_extent(extent_to_pad_idx) == dynamic_extent),
"if padding stride is 0, static_extent(extent-to-pad-rank) must also be 0 or dynamic_extent");
+ static_assert(detail::check_static_extents_representability<extents_type>(), "The size of the muiltidimensional index space given by the extents must be representable as a value of index_type");
+ static_assert((padding_value == dynamic_extent) || MDSPAN_IMPL_STANDARD_NAMESPACE::detail::in_range<index_type>(padding_value), "padding_value must be representable as a value of type index_type");
+
using padded_stride_type = detail::padded_extent< padding_value, extents_type, extent_to_pad_idx >;
static constexpr size_t static_padding_stride = padded_stride_type::static_value();
+ static_assert(detail::check_static_extents_and_right_padding_representability<index_type, static_padding_stride, extents_type>()
+ && detail::check_static_extents_and_right_padding_representability<size_t, static_padding_stride, extents_type>(),
+ "the product of static_padding_stride and static extents 1 through rank must be representable as a value of type size_t and index_type");
+
typename padded_stride_type::static_array_type padded_stride = {};
extents_type exts = {};
@@ -595,7 +788,12 @@ public:
*/
MDSPAN_INLINE_FUNCTION
constexpr mapping(const extents_type &ext)
- : padded_stride(padded_stride_type::init_padding(ext)), exts(ext) {}
+ : padded_stride(padded_stride_type::init_padding(ext)), exts(ext) {
+ MDSPAN_IMPL_PRECONDITION(detail::check_extents_representability(ext));
+ MDSPAN_IMPL_PRECONDITION(
+ detail::check_extents_and_right_padding_representability<index_type>(
+ ext, padded_stride.value(0)));
+ }
/**
* Initializes the mapping with the given extents and the specified padding value.
@@ -607,18 +805,22 @@ public:
* \param padding_value the padding value
*/
MDSPAN_TEMPLATE_REQUIRES(
- class _Size,
+ class Size,
/* requires */ (
- std::is_convertible_v<_Size, index_type>
- && std::is_nothrow_constructible_v<index_type, _Size>
+ std::is_convertible_v<Size, index_type>
+ && std::is_nothrow_constructible_v<index_type, Size>
)
)
MDSPAN_INLINE_FUNCTION
- constexpr mapping(const extents_type &ext, _Size dynamic_padding_value)
+ constexpr mapping(const extents_type &ext, Size dynamic_padding_value)
: padded_stride(padded_stride_type::init_padding(ext, static_cast<index_type>(dynamic_padding_value))),
exts(ext) {
assert((padding_value == dynamic_extent) ||
(static_cast<index_type>(padding_value) == static_cast<index_type>(dynamic_padding_value)));
+ MDSPAN_IMPL_PRECONDITION(detail::check_extents_representability(ext));
+ MDSPAN_IMPL_PRECONDITION(
+ detail::check_extents_and_right_padding_representability<index_type>(
+ ext, dynamic_padding_value));
}
/**
@@ -629,22 +831,26 @@ public:
* otherwise, `OtherExtents::static_extent(0)` must be equal to the least multiple of `padding_value` greater than or equal to `extents_type::static_extent(0)`
*/
MDSPAN_TEMPLATE_REQUIRES(
- class _OtherExtents,
- /* requires */ (std::is_constructible_v<extents_type, _OtherExtents>))
+ class OtherExtents,
+ /* requires */ (std::is_constructible_v<extents_type, OtherExtents>))
MDSPAN_CONDITIONAL_EXPLICIT(
- (!std::is_convertible_v<_OtherExtents, extents_type>))
+ (!std::is_convertible_v<OtherExtents, extents_type>))
MDSPAN_INLINE_FUNCTION
- constexpr mapping(const layout_right::mapping<_OtherExtents> &other_mapping)
+ constexpr mapping(const layout_right::mapping<OtherExtents> &other_mapping)
: padded_stride(padded_stride_type::init_padding(
other_mapping,
std::integral_constant<size_t, padded_stride_idx>{})),
exts(other_mapping.extents()) {
static_assert(
- (_OtherExtents::rank() > 1) ||
+ (OtherExtents::rank() > 1) ||
(padded_stride_type::static_value() != dynamic_extent) ||
- (_OtherExtents::static_extent(extent_to_pad_idx) != dynamic_extent) ||
+ (OtherExtents::static_extent(extent_to_pad_idx) != dynamic_extent) ||
(padded_stride_type::static_value() ==
- _OtherExtents::static_extent(extent_to_pad_idx)));
+ OtherExtents::static_extent(extent_to_pad_idx)));
+ MDSPAN_IMPL_PRECONDITION(detail::check_extents_representability(exts));
+ MDSPAN_IMPL_PRECONDITION(
+ detail::check_extents_and_right_padding_representability<index_type>(
+ exts, padded_stride.value(0)));
}
/**
@@ -654,15 +860,20 @@ public:
* `is_constructible_v<extents_type, OtherExtents>` is true
*/
MDSPAN_TEMPLATE_REQUIRES(
- class _OtherExtents,
- /* requires */ (std::is_constructible_v<extents_type, _OtherExtents>))
+ class OtherExtents,
+ /* requires */ (std::is_constructible_v<extents_type, OtherExtents>))
MDSPAN_CONDITIONAL_EXPLICIT((extents_type::rank() > 0))
MDSPAN_INLINE_FUNCTION
- constexpr mapping(const layout_stride::mapping<_OtherExtents> &other_mapping)
+ constexpr mapping(const layout_stride::mapping<OtherExtents> &other_mapping)
: padded_stride(padded_stride_type::init_padding(
other_mapping,
std::integral_constant<size_t, padded_stride_idx>{})),
- exts(other_mapping.extents()) {}
+ exts(other_mapping.extents()) {
+ MDSPAN_IMPL_PRECONDITION(detail::check_extents_representability(exts));
+ MDSPAN_IMPL_PRECONDITION(
+ detail::check_extents_and_right_padding_representability<index_type>(
+ exts, padded_stride.value(0)));
+ }
/**
* Converting constructor from `layout_right_padded::mapping`.
@@ -673,22 +884,26 @@ public:
* `padding_value == OtherPaddingStride`.
*/
MDSPAN_TEMPLATE_REQUIRES(
- class _Mapping,
- /* requires */ (detail::is_layout_right_padded_mapping<_Mapping>::value
+ class Mapping,
+ /* requires */ (detail::is_layout_right_padded_mapping<Mapping>::value
&&std::is_constructible_v<
- extents_type, typename _Mapping::extents_type>))
+ extents_type, typename Mapping::extents_type>))
MDSPAN_CONDITIONAL_EXPLICIT((extents_type::rank() > 1 &&
(padding_value == dynamic_extent ||
- _Mapping::padding_value == dynamic_extent)))
+ Mapping::padding_value == dynamic_extent)))
MDSPAN_INLINE_FUNCTION
- constexpr mapping(const _Mapping &other_mapping)
+ constexpr mapping(const Mapping &other_mapping)
: padded_stride(padded_stride_type::init_padding(
other_mapping,
std::integral_constant<size_t, padded_stride_idx>{})),
exts(other_mapping.extents()) {
static_assert(padding_value == dynamic_extent ||
- _Mapping::padding_value == dynamic_extent ||
- padding_value == _Mapping::padding_value);
+ Mapping::padding_value == dynamic_extent ||
+ padding_value == Mapping::padding_value);
+ MDSPAN_IMPL_PRECONDITION(detail::check_extents_representability(exts));
+ MDSPAN_IMPL_PRECONDITION(
+ detail::check_extents_and_right_padding_representability<index_type>(
+ exts, padded_stride.value(0)));
}
/**
@@ -699,19 +914,24 @@ public:
* OtherExtents>` is `true`.
*/
MDSPAN_TEMPLATE_REQUIRES(
- class _Mapping,
- /* requires */ (detail::is_layout_left_padded_mapping<_Mapping>::value
+ class Mapping,
+ /* requires */ (detail::is_layout_left_padded_mapping<Mapping>::value
&&extents_type::rank() <= 1 &&
std::is_constructible_v<extents_type,
- typename _Mapping::extents_type>))
+ typename Mapping::extents_type>))
MDSPAN_CONDITIONAL_EXPLICIT(
- (!std::is_convertible_v<typename _Mapping::extents_type, extents_type>))
+ (!std::is_convertible_v<typename Mapping::extents_type, extents_type>))
MDSPAN_INLINE_FUNCTION
- constexpr mapping(const _Mapping &other_mapping) noexcept
+ constexpr mapping(const Mapping &other_mapping) noexcept
: padded_stride(padded_stride_type::init_padding(
static_cast<extents_type>(other_mapping.extents()),
other_mapping.extents().extent(extent_to_pad_idx))),
- exts(other_mapping.extents()) {}
+ exts(other_mapping.extents()) {
+ MDSPAN_IMPL_PRECONDITION(detail::check_extents_representability(exts));
+ MDSPAN_IMPL_PRECONDITION(
+ detail::check_extents_and_right_padding_representability<index_type>(
+ exts, padded_stride.value(0)));
+ }
MDSPAN_INLINE_FUNCTION constexpr const extents_type &
extents() const noexcept {
@@ -745,11 +965,11 @@ public:
} else if constexpr (extents_type::rank() == 1) {
return exts.extent(0);
} else {
- index_type value = 1;
+ index_type value = padded_stride.value(0);
for (rank_type r = 0; r < extent_to_pad_idx; ++r) {
value *= exts.extent(r);
}
- return value * padded_stride.value(0);
+ return value == 0 ? 0 : value + exts.extent(extent_to_pad_idx) - padded_stride.value(0);
}
}
@@ -762,13 +982,13 @@ public:
* - (is_nothrow_constructible_v<index_type, Indices> && ...) is true.
*/
MDSPAN_TEMPLATE_REQUIRES(
- class... _Indices,
- /* requires */ (sizeof...(_Indices) == extents_type::rank() &&
+ class... Indices,
+ /* requires */ (sizeof...(Indices) == extents_type::rank() &&
(::MDSPAN_IMPL_STANDARD_NAMESPACE::detail::
- are_valid_indices<index_type, _Indices...>())))
+ are_valid_indices<index_type, Indices...>())))
MDSPAN_INLINE_FUNCTION constexpr size_t
- operator()(_Indices... idxs) const noexcept {
- return compute_offset(std::index_sequence_for<_Indices...>{}, idxs...);
+ operator()(Indices... idxs) const noexcept {
+ return compute_offset(std::index_sequence_for<Indices...>{}, idxs...);
}
MDSPAN_INLINE_FUNCTION static constexpr bool is_always_unique() noexcept {
@@ -819,11 +1039,11 @@ public:
* Extents>`. However, this makes `padding_value` non-deducible.
*/
MDSPAN_TEMPLATE_REQUIRES(
- class _Mapping,
- /* requires */ (detail::is_layout_right_padded_mapping<_Mapping>::value &&
- (_Mapping::extents_type::rank() == extents_type::rank())))
+ class Mapping,
+ /* requires */ (detail::is_layout_right_padded_mapping<Mapping>::value &&
+ (Mapping::extents_type::rank() == extents_type::rank())))
MDSPAN_INLINE_FUNCTION friend constexpr bool
- operator==(const mapping &left, const _Mapping &right) noexcept {
+ operator==(const mapping &left, const Mapping &right) noexcept {
// Workaround for some compilers not short-circuiting properly with
// compile-time checks i.e. we can't access stride(_padding_stride_idx) of a
// rank 0 mapping
@@ -843,11 +1063,11 @@ public:
* `OtherExtents::rank() == extents_type::rank()`.
*/
MDSPAN_TEMPLATE_REQUIRES(
- class _Mapping,
- /* requires */ (detail::is_layout_right_padded_mapping<_Mapping>::value &&
- (_Mapping::extents_type::rank() == extents_type::rank())))
+ class Mapping,
+ /* requires */ (detail::is_layout_right_padded_mapping<Mapping>::value &&
+ (Mapping::extents_type::rank() == extents_type::rank())))
MDSPAN_INLINE_FUNCTION friend constexpr bool
- operator!=(const mapping &left, const _Mapping &right) noexcept {
+ operator!=(const mapping &left, const Mapping &right) noexcept {
return !(left == right);
}
#endif
diff --git a/ext/mdspan/include/experimental/__p2642_bits/layout_padded_fwd.hpp b/ext/mdspan/include/experimental/__p2642_bits/layout_padded_fwd.hpp
index 3f141ff..481b1d5 100644
--- a/ext/mdspan/include/experimental/__p2642_bits/layout_padded_fwd.hpp
+++ b/ext/mdspan/include/experimental/__p2642_bits/layout_padded_fwd.hpp
@@ -24,110 +24,110 @@ namespace MDSPAN_IMPL_PROPOSED_NAMESPACE {
template <size_t padding_value = dynamic_extent>
struct layout_left_padded {
- template <class _Extents>
+ template <class Extents>
class mapping;
};
template <size_t padding_value = dynamic_extent>
struct layout_right_padded {
- template <class _Extents>
+ template <class Extents>
class mapping;
};
namespace detail {
// The layout_padded_constants structs are only useful if rank > 1, otherwise they may wrap
-template <class _Layout, class _ExtentsType>
+template <class Layout, class ExtentsType>
struct layout_padded_constants;
-template <class _ExtentsType, size_t _PaddingStride>
-struct layout_padded_constants<layout_left_padded<_PaddingStride>, _ExtentsType>
+template <class ExtentsType, size_t PaddingStride>
+struct layout_padded_constants<layout_left_padded<PaddingStride>, ExtentsType>
{
- using rank_type = typename _ExtentsType::rank_type;
+ using rank_type = typename ExtentsType::rank_type;
static constexpr rank_type padded_stride_idx = 1;
static constexpr rank_type extent_to_pad_idx = 0;
};
-template <class _ExtentsType, size_t _PaddingStride>
-struct layout_padded_constants<layout_right_padded<_PaddingStride>, _ExtentsType>
+template <class ExtentsType, size_t PaddingStride>
+struct layout_padded_constants<layout_right_padded<PaddingStride>, ExtentsType>
{
- using rank_type = typename _ExtentsType::rank_type;
- static constexpr rank_type padded_stride_idx = _ExtentsType::rank() - 2;
- static constexpr rank_type extent_to_pad_idx = _ExtentsType::rank() - 1;
+ using rank_type = typename ExtentsType::rank_type;
+ static constexpr rank_type padded_stride_idx = ExtentsType::rank() - 2;
+ static constexpr rank_type extent_to_pad_idx = ExtentsType::rank() - 1;
};
-template <class _Layout>
+template <class Layout>
struct is_layout_left_padded : std::false_type {};
-template <size_t _PaddingStride>
-struct is_layout_left_padded<layout_left_padded<_PaddingStride>> : std::true_type {};
+template <size_t PaddingStride>
+struct is_layout_left_padded<layout_left_padded<PaddingStride>> : std::true_type {};
-template <class _Mapping, class _Enabled = void>
+template <class Mapping, class Enabled = void>
struct is_layout_left_padded_mapping : std::false_type {};
-template <class _Mapping>
-struct is_layout_left_padded_mapping<_Mapping,
- std::enable_if_t<std::is_same<_Mapping, typename layout_left_padded<_Mapping::padding_value>::template mapping<typename _Mapping::extents_type>>::value>>
+template <class Mapping>
+struct is_layout_left_padded_mapping<Mapping,
+ std::enable_if_t<std::is_same<Mapping, typename layout_left_padded<Mapping::padding_value>::template mapping<typename Mapping::extents_type>>::value>>
: std::true_type {};
-template <class _Layout>
+template <class Layout>
struct is_layout_right_padded : std::false_type {};
-template <size_t _PaddingStride>
-struct is_layout_right_padded<layout_right_padded<_PaddingStride>> : std::true_type {};
+template <size_t PaddingStride>
+struct is_layout_right_padded<layout_right_padded<PaddingStride>> : std::true_type {};
-template <class _Mapping, class _Enabled = void>
+template <class Mapping, class Enabled = void>
struct is_layout_right_padded_mapping : std::false_type {};
-template <class _Mapping>
-struct is_layout_right_padded_mapping<_Mapping,
- std::enable_if_t<std::is_same<_Mapping, typename layout_right_padded<_Mapping::padding_value>::template mapping<typename _Mapping::extents_type>>::value>>
+template <class Mapping>
+struct is_layout_right_padded_mapping<Mapping,
+ std::enable_if_t<std::is_same<Mapping, typename layout_right_padded<Mapping::padding_value>::template mapping<typename Mapping::extents_type>>::value>>
: std::true_type {};
-template <class _LayoutExtentsType, class _PaddedLayoutMappingType>
+template <class LayoutExtentsType, class PaddedLayoutMappingType>
MDSPAN_INLINE_FUNCTION
constexpr void check_padded_layout_converting_constructor_mandates(MDSPAN_IMPL_STANDARD_NAMESPACE::detail::with_rank<0>) {}
-template <class _LayoutExtentsType, class _PaddedLayoutMappingType>
+template <class LayoutExtentsType, class PaddedLayoutMappingType>
MDSPAN_INLINE_FUNCTION
constexpr void check_padded_layout_converting_constructor_mandates(MDSPAN_IMPL_STANDARD_NAMESPACE::detail::with_rank<1>) {}
-template <class _LayoutExtentsType, class _PaddedLayoutMappingType, std::size_t N>
+template <class LayoutExtentsType, class PaddedLayoutMappingType, std::size_t N>
MDSPAN_INLINE_FUNCTION
constexpr void check_padded_layout_converting_constructor_mandates(MDSPAN_IMPL_STANDARD_NAMESPACE::detail::with_rank<N>)
{
- using extents_type = typename _PaddedLayoutMappingType::extents_type;
- constexpr auto padding_value = _PaddedLayoutMappingType::padding_value;
- constexpr auto idx = layout_padded_constants<typename _PaddedLayoutMappingType::layout_type, _LayoutExtentsType >::extent_to_pad_idx;
+ using extents_type = typename PaddedLayoutMappingType::extents_type;
+ constexpr auto padding_value = PaddedLayoutMappingType::padding_value;
+ constexpr auto idx = layout_padded_constants<typename PaddedLayoutMappingType::layout_type, LayoutExtentsType >::extent_to_pad_idx;
constexpr auto statically_determinable =
- (_LayoutExtentsType::static_extent(idx) != dynamic_extent) &&
+ (LayoutExtentsType::static_extent(idx) != dynamic_extent) &&
(extents_type::static_extent(idx) != dynamic_extent) &&
(padding_value != dynamic_extent);
static_assert(!statically_determinable ||
(padding_value == 0
- ? _LayoutExtentsType::static_extent(idx) == 0
- : _LayoutExtentsType::static_extent(idx) % padding_value == 0),
+ ? LayoutExtentsType::static_extent(idx) == 0
+ : LayoutExtentsType::static_extent(idx) % padding_value == 0),
"");
}
-template <typename _ExtentsType, typename _OtherMapping>
+template <typename ExtentsType, typename OtherMapping>
MDSPAN_INLINE_FUNCTION
constexpr void check_padded_layout_converting_constructor_preconditions(MDSPAN_IMPL_STANDARD_NAMESPACE::detail::with_rank<0>,
- const _OtherMapping&) {}
-template <typename _ExtentsType, typename _OtherMapping>
+ const OtherMapping&) {}
+template <typename ExtentsType, typename OtherMapping>
MDSPAN_INLINE_FUNCTION
constexpr void check_padded_layout_converting_constructor_preconditions(MDSPAN_IMPL_STANDARD_NAMESPACE::detail::with_rank<1>,
- const _OtherMapping&) {}
-template <typename _ExtentsType, typename _OtherMapping, std::size_t N>
+ const OtherMapping&) {}
+template <typename ExtentsType, typename OtherMapping, std::size_t N>
MDSPAN_INLINE_FUNCTION
constexpr void check_padded_layout_converting_constructor_preconditions(MDSPAN_IMPL_STANDARD_NAMESPACE::detail::with_rank<N>,
- const _OtherMapping &other_mapping) {
+ const OtherMapping &other_mapping) {
constexpr auto padded_stride_idx =
- layout_padded_constants<typename _OtherMapping::layout_type,
- _ExtentsType>::padded_stride_idx;
- constexpr auto extent_to_pad_idx = layout_padded_constants<typename _OtherMapping::layout_type, _ExtentsType>::extent_to_pad_idx;
+ layout_padded_constants<typename OtherMapping::layout_type,
+ ExtentsType>::padded_stride_idx;
+ constexpr auto extent_to_pad_idx = layout_padded_constants<typename OtherMapping::layout_type, ExtentsType>::extent_to_pad_idx;
MDSPAN_IMPL_PRECONDITION(other_mapping.stride(padded_stride_idx) == other_mapping.extents().extent(extent_to_pad_idx));
}