Document #: | PxxxxR0 |
Date: | 2023-12-11 |
Project: | Programming Language C++ |
Audience: |
Library Evolution Working Group (LEWG) SG23 Safety and Security |
Reply-to: |
Stephan Lachnit <stephan.lachnit@cern.ch> |
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 [N4964].
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)
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)
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
.