[libcxx-commits] [libcxx] [libc++] Add missing noexcept to span constructor (PR #94381)

via libcxx-commits libcxx-commits at lists.llvm.org
Tue Jun 4 09:57:47 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libcxx

Author: Louis Dionne (ldionne)

<details>
<summary>Changes</summary>

Thanks to Marshal Clow for noticing.
Fixes #<!-- -->94364

---
Full diff: https://github.com/llvm/llvm-project/pull/94381.diff


2 Files Affected:

- (modified) libcxx/include/span (+2-1) 
- (modified) libcxx/test/std/containers/views/views.span/span.cons/span.pass.cpp (+74-71) 


``````````diff
diff --git a/libcxx/include/span b/libcxx/include/span
index 0307edcb55c30..11006b74fbb58 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 edf983ec3e243..a1ac0dd11b2d1 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;
 }

``````````

</details>


https://github.com/llvm/llvm-project/pull/94381


More information about the libcxx-commits mailing list