Skip to content

Commit 4cff9ce

Browse files
Check negative indicies in at()
Signed-off-by: Stephan Lachnit <stephanlachnit@debian.org>
1 parent ab57448 commit 4cff9ce

File tree

1 file changed

+21
-3
lines changed

1 file changed

+21
-3
lines changed

include/experimental/__p0009_bits/mdspan.hpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
#include <stdexcept>
2626
#include <string>
27+
#include <type_traits>
2728

2829
namespace MDSPAN_IMPL_STANDARD_NAMESPACE {
2930
template <
@@ -234,7 +235,7 @@ class mdspan
234235
{
235236
size_t r = 0;
236237
for (const auto& index : {indices...}) {
237-
if (index >= __mapping_ref().extents().extent(r)) {
238+
if (__is_index_oor(index, __mapping_ref().extents().extent(r))) {
238239
throw std::out_of_range(
239240
"mdspan::at(...," + std::to_string(index) + ",...) out-of-range at rank index " + std::to_string(r) +
240241
" for mdspan with extent {...," + std::to_string(__mapping_ref().extents().extent(r)) + ",...}");
@@ -254,7 +255,7 @@ class mdspan
254255
constexpr reference at(const std::array<SizeType, rank()>& indices) const
255256
{
256257
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))) {
258259
throw std::out_of_range(
259260
"mdspan::at({...," + std::to_string(indices[r]) + ",...}) out-of-range at rank index " + std::to_string(r) +
260261
" for mdspan with extent {...," + std::to_string(__mapping_ref().extents().extent(r)) + ",...}");
@@ -274,7 +275,7 @@ class mdspan
274275
constexpr reference at(std::span<SizeType, rank()> indices) const
275276
{
276277
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))) {
278279
throw std::out_of_range(
279280
"mdspan::at({...," + std::to_string(indices[r]) + ",...}) out-of-range at rank index " + std::to_string(r) +
280281
" for mdspan with extent {...," + std::to_string(__mapping_ref().extents().extent(r)) + ",...}");
@@ -441,6 +442,23 @@ class mdspan
441442
MDSPAN_FORCE_INLINE_FUNCTION constexpr mapping_type const& __mapping_ref() const noexcept { return __members.__second().__first(); }
442443
MDSPAN_FORCE_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 accessor_type& __accessor_ref() noexcept { return __members.__second().__second(); }
443444
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+
}
444462

445463
template <class, class, class, class>
446464
friend class mdspan;

0 commit comments

Comments
 (0)