Document #: | P3383R0 |
Date: | 2024-09-05 |
Project: | Programming Language C++ |
Audience: |
Library Evolution Working Group (LEWG) SG23 Safety and Security |
Reply-to: |
Stephan Lachnit <stephan.lachnit@cern.ch> Xavier Bonaventura (BMW) <xavier.bonaventura@bmw.de> |
This paper proposes element access with bounds checking to
std::mdspan
via at()
member functions.
The new
at()
member
functions provide memory-safe element access to
std::mdspan
,
and thus have defined behavior. Out-of-bound access can be caught by
catching the std::out_of_range
exception.
In [P2821R4], element access with bounds
checking via
at()
has
been added to
std::span
.
One of the main motivations for this change was consistency with other
containers that have element access with bounds checking via
at()
.
Similarly, such element access should be added to
std::mdspan
.
The impact of this proposal on the standard is low. The proposed
function signatures for the
at()
member
functions are identical to the function signatures for the subscript
operators as proposed in [P0009R18].
One consideration is that the
at()
method
has previously not been used with multi-dimensional arguments. However,
this was also true for the subscript operator before the possibility was
introduced in [P2128R6].
The wording is relative to [N4981].
In 17.3.2 ([version.syn]), add:
#define __cpp_lib_mdspan_at YYYYMML // also in <mdspan>
Adjust the placeholder value as needed to denote this proposal’s date of adoption.
In 24.7.3.6.1 ([mdspan.mdspan.overview]), add the following immediately after the subscript operators:
template<class... OtherIndexTypes> constexpr reference at(OtherIndexTypes... indices) const; template<class OtherIndexType> constexpr reference at(span<OtherIndexType, rank()> indices) const; template<class OtherIndexType> constexpr reference at(const array<OtherIndexType, rank()>& indices) const;
In 24.7.3.6.3 ([mdspan.mdspan.members]), add the following immediately after the subscript operators:
template<class... OtherIndexTypes> constexpr reference at(OtherIndexTypes... indices) const;
7 Constraints:
- (7.1)
(is_convertible_v<OtherIndexTypes, index_type> && ...)
istrue
,- (7.2)
(is_nothrow_constructible_v<index_type, OtherIndexTypes> && ...)
istrue
, and- (7.3)
sizeof...(OtherIndexTypes) == rank()
istrue
.8 Returns:
(*this)[indices...]
9 Throws:
out_of_range
if
indices_v[i] >= extent(i) || indices_v[i] < 0
for anyindices_v[i]
invector<OtherIndexTypes>({indices...})
.template<class OtherIndexType> constexpr reference at(span<OtherIndexType, rank()> indices) const;
template<class OtherIndexType> constexpr reference at(const array<OtherIndexType, rank()>& indices) const;
10 Constraints:
- (10.1)
is_convertible_v<const OtherIndexType&, index_type>
istrue
, and- (10.2)
is_nothrow_constructible_v<index_type, const OtherIndexType&>
istrue
.11 Returns:
(*this)[indices]
12 Throws:
out_of_range
if
indices[i] >= extent(i) || indices[i] < 0
for anyindices[i]
inindices
.
The at()
member functions have been implemented in the
std::mdspan
reference implementation from the Kokkos project at Sandia National
Laboratories [kokkos/mdspan], see [kokkos/mdspan#302].
at()
to
std::mdspan
.