-
Notifications
You must be signed in to change notification settings - Fork 69
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add element access via at()
to std::mdspan
#302
base: stable
Are you sure you want to change the base?
Conversation
at()
to std::mdspan
9e59d6e
to
7b3a6e0
Compare
Given that SizeTypes can be signed, it should also check for indices[r] < 0. |
Thanks for this comment! Is this true for |
In |
Ah right, thanks for pointing this out! Edit: updated the pull request |
7b3a6e0
to
0accddc
Compare
0accddc
to
4cff9ce
Compare
// Check for negative indices | ||
if constexpr(std::is_signed_v<SizeType>) { | ||
if(index < 0) { | ||
return true; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SizeType
doesn't need to be integral here or even less-than comparable with int
. mdspan behaves as if all operations on indices happen after conversion to index_type
. Thus, should we consider instead converting to index_type
first, as we do below?
// Check for negative indices | |
if constexpr(std::is_signed_v<SizeType>) { | |
if(index < 0) { | |
return true; | |
} | |
} | |
// Check for negative indices | |
if constexpr (std::is_signed_v<index_type>) { | |
if (static_cast<index_type>(index) < 0) { | |
return true; | |
} | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems reasonable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After thinking about it again, I'm not sure if this is correct: imagine I have unsigned short
as index_type
and an extent of size of 65535
. Now, I want to access with a signed short
of value -10
. What I end up getting is the element at index 65526
, which is not the expected result.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I ended up reverting this: if SizeType
is not integral or less-than comparable with int, std::is_signed_v
should be false anyway. The question is, what happens if SizeType
can be negative, but is is not integral or less-than comparable with int, while index_type
is not signed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After thinking about it again, I'm not sure if this is correct: imagine I have unsigned short as index_type and an extent of size of 65535. Now, I want to access with a signed short of value -10. What I end up getting is the element at index 65526, which is not the expected result.
Thanks for pointing this out! The underlying issue, as I understand it, is that index-cast
returns its input (with the same type, not cast to index_type
) if the input type is integral-not-bool.
[mdspan.mdspan.members] 2 - 3 together say that the precondition on the input of mdspan::operator[]
applies to extents_type::
index-cast
(std::move(indices...))
. For the specific case you mentioned of SizeType = signed short
, [mdspan.extents.expo] 9 explains that index-cast
would just return signed short
; it does not convert to index_type
. -10 cannot be part of a multidimensional index in extents()
, so this violates a precondition.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw, I was looking through extents.hpp and noticed check_all_indices
. It looks like the layout mappings using this. I think it could be refactored a bit to serve your needs.
Signed-off-by: Stephan Lachnit <[email protected]>
Signed-off-by: Stephan Lachnit <[email protected]>
4cff9ce
to
efea5cb
Compare
|
6ad06bc
to
0ed2570
Compare
450a611
to
5325056
Compare
I don't quite get the build failure on MSVC, would need some help there... |
_MDSPAN_TRAIT(std::is_nothrow_constructible, index_type, const SizeType&) | ||
) | ||
) | ||
MDSPAN_FORCE_INLINE_FUNCTION constexpr bool __is_index_oor(SizeType index, index_type extent) const noexcept { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm of the opinion that we shouldn't add to the reserved names (i.e. __
prefix) even though it's consistent with the rest of the class since we do plan on removing them.
What if you used the requires clause from MDSPAN_TEMPLATE_REQUIRES(
class... SizeTypes,
/* requires */ (
extents_type::rank() == sizeof...(SizeTypes) &&
(detail::are_valid_indices<index_type, SizeTypes...>())
)
) |
Closes #300
Possible implementation for ::at element access to mdspan with boundary checks. The boundary check is implemented with a for loop, as I did not see any other way to achieve this. The error message is inspired by the
std::span::at
error message from libstdc++ (gcc-mirror/gcc@1fa85dc).Note that this does not implement ::at element access to mdarray.