Document #: | P3383R2 |
Date: | 2025-02-22 |
Project: | Programming Language C++ |
Audience: |
Library Working Group (LWG) |
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.
operator[]
and rebase on top of latest draftUpdate wording to align with [P2821R5]:
__cpp_lib_mdspan
instead of
adding __cpp_lib_mdspan_at
at()
as
freestanding deleted and adjust freestanding comments of header and
classInitial version
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 [P2821R5], 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 [N5001].
In 23.7.3.2 ([mdspan.syn]), change the following lines:
- // all freestanding
+ // mostly freestanding
namespace std {
// 23.7.3.6, class template mdspan
template<class ElementType, class Extents, class LayoutPolicy = layout_right,
class AccessorPolicy = default_accessor<ElementType>>- class mdspan;
+ class mdspan; // partially freestanding
In 23.7.3.6.1 ([mdspan.mdspan.overview]), add the following immediately after the subscript operators:
template<class... OtherIndexTypes> constexpr reference at(OtherIndexTypes... indices) const; // freestanding-deleted template<class OtherIndexType> constexpr reference at(span<OtherIndexType, rank()> indices) const; // freestanding-deleted template<class OtherIndexType> constexpr reference at(const array<OtherIndexType, rank()>& indices) const; // freestanding-deleted
In 23.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 Let
I
beextents_type::
index_cast
(std::move(indices))
.10 Throws:
out_of_range
ifI
is not a multidimensional index inextents()
.template<class OtherIndexType> constexpr reference at(span<OtherIndexType, rank()> indices) const;
template<class OtherIndexType> constexpr reference at(const array<OtherIndexType, rank()>& indices) const;
11 Constraints:
- (11.1)
is_convertible_v<const OtherIndexType&, index_type>
istrue
, and- (11.2)
is_nothrow_constructible_v<index_type, const OtherIndexType&>
istrue
.12 Effects: Let
P
be a parameter pack such thatis_same_v<make_index_sequence<rank()>, index_sequence<P...>>
istrue
. Equivalent to:return at(extents_type::
index-cast
(as_const(indices[P]))...);
LEWG decided to drop the bump of the feature test macro.
Remove the feature test macro bump from P3383R1
SF
|
F
|
N
|
A
|
SA
|
---|---|---|---|---|
4 | 4 | 4 | 2 | 0 |
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
.