diff --git a/libcxx/include/span b/libcxx/include/span --- a/libcxx/include/span +++ b/libcxx/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& __arr) noexcept : __data{__arr.data()} {} - _LIBCPP_INLINE_VISIBILITY constexpr span(const array& __arr) noexcept : __data{__arr.data()} {} + + template , nullptr_t> = nullptr> + _LIBCPP_INLINE_VISIBILITY + constexpr span(array<_OtherElementType, _Extent>& __arr) noexcept : __data{__arr.data()} {} + + template , nullptr_t> = nullptr> + _LIBCPP_INLINE_VISIBILITY + constexpr span(const array<_OtherElementType, _Extent>& __arr) noexcept : __data{__arr.data()} {} template _LIBCPP_INLINE_VISIBILITY @@ -386,13 +394,15 @@ _LIBCPP_INLINE_VISIBILITY constexpr span(element_type (&__arr)[_Sz]) noexcept : __data{__arr}, __size{_Sz} {} - template + template , nullptr_t> = nullptr> _LIBCPP_INLINE_VISIBILITY - constexpr span(array& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {} + constexpr span(array<_OtherElementType, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {} - template + template , nullptr_t> = nullptr> _LIBCPP_INLINE_VISIBILITY - constexpr span(const array& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {} + constexpr span(const array<_OtherElementType, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {} template _LIBCPP_INLINE_VISIBILITY diff --git a/libcxx/test/std/containers/views/span.cons/stdarray.pass.cpp b/libcxx/test/std/containers/views/span.cons/stdarray.pass.cpp --- a/libcxx/test/std/containers/views/span.cons/stdarray.pass.cpp +++ b/libcxx/test/std/containers/views/span.cons/stdarray.pass.cpp @@ -68,49 +68,58 @@ } } +template +constexpr bool testConstructorArray() +{ + std::array val = { U(), U() }; + ASSERT_NOEXCEPT(std::span {val}); + ASSERT_NOEXCEPT(std::span{val}); + std::span s1{val}; + std::span s2{val}; + return s1.data() == &val[0] && s1.size() == 2 + && s2.data() == &val[0] && s2.size() == 2; +} -template -constexpr bool testConstexprSpan() +template +constexpr bool testConstructorConstArray() { - constexpr std::array val = { T(), T() }; + const std::array val = { U(), U() }; ASSERT_NOEXCEPT(std::span {val}); ASSERT_NOEXCEPT(std::span{val}); std::span s1{val}; std::span s2{val}; - return - s1.data() == &val[0] && s1.size() == 2 - && s2.data() == &val[0] && s2.size() == 2; + return s1.data() == &val[0] && s1.size() == 2 + && s2.data() == &val[0] && s2.size() == 2; } - template -void testRuntimeSpan() -{ - std::array val; - ASSERT_NOEXCEPT(std::span {val}); - ASSERT_NOEXCEPT(std::span{val}); - std::span s1{val}; - std::span s2{val}; - assert(s1.data() == &val[0] && s1.size() == 2); - assert(s2.data() == &val[0] && s2.size() == 2); +constexpr bool testConstructors() { + static_assert(testConstructorArray(), ""); + static_assert(testConstructorArray(), ""); + static_assert(testConstructorConstArray(), ""); + static_assert(testConstructorConstArray(), ""); + + return testConstructorArray() + && testConstructorArray() + && testConstructorConstArray() + && testConstructorConstArray(); } struct A{}; int main(int, char**) { - static_assert(testConstexprSpan(), ""); - static_assert(testConstexprSpan(), ""); - static_assert(testConstexprSpan(), ""); - static_assert(testConstexprSpan(), ""); + assert(testConstructors()); + assert(testConstructors()); + assert(testConstructors()); + assert(testConstructors()); - testRuntimeSpan(); - testRuntimeSpan(); - testRuntimeSpan(); - testRuntimeSpan(); - testRuntimeSpan(); + assert(testConstructors()); + assert(testConstructors()); + assert(testConstructors()); + assert(testConstructors()); checkCV(); - return 0; + return 0; } diff --git a/libcxx/www/cxx2a_status.html b/libcxx/www/cxx2a_status.html --- a/libcxx/www/cxx2a_status.html +++ b/libcxx/www/cxx2a_status.html @@ -490,7 +490,7 @@ 3251Are std::format alignment specifiers applied to string arguments?Prague 3252Parse locale's aware modifiers for commands are not consistent with POSIX specPrague 3254Strike stop_token's operator!=Prague - 3255span's array constructor is too strictPrague + 3255span's array constructor is too strictPragueComplete 3260year_month* arithmetic rejects durations convertible to yearsPrague 3262Formatting of negative durations is not specifiedPrague 3264sized_range and ranges::size redundantly use disable_sized_rangePrague