[libcxx][span] Implement solution to LWG-3255

This implements the relaxed requirements on the std::array constructors of span,
where the type only needs to be convertible to the element type of the span.

Note that the previous tests were not sufficient, as the const array<T, n> constructor
was only tested for compile time and the array<T, N> only during runtime.

Restructure the tests so that we can test conversions as well as both constructors.

Differential Revision: https://reviews.llvm.org/D75706

Cr-Mirrored-From: https://chromium.googlesource.com/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: ab9f11168f55add345f29592ec0946ac2e5ae697
diff --git a/include/span b/include/span
index 1851ff3..7ae0bdb 100644
--- a/include/span
+++ b/include/span
@@ -212,8 +212,16 @@
         { (void)__l;     _LIBCPP_ASSERT(_Extent == distance(__f, __l), "size mismatch in span's constructor (ptr, ptr)"); }
 
     _LIBCPP_INLINE_VISIBILITY constexpr span(element_type (&__arr)[_Extent])          noexcept : __data{__arr} {}
-    _LIBCPP_INLINE_VISIBILITY constexpr span(      array<value_type, _Extent>& __arr) noexcept : __data{__arr.data()} {}
-    _LIBCPP_INLINE_VISIBILITY constexpr span(const array<value_type, _Extent>& __arr) noexcept : __data{__arr.data()} {}
+
+    template <class _OtherElementType,
+              enable_if_t<is_convertible_v<_OtherElementType(*)[], element_type (*)[]>, nullptr_t> = nullptr>
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr span(array<_OtherElementType, _Extent>& __arr) noexcept : __data{__arr.data()} {}
+
+    template <class _OtherElementType,
+              enable_if_t<is_convertible_v<const _OtherElementType(*)[], element_type (*)[]>, nullptr_t> = nullptr>
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr span(const array<_OtherElementType, _Extent>& __arr) noexcept : __data{__arr.data()} {}
 
     template <class _Container>
     _LIBCPP_INLINE_VISIBILITY
@@ -386,13 +394,15 @@
     _LIBCPP_INLINE_VISIBILITY
     constexpr span(element_type (&__arr)[_Sz])          noexcept : __data{__arr}, __size{_Sz} {}
 
-    template <size_t _Sz>
+    template <class _OtherElementType, size_t _Sz,
+              enable_if_t<is_convertible_v<_OtherElementType(*)[], element_type (*)[]>, nullptr_t> = nullptr>
     _LIBCPP_INLINE_VISIBILITY
-    constexpr span(array<value_type, _Sz>& __arr)       noexcept : __data{__arr.data()}, __size{_Sz} {}
+    constexpr span(array<_OtherElementType, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {}
 
-    template <size_t _Sz>
+    template <class _OtherElementType, size_t _Sz,
+              enable_if_t<is_convertible_v<const _OtherElementType(*)[], element_type (*)[]>, nullptr_t> = nullptr>
     _LIBCPP_INLINE_VISIBILITY
-    constexpr span(const array<value_type, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {}
+    constexpr span(const array<_OtherElementType, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {}
 
     template <class _Container>
     _LIBCPP_INLINE_VISIBILITY