24
24
25
25
#include < stdexcept>
26
26
#include < string>
27
+ #include < type_traits>
27
28
28
29
namespace MDSPAN_IMPL_STANDARD_NAMESPACE {
29
30
template <
@@ -234,7 +235,7 @@ class mdspan
234
235
{
235
236
size_t r = 0 ;
236
237
for (const auto & index : {indices...}) {
237
- if (index >= __mapping_ref ().extents ().extent (r)) {
238
+ if (__is_index_oor ( index, __mapping_ref ().extents ().extent (r) )) {
238
239
throw std::out_of_range (
239
240
" mdspan::at(...," + std::to_string (index) + " ,...) out-of-range at rank index " + std::to_string (r) +
240
241
" for mdspan with extent {...," + std::to_string (__mapping_ref ().extents ().extent (r)) + " ,...}" );
@@ -254,7 +255,7 @@ class mdspan
254
255
constexpr reference at(const std::array<SizeType, rank()>& indices) const
255
256
{
256
257
for (size_t r = 0 ; r < indices.size (); ++r) {
257
- if (indices[r] >= __mapping_ref ().extents ().extent (r)) {
258
+ if (__is_index_oor ( indices[r], __mapping_ref ().extents ().extent (r) )) {
258
259
throw std::out_of_range (
259
260
" mdspan::at({...," + std::to_string (indices[r]) + " ,...}) out-of-range at rank index " + std::to_string (r) +
260
261
" for mdspan with extent {...," + std::to_string (__mapping_ref ().extents ().extent (r)) + " ,...}" );
@@ -274,7 +275,7 @@ class mdspan
274
275
constexpr reference at(std::span<SizeType, rank()> indices) const
275
276
{
276
277
for (size_t r = 0 ; r < indices.size (); ++r) {
277
- if (indices[r] >= __mapping_ref ().extents ().extent (r)) {
278
+ if (__is_index_oor ( indices[r], __mapping_ref ().extents ().extent (r) )) {
278
279
throw std::out_of_range (
279
280
" mdspan::at({...," + std::to_string (indices[r]) + " ,...}) out-of-range at rank index " + std::to_string (r) +
280
281
" for mdspan with extent {...," + std::to_string (__mapping_ref ().extents ().extent (r)) + " ,...}" );
@@ -441,6 +442,23 @@ class mdspan
441
442
MDSPAN_FORCE_INLINE_FUNCTION constexpr mapping_type const & __mapping_ref () const noexcept { return __members.__second ().__first (); }
442
443
MDSPAN_FORCE_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 accessor_type& __accessor_ref () noexcept { return __members.__second ().__second (); }
443
444
MDSPAN_FORCE_INLINE_FUNCTION constexpr accessor_type const & __accessor_ref () const noexcept { return __members.__second ().__second (); }
445
+
446
+ MDSPAN_TEMPLATE_REQUIRES (
447
+ class SizeType ,
448
+ /* requires */ (
449
+ _MDSPAN_TRAIT (std::is_convertible, const SizeType&, index_type) &&
450
+ _MDSPAN_TRAIT(std::is_nothrow_constructible, index_type, const SizeType&)
451
+ )
452
+ )
453
+ MDSPAN_FORCE_INLINE_FUNCTION constexpr bool __is_index_oor(SizeType index, index_type extent) const noexcept {
454
+ // Check for negative indices
455
+ if constexpr (std::is_signed_v<SizeType>) {
456
+ if (index < 0 ) {
457
+ return true ;
458
+ }
459
+ }
460
+ return static_cast <index_type>(index) >= extent;
461
+ }
444
462
445
463
template <class , class , class , class >
446
464
friend class mdspan ;
0 commit comments