Skip to content

Commit 9ddcd1b

Browse files
committed
[libc++] Use static_asserts for span::front() and span::back() when possible
1 parent cb4433b commit 9ddcd1b

File tree

5 files changed

+88
-28
lines changed

5 files changed

+88
-28
lines changed

libcxx/include/span

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -367,12 +367,12 @@ public:
367367
# endif
368368

369369
_LIBCPP_HIDE_FROM_ABI constexpr reference front() const noexcept {
370-
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T, N>::front() on empty span");
370+
static_assert(_Extent >= 1, "span<T, N>::front() on empty span");
371371
return __data_[0];
372372
}
373373

374374
_LIBCPP_HIDE_FROM_ABI constexpr reference back() const noexcept {
375-
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T, N>::back() on empty span");
375+
static_assert(_Extent >= 1, "span<T, N>::back() on empty span");
376376
return __data_[size() - 1];
377377
}
378378

libcxx/test/libcxx/containers/views/views.span/span.elem/assert.back.pass.cpp

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66
//
77
//===----------------------------------------------------------------------===//
8+
89
// UNSUPPORTED: c++03, c++11, c++14, c++17
910

1011
// <span>
@@ -23,17 +24,13 @@
2324
#include "check_assertion.h"
2425

2526
int main(int, char**) {
26-
{
27-
std::array<int, 3> array{0, 1, 2};
28-
std::span<int> const s(array.data(), 0);
29-
TEST_LIBCPP_ASSERT_FAILURE(s.back(), "span<T>::back() on empty span");
30-
}
31-
32-
{
33-
std::array<int, 3> array{0, 1, 2};
34-
std::span<int, 0> const s(array.data(), 0);
35-
TEST_LIBCPP_ASSERT_FAILURE(s.back(), "span<T, N>::back() on empty span");
36-
}
37-
38-
return 0;
27+
{
28+
std::array<int, 3> array{0, 1, 2};
29+
std::span<int> const s(array.data(), 0);
30+
TEST_LIBCPP_ASSERT_FAILURE(s.back(), "span<T>::back() on empty span");
31+
}
32+
33+
// back() on a span with a static extent is caught statically and tested in front.verify.cpp
34+
35+
return 0;
3936
}

libcxx/test/libcxx/containers/views/views.span/span.elem/assert.front.pass.cpp

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66
//
77
//===----------------------------------------------------------------------===//
8+
89
// UNSUPPORTED: c++03, c++11, c++14, c++17
910

1011
// <span>
@@ -23,17 +24,13 @@
2324
#include "check_assertion.h"
2425

2526
int main(int, char**) {
26-
{
27-
std::array<int, 3> array{0, 1, 2};
28-
std::span<int> const s(array.data(), 0);
29-
TEST_LIBCPP_ASSERT_FAILURE(s.front(), "span<T>::front() on empty span");
30-
}
31-
32-
{
33-
std::array<int, 3> array{0, 1, 2};
34-
std::span<int, 0> const s(array.data(), 0);
35-
TEST_LIBCPP_ASSERT_FAILURE(s.front(), "span<T, N>::front() on empty span");
36-
}
37-
38-
return 0;
27+
{
28+
std::array<int, 3> array{0, 1, 2};
29+
std::span<int> const s(array.data(), 0);
30+
TEST_LIBCPP_ASSERT_FAILURE(s.front(), "span<T>::front() on empty span");
31+
}
32+
33+
// front() on a span with a static extent is caught statically and tested in front.verify.cpp
34+
35+
return 0;
3936
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// UNSUPPORTED: c++03, c++11, c++14, c++17
10+
11+
// <span>
12+
//
13+
// constexpr reference back() const noexcept;
14+
15+
// Make sure that accessing a statically-sized span out-of-bounds triggers a
16+
// compile-time error.
17+
18+
#include <array>
19+
#include <span>
20+
21+
int main(int, char**) {
22+
std::array<int, 3> array{0, 1, 2};
23+
{
24+
std::span<int, 0> const s(array.data(), 0);
25+
s.back(); // expected-error@span:* {{span<T, N>::back() on empty span}}
26+
}
27+
{
28+
std::span<int, 3> const s(array.data(), 3);
29+
s.back(); // nothing
30+
}
31+
32+
return 0;
33+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// UNSUPPORTED: c++03, c++11, c++14, c++17
10+
11+
// <span>
12+
//
13+
// constexpr reference front() const noexcept;
14+
15+
// Make sure that accessing a statically-sized span out-of-bounds triggers a
16+
// compile-time error.
17+
18+
#include <array>
19+
#include <span>
20+
21+
int main(int, char**) {
22+
std::array<int, 3> array{0, 1, 2};
23+
{
24+
std::span<int, 0> const s(array.data(), 0);
25+
s.front(); // expected-error@span:* {{span<T, N>::front() on empty span}}
26+
}
27+
{
28+
std::span<int, 3> const s(array.data(), 3);
29+
s.front(); // nothing
30+
}
31+
32+
return 0;
33+
}

0 commit comments

Comments
 (0)