Index: libcxx/include/span =================================================================== --- libcxx/include/span +++ libcxx/include/span @@ -232,15 +232,6 @@ nullptr_t> = nullptr) : __data{__other.data()} {} - template - _LIBCPP_INLINE_VISIBILITY - constexpr span(const span<_OtherElementType, dynamic_extent>& __other, - enable_if_t< - is_convertible_v<_OtherElementType(*)[], element_type (*)[]>, - nullptr_t> = nullptr) noexcept - : __data{__other.data()} { _LIBCPP_ASSERT(_Extent == __other.size(), "size mismatch in span's constructor (other span)"); } - - // ~span() noexcept = default; template Index: libcxx/test/std/containers/views/span.cons/span.fail.cpp =================================================================== --- libcxx/test/std/containers/views/span.cons/span.fail.cpp +++ libcxx/test/std/containers/views/span.cons/span.fail.cpp @@ -74,18 +74,34 @@ std::span< volatile int> s6{ csp0}; // expected-error {{no matching constructor for initialization of 'std::span'}} std::span< volatile int> s7{cvsp0}; // expected-error {{no matching constructor for initialization of 'std::span'}} } +} -// Try to remove const and/or volatile (static -> static) +void checkExtent () +{ + std::span spd; + std::span sp0; + std::span sp1{nullptr, 1}; + std::span sp2{nullptr, 2}; + +// Try to construct static span with extent 0 from span with different extent { - std::span< int, 0> s1{ csp}; // expected-error {{no matching constructor for initialization of 'std::span'}} - std::span< int, 0> s2{ vsp}; // expected-error {{no matching constructor for initialization of 'std::span'}} - std::span< int, 0> s3{cvsp}; // expected-error {{no matching constructor for initialization of 'std::span'}} + std::span s1{spd}; // expected-error {{no matching constructor for initialization of 'std::span'}} + std::span s2{sp1}; // expected-error {{no matching constructor for initialization of 'std::span'}} + std::span s3{sp2}; // expected-error {{no matching constructor for initialization of 'std::span'}} + } - std::span s4{ vsp}; // expected-error {{no matching constructor for initialization of 'std::span'}} - std::span s5{cvsp}; // expected-error {{no matching constructor for initialization of 'std::span'}} +// Try to construct static span with extent 1 from span with different extent + { + std::span s1{spd}; // expected-error {{no matching constructor for initialization of 'std::span'}} + std::span s2{sp0}; // expected-error {{no matching constructor for initialization of 'std::span'}} + std::span s3{sp2}; // expected-error {{no matching constructor for initialization of 'std::span'}} + } - std::span< volatile int, 0> s6{ csp}; // expected-error {{no matching constructor for initialization of 'std::span'}} - std::span< volatile int, 0> s7{cvsp}; // expected-error {{no matching constructor for initialization of 'std::span'}} +// Try to construct static span with extent 2 from span with different extent + { + std::span s1{spd}; // expected-error {{no matching constructor for initialization of 'std::span'}} + std::span s2{sp0}; // expected-error {{no matching constructor for initialization of 'std::span'}} + std::span s3{sp1}; // expected-error {{no matching constructor for initialization of 'std::span'}} } } @@ -100,6 +116,7 @@ std::span s4{sp0}; // expected-error {{no matching constructor for initialization of 'std::span'}} checkCV(); + checkExtent(); return 0; } Index: libcxx/test/std/containers/views/span.cons/span.pass.cpp =================================================================== --- libcxx/test/std/containers/views/span.cons/span.pass.cpp +++ libcxx/test/std/containers/views/span.cons/span.pass.cpp @@ -62,48 +62,42 @@ std::span s4{ vsp0}; // a span pointing at volatile int. assert(s1.size() + s2.size() + s3.size() + s4.size() == 0); } - -// dynamic -> static - { - std::span s1{ sp}; // a span pointing at int. - std::span< volatile int, 0> s2{ sp}; // a span< volatile int> pointing at int. - std::span s3{ sp}; // a span pointing at int. - std::span s4{ vsp}; // a span pointing at volatile int. - assert(s1.size() + s2.size() + s3.size() + s4.size() == 0); - } } template constexpr bool testConstexprSpan() { - std::span s0{}; - std::span s1(s0); // dynamic -> static - std::span s2(s1); // static -> dynamic - ASSERT_NOEXCEPT(std::span {s0}); - ASSERT_NOEXCEPT(std::span{s1}); - ASSERT_NOEXCEPT(std::span {s1}); - ASSERT_NOEXCEPT(std::span{s0}); - - return - s1.data() == nullptr && s1.size() == 0 - && s2.data() == nullptr && s2.size() == 0; + std::span s0d{}; + std::span s0s{}; + std::span s1(s0d); // dynamic -> dynamic + std::span s2(s0s); // static -> static + std::span s3(s2); // static -> dynamic + ASSERT_NOEXCEPT(std::span{s0d}); + ASSERT_NOEXCEPT(std::span{s0s}); + ASSERT_NOEXCEPT(std::span{s0s}); + + return s1.data() == nullptr && s1.size() == 0 + && s2.data() == nullptr && s2.size() == 0 + && s3.data() == nullptr && s3.size() == 0; } template void testRuntimeSpan() { - std::span s0{}; - std::span s1(s0); // dynamic -> static - std::span s2(s1); // static -> dynamic - ASSERT_NOEXCEPT(std::span {s0}); - ASSERT_NOEXCEPT(std::span{s1}); - ASSERT_NOEXCEPT(std::span {s1}); - ASSERT_NOEXCEPT(std::span{s0}); - - assert(s1.data() == nullptr && s1.size() == 0); - assert(s2.data() == nullptr && s2.size() == 0); + std::span s0d{}; + std::span s0s{}; + std::span s1(s0d); // dynamic -> dynamic + std::span s2(s0s); // static -> static + std::span s3(s2); // static -> dynamic + ASSERT_NOEXCEPT(std::span{s0d}); + ASSERT_NOEXCEPT(std::span{s0s}); + ASSERT_NOEXCEPT(std::span{s0s}); + + assert(s1.data() == nullptr && s1.size() == 0); + assert(s2.data() == nullptr && s2.size() == 0); + assert(s3.data() == nullptr && s3.size() == 0); } @@ -112,11 +106,13 @@ { static_assert(std::is_convertible_v, "Bad input types to 'testConversionSpan"); std::span s0d{}; - std::span s0s{}; - std::span s1(s0d); // dynamic -> static - std::span s2(s0s); // static -> dynamic - s1.data() == nullptr && s1.size() == 0 - && s2.data() == nullptr && s2.size() == 0; + std::span s0s{}; + std::span s1(s0d); // dynamic -> dynamic + std::span s2(s0s); // static -> static + std::span s3(s0d); // static -> dynamic + return s1.data() == nullptr && s1.size() == 0 + && s2.data() == nullptr && s2.size() == 0 + && s3.data() == nullptr && s3.size() == 0; } struct A{};