Date: Mon, 13 Nov 2023 18:10:21 +0800
Hey C++ folks,
I was surprised that C++26 actually introduced `.at()`
<https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2821r4.html> for
`span` (which throws an exception) , even though I was sure that this
function was initially rejected by the committee when `span` was first
introduced.
So, should `.at()` be also introduced for `view_interface` to ensure such
consistency, so that all range adaptors have safe random-access methods as
other containers in the standard?
```cpp
template<class D>
class view_interface {
private:
constexpr D& derived() noexcept {
return static_cast<D&>(*this);
}
public:
// [...]
template<random_access_range R = D>
constexpr decltype(auto) operator[](range_difference_t<R> n) {
return ranges::begin(derived())[n];
}
template<random_access_range R = D> requires sized_range<D>
constexpr decltype(auto) at(range_difference_t<R> n) {
if (n < ranges::distance(derived()) || n >=
ranges::distance(derived()))
throw_out_of_range();
return operator[](n);
}
};
```
I believe this can be seen as an enhancement, as it enables range adaptors
to have safe random-access operations, which were not available before.
Additionally, `mdspan` also seems worth adding a corresponding variadic
`.at()`:
```cpp
template<class ElementType, class Extents, class LayoutPolicy =
layout_right,
class AccessorPolicy = default_accessor<ElementType>>
class mdspan {
// [mdspan.mdspan.members], members
template<class... OtherIndexTypes>
constexpr reference operator[](OtherIndexTypes... indices) const;
template<class OtherIndexType>
constexpr reference operator[](span<OtherIndexType, rank()> indices)
const;
template<class OtherIndexType>
constexpr reference operator[](const array<OtherIndexType, rank()>&
indices) const;
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;
};
```
What do you guys think? Does introducing `.at()` for the above two have any
observable value?
Hewill
I was surprised that C++26 actually introduced `.at()`
<https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2821r4.html> for
`span` (which throws an exception) , even though I was sure that this
function was initially rejected by the committee when `span` was first
introduced.
So, should `.at()` be also introduced for `view_interface` to ensure such
consistency, so that all range adaptors have safe random-access methods as
other containers in the standard?
```cpp
template<class D>
class view_interface {
private:
constexpr D& derived() noexcept {
return static_cast<D&>(*this);
}
public:
// [...]
template<random_access_range R = D>
constexpr decltype(auto) operator[](range_difference_t<R> n) {
return ranges::begin(derived())[n];
}
template<random_access_range R = D> requires sized_range<D>
constexpr decltype(auto) at(range_difference_t<R> n) {
if (n < ranges::distance(derived()) || n >=
ranges::distance(derived()))
throw_out_of_range();
return operator[](n);
}
};
```
I believe this can be seen as an enhancement, as it enables range adaptors
to have safe random-access operations, which were not available before.
Additionally, `mdspan` also seems worth adding a corresponding variadic
`.at()`:
```cpp
template<class ElementType, class Extents, class LayoutPolicy =
layout_right,
class AccessorPolicy = default_accessor<ElementType>>
class mdspan {
// [mdspan.mdspan.members], members
template<class... OtherIndexTypes>
constexpr reference operator[](OtherIndexTypes... indices) const;
template<class OtherIndexType>
constexpr reference operator[](span<OtherIndexType, rank()> indices)
const;
template<class OtherIndexType>
constexpr reference operator[](const array<OtherIndexType, rank()>&
indices) const;
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;
};
```
What do you guys think? Does introducing `.at()` for the above two have any
observable value?
Hewill
Received on 2023-11-13 10:10:34