Skip to content

Commit 38bf684

Browse files
authored
[libc++] Add missing noexcept to span constructor (llvm#94381)
Thanks to Marshall Clow for noticing. Fixes llvm#94364
1 parent ce8bb9b commit 38bf684

File tree

2 files changed

+76
-72
lines changed

2 files changed

+76
-72
lines changed

libcxx/include/span

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,8 @@ public:
294294
}
295295

296296
template <__span_array_convertible<element_type> _OtherElementType>
297-
_LIBCPP_HIDE_FROM_ABI constexpr span(const span<_OtherElementType, _Extent>& __other) : __data_{__other.data()} {}
297+
_LIBCPP_HIDE_FROM_ABI constexpr span(const span<_OtherElementType, _Extent>& __other) noexcept
298+
: __data_{__other.data()} {}
298299

299300
template <__span_array_convertible<element_type> _OtherElementType>
300301
_LIBCPP_HIDE_FROM_ABI constexpr explicit span(const span<_OtherElementType, dynamic_extent>& __other) noexcept

libcxx/test/std/containers/views/views.span/span.cons/span.pass.cpp

Lines changed: 74 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -16,103 +16,106 @@
1616
// Extent == dynamic_extent || Extent == OtherExtent is true, and
1717
// OtherElementType(*)[] is convertible to ElementType(*)[].
1818

19-
2019
#include <span>
2120
#include <cassert>
2221
#include <string>
2322

2423
#include "test_macros.h"
2524

26-
void checkCV()
27-
{
28-
std::span< int> sp;
29-
// std::span<const int> csp;
30-
std::span< volatile int> vsp;
31-
// std::span<const volatile int> cvsp;
25+
template <class T, class From>
26+
TEST_CONSTEXPR_CXX20 void check() {
27+
// dynamic -> dynamic
28+
{
29+
{
30+
std::span<From> from;
31+
std::span<T> span{from};
32+
ASSERT_NOEXCEPT(std::span<T>(from));
33+
assert(span.data() == nullptr);
34+
assert(span.size() == 0);
35+
}
36+
{
37+
From array[3] = {};
38+
std::span<From> from(array);
39+
std::span<T> span{from};
40+
ASSERT_NOEXCEPT(std::span<T>(from));
41+
assert(span.data() == array);
42+
assert(span.size() == 3);
43+
}
44+
}
3245

33-
std::span< int, 0> sp0;
34-
// std::span<const int, 0> csp0;
35-
std::span< volatile int, 0> vsp0;
36-
// std::span<const volatile int, 0> cvsp0;
46+
// static -> static
47+
{
48+
{
49+
std::span<From, 0> from;
50+
std::span<T, 0> span{from};
51+
ASSERT_NOEXCEPT(std::span<T, 0>(from));
52+
assert(span.data() == nullptr);
53+
assert(span.size() == 0);
54+
}
3755

38-
// dynamic -> dynamic
3956
{
40-
std::span<const int> s1{ sp}; // a span<const int> pointing at int.
41-
std::span< volatile int> s2{ sp}; // a span< volatile int> pointing at int.
42-
std::span<const volatile int> s3{ sp}; // a span<const volatile int> pointing at int.
43-
std::span<const volatile int> s4{ vsp}; // a span<const volatile int> pointing at volatile int.
44-
assert(s1.size() + s2.size() + s3.size() + s4.size() == 0);
57+
From array[3] = {};
58+
std::span<From, 3> from(array);
59+
std::span<T, 3> span{from};
60+
ASSERT_NOEXCEPT(std::span<T, 3>(from));
61+
assert(span.data() == array);
62+
assert(span.size() == 3);
4563
}
64+
}
4665

47-
// static -> static
66+
// static -> dynamic
67+
{
4868
{
49-
std::span<const int, 0> s1{ sp0}; // a span<const int> pointing at int.
50-
std::span< volatile int, 0> s2{ sp0}; // a span< volatile int> pointing at int.
51-
std::span<const volatile int, 0> s3{ sp0}; // a span<const volatile int> pointing at int.
52-
std::span<const volatile int, 0> s4{ vsp0}; // a span<const volatile int> pointing at volatile int.
53-
assert(s1.size() + s2.size() + s3.size() + s4.size() == 0);
69+
std::span<From, 0> from;
70+
std::span<T> span{from};
71+
ASSERT_NOEXCEPT(std::span<T>(from));
72+
assert(span.data() == nullptr);
73+
assert(span.size() == 0);
5474
}
5575

56-
// static -> dynamic
5776
{
58-
std::span<const int> s1{ sp0}; // a span<const int> pointing at int.
59-
std::span< volatile int> s2{ sp0}; // a span< volatile int> pointing at int.
60-
std::span<const volatile int> s3{ sp0}; // a span<const volatile int> pointing at int.
61-
std::span<const volatile int> s4{ vsp0}; // a span<const volatile int> pointing at volatile int.
62-
assert(s1.size() + s2.size() + s3.size() + s4.size() == 0);
77+
From array[3] = {};
78+
std::span<From, 3> from(array);
79+
std::span<T> span{from};
80+
ASSERT_NOEXCEPT(std::span<T>(from));
81+
assert(span.data() == array);
82+
assert(span.size() == 3);
6383
}
84+
}
6485

65-
// dynamic -> static (not allowed)
86+
// dynamic -> static (not allowed)
6687
}
6788

89+
template <class T>
90+
TEST_CONSTEXPR_CXX20 void check_cvs() {
91+
check<T, T>();
6892

69-
template <typename T>
70-
constexpr bool testConstexprSpan()
71-
{
72-
std::span<T> s0{};
73-
std::span<T, 0> s1{};
74-
std::span<T> s2(s1); // static -> dynamic
75-
ASSERT_NOEXCEPT(std::span<T> {s0});
76-
ASSERT_NOEXCEPT(std::span<T, 0>{s1});
77-
ASSERT_NOEXCEPT(std::span<T> {s1});
93+
check<T const, T>();
94+
check<T const, T const>();
7895

79-
return
80-
s1.data() == nullptr && s1.size() == 0
81-
&& s2.data() == nullptr && s2.size() == 0;
82-
}
83-
84-
85-
template <typename T>
86-
void testRuntimeSpan()
87-
{
88-
std::span<T> s0{};
89-
std::span<T, 0> s1{};
90-
std::span<T> s2(s1); // static -> dynamic
91-
ASSERT_NOEXCEPT(std::span<T> {s0});
92-
ASSERT_NOEXCEPT(std::span<T, 0>{s1});
93-
ASSERT_NOEXCEPT(std::span<T> {s1});
96+
check<T volatile, T>();
97+
check<T volatile, T volatile>();
9498

95-
assert(s1.data() == nullptr && s1.size() == 0);
96-
assert(s2.data() == nullptr && s2.size() == 0);
99+
check<T const volatile, T>();
100+
check<T const volatile, T const>();
101+
check<T const volatile, T volatile>();
102+
check<T const volatile, T const volatile>();
97103
}
98104

105+
struct A {};
99106

100-
struct A{};
101-
102-
int main(int, char**)
103-
{
104-
static_assert(testConstexprSpan<int>(), "");
105-
static_assert(testConstexprSpan<long>(), "");
106-
static_assert(testConstexprSpan<double>(), "");
107-
static_assert(testConstexprSpan<A>(), "");
108-
109-
testRuntimeSpan<int>();
110-
testRuntimeSpan<long>();
111-
testRuntimeSpan<double>();
112-
testRuntimeSpan<std::string>();
113-
testRuntimeSpan<A>();
107+
TEST_CONSTEXPR_CXX20 bool test() {
108+
check_cvs<int>();
109+
check_cvs<long>();
110+
check_cvs<double>();
111+
check_cvs<std::string>();
112+
check_cvs<A>();
113+
return true;
114+
}
114115

115-
checkCV();
116+
int main(int, char**) {
117+
static_assert(test());
118+
test();
116119

117120
return 0;
118121
}

0 commit comments

Comments
 (0)