diff options
author | Louis Dionne <ldionne.2@gmail.com> | 2024-06-05 07:21:57 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-05 10:21:57 -0400 |
commit | 38bf6840e8589ebe22e8157aee79a57d9db9393d (patch) | |
tree | 6e367e6640aed9fd737b61e5905dbe3216e48c25 | |
parent | ce8bb9b5acea9f8fb5392ae717e7d7b7683230ea (diff) | |
download | llvm-38bf6840e8589ebe22e8157aee79a57d9db9393d.zip llvm-38bf6840e8589ebe22e8157aee79a57d9db9393d.tar.gz llvm-38bf6840e8589ebe22e8157aee79a57d9db9393d.tar.bz2 |
[libc++] Add missing noexcept to span constructor (#94381)
Thanks to Marshall Clow for noticing.
Fixes #94364
-rw-r--r-- | libcxx/include/span | 3 | ||||
-rw-r--r-- | libcxx/test/std/containers/views/views.span/span.cons/span.pass.cpp | 145 |
2 files changed, 76 insertions, 72 deletions
diff --git a/libcxx/include/span b/libcxx/include/span index 0307edc..11006b7 100644 --- a/libcxx/include/span +++ b/libcxx/include/span @@ -294,7 +294,8 @@ public: } template <__span_array_convertible<element_type> _OtherElementType> - _LIBCPP_HIDE_FROM_ABI constexpr span(const span<_OtherElementType, _Extent>& __other) : __data_{__other.data()} {} + _LIBCPP_HIDE_FROM_ABI constexpr span(const span<_OtherElementType, _Extent>& __other) noexcept + : __data_{__other.data()} {} template <__span_array_convertible<element_type> _OtherElementType> _LIBCPP_HIDE_FROM_ABI constexpr explicit span(const span<_OtherElementType, dynamic_extent>& __other) noexcept diff --git a/libcxx/test/std/containers/views/views.span/span.cons/span.pass.cpp b/libcxx/test/std/containers/views/views.span/span.cons/span.pass.cpp index edf983e..a1ac0dd 100644 --- a/libcxx/test/std/containers/views/views.span/span.cons/span.pass.cpp +++ b/libcxx/test/std/containers/views/views.span/span.cons/span.pass.cpp @@ -16,103 +16,106 @@ // Extent == dynamic_extent || Extent == OtherExtent is true, and // OtherElementType(*)[] is convertible to ElementType(*)[]. - #include <span> #include <cassert> #include <string> #include "test_macros.h" -void checkCV() -{ - std::span< int> sp; -// std::span<const int> csp; - std::span< volatile int> vsp; -// std::span<const volatile int> cvsp; +template <class T, class From> +TEST_CONSTEXPR_CXX20 void check() { + // dynamic -> dynamic + { + { + std::span<From> from; + std::span<T> span{from}; + ASSERT_NOEXCEPT(std::span<T>(from)); + assert(span.data() == nullptr); + assert(span.size() == 0); + } + { + From array[3] = {}; + std::span<From> from(array); + std::span<T> span{from}; + ASSERT_NOEXCEPT(std::span<T>(from)); + assert(span.data() == array); + assert(span.size() == 3); + } + } - std::span< int, 0> sp0; -// std::span<const int, 0> csp0; - std::span< volatile int, 0> vsp0; -// std::span<const volatile int, 0> cvsp0; + // static -> static + { + { + std::span<From, 0> from; + std::span<T, 0> span{from}; + ASSERT_NOEXCEPT(std::span<T, 0>(from)); + assert(span.data() == nullptr); + assert(span.size() == 0); + } -// dynamic -> dynamic { - std::span<const int> s1{ sp}; // a span<const int> pointing at int. - std::span< volatile int> s2{ sp}; // a span< volatile int> pointing at int. - std::span<const volatile int> s3{ sp}; // a span<const volatile int> pointing at int. - std::span<const volatile int> s4{ vsp}; // a span<const volatile int> pointing at volatile int. - assert(s1.size() + s2.size() + s3.size() + s4.size() == 0); + From array[3] = {}; + std::span<From, 3> from(array); + std::span<T, 3> span{from}; + ASSERT_NOEXCEPT(std::span<T, 3>(from)); + assert(span.data() == array); + assert(span.size() == 3); } + } -// static -> static + // static -> dynamic + { { - std::span<const int, 0> s1{ sp0}; // a span<const int> pointing at int. - std::span< volatile int, 0> s2{ sp0}; // a span< volatile int> pointing at int. - std::span<const volatile int, 0> s3{ sp0}; // a span<const volatile int> pointing at int. - std::span<const volatile int, 0> s4{ vsp0}; // a span<const volatile int> pointing at volatile int. - assert(s1.size() + s2.size() + s3.size() + s4.size() == 0); + std::span<From, 0> from; + std::span<T> span{from}; + ASSERT_NOEXCEPT(std::span<T>(from)); + assert(span.data() == nullptr); + assert(span.size() == 0); } -// static -> dynamic { - std::span<const int> s1{ sp0}; // a span<const int> pointing at int. - std::span< volatile int> s2{ sp0}; // a span< volatile int> pointing at int. - std::span<const volatile int> s3{ sp0}; // a span<const volatile int> pointing at int. - std::span<const volatile int> s4{ vsp0}; // a span<const volatile int> pointing at volatile int. - assert(s1.size() + s2.size() + s3.size() + s4.size() == 0); + From array[3] = {}; + std::span<From, 3> from(array); + std::span<T> span{from}; + ASSERT_NOEXCEPT(std::span<T>(from)); + assert(span.data() == array); + assert(span.size() == 3); } + } -// dynamic -> static (not allowed) + // dynamic -> static (not allowed) } +template <class T> +TEST_CONSTEXPR_CXX20 void check_cvs() { + check<T, T>(); -template <typename T> -constexpr bool testConstexprSpan() -{ - std::span<T> s0{}; - std::span<T, 0> s1{}; - std::span<T> s2(s1); // static -> dynamic - ASSERT_NOEXCEPT(std::span<T> {s0}); - ASSERT_NOEXCEPT(std::span<T, 0>{s1}); - ASSERT_NOEXCEPT(std::span<T> {s1}); + check<T const, T>(); + check<T const, T const>(); - return - s1.data() == nullptr && s1.size() == 0 - && s2.data() == nullptr && s2.size() == 0; -} - - -template <typename T> -void testRuntimeSpan() -{ - std::span<T> s0{}; - std::span<T, 0> s1{}; - std::span<T> s2(s1); // static -> dynamic - ASSERT_NOEXCEPT(std::span<T> {s0}); - ASSERT_NOEXCEPT(std::span<T, 0>{s1}); - ASSERT_NOEXCEPT(std::span<T> {s1}); + check<T volatile, T>(); + check<T volatile, T volatile>(); - assert(s1.data() == nullptr && s1.size() == 0); - assert(s2.data() == nullptr && s2.size() == 0); + check<T const volatile, T>(); + check<T const volatile, T const>(); + check<T const volatile, T volatile>(); + check<T const volatile, T const volatile>(); } +struct A {}; -struct A{}; - -int main(int, char**) -{ - static_assert(testConstexprSpan<int>(), ""); - static_assert(testConstexprSpan<long>(), ""); - static_assert(testConstexprSpan<double>(), ""); - static_assert(testConstexprSpan<A>(), ""); - - testRuntimeSpan<int>(); - testRuntimeSpan<long>(); - testRuntimeSpan<double>(); - testRuntimeSpan<std::string>(); - testRuntimeSpan<A>(); +TEST_CONSTEXPR_CXX20 bool test() { + check_cvs<int>(); + check_cvs<long>(); + check_cvs<double>(); + check_cvs<std::string>(); + check_cvs<A>(); + return true; +} - checkCV(); +int main(int, char**) { + static_assert(test()); + test(); return 0; } |