Skip to content

Commit

Permalink
[370] - Did you know that C++26 added span.at?
Browse files Browse the repository at this point in the history
  • Loading branch information
kris-jusiak committed Apr 1, 2024
1 parent f4fd31f commit fb693d1
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

> C++26
* [Did you know that C++26 added `span.at`?](https://github.com/tip-of-the-week/cpp/blob/master/tips/370.md)
* [Did you know about C++26 simd proposal (1/N)?](https://github.com/tip-of-the-week/cpp/blob/master/tips/367.md)
* [Did you know about C++26 static reflection proposal (1/N)?](https://github.com/tip-of-the-week/cpp/blob/master/tips/361.md)
* [Did you know about C++26 static reflection proposal (2/N)?](https://github.com/tip-of-the-week/cpp/blob/master/tips/362.md)
Expand Down
74 changes: 74 additions & 0 deletions tips/370.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<details open><summary>Info</summary><p>

* **Did you know that C++26 added `span.at`?

* https://wg21.link/P2821

</p></details><details open><summary>Example</summary><p>

```cpp
std::array<int, 42> storage{};
const auto span = std::span(storage);
(void)span.at(0); // okay
(void)span.at(storage.size()); // throws
```

> https://godbolt.org/z/ezvMvraW1
</p></details><details open><summary>Puzzle</summary><p>

* **Can you implement `span_at` which will use `[]` if `fn` is noexcept and `at` otherwise?

```cpp
struct span_at; // TODO

int main() {
using namespace boost::ut;

std::array<int, 42> storage{};
for (auto i = 0; i < storage.size(); ++i) { storage[i] = i; }

"span[index]"_test = [&] {
span_at t{storage};
expect(0_i == t([](auto i) noexcept(true) { return i; }, 0));
expect(2_i == t([](auto i) noexcept(true) { return i; }, 2));
expect(41_i == t([](auto i) noexcept(true) { return i; }, 41));
// expect(not throws([&] { (void)t([](auto i) noexcept(true) { return i; }, 42); }));
};

"span.at"_test = [&] {
span_at t{storage};
expect(0_i == t([](auto i) noexcept(false) { return i; }, 0));
expect(2_i == t([](auto i) noexcept(false) { return i; }, 2));
expect(41_i == t([](auto i) noexcept(false) { return i; }, 41));
expect(throws([&] { (void)t([](auto i) noexcept(false) { return i; }, 42); }));
};
}
```

> https://godbolt.org/z/oTxo9aaz4
</p></details>

</p></details><details><summary>Solutions</summary><p>

```cpp
struct span_at {
constexpr explicit span_at(std::span<const int> span) : span_{span} { }

[[nodiscard]] constexpr auto operator()(auto&& fn, auto index) {
if constexpr(noexcept(fn(span_[index]))) {
return fn(span_[index]);
} else {
return fn(span_.at(index));
}
}

private:
std::span<const int> span_{};
};
```
> https://godbolt.org/z/hcnWjWodM
</p></details>

0 comments on commit fb693d1

Please sign in to comment.