diff --git a/libcxx/include/span b/libcxx/include/span index 60d76d830f0f3..da631cdc3f90e 100644 --- a/libcxx/include/span +++ b/libcxx/include/span @@ -206,10 +206,10 @@ struct __is_std_span> : true_type {}; template concept __span_compatible_range = + !__is_std_span>::value && // ranges::contiguous_range<_Range> && // ranges::sized_range<_Range> && // (ranges::borrowed_range<_Range> || is_const_v<_ElementType>) && // - !__is_std_span>::value && // !__is_std_array>::value && // !is_array_v> && // is_convertible_v> (*)[], _ElementType (*)[]>; diff --git a/libcxx/test/std/containers/views/views.span/span.cons/copy.pass.cpp b/libcxx/test/std/containers/views/views.span/span.cons/copy.pass.cpp index 28f13e122ddc5..d3990fd60a459 100644 --- a/libcxx/test/std/containers/views/views.span/span.cons/copy.pass.cpp +++ b/libcxx/test/std/containers/views/views.span/span.cons/copy.pass.cpp @@ -5,6 +5,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// + // UNSUPPORTED: c++03, c++11, c++14, c++17 // @@ -14,58 +15,101 @@ #include #include #include +#include #include "test_macros.h" -template -constexpr bool doCopy(const T &rhs) -{ - ASSERT_NOEXCEPT(T{rhs}); - T lhs{rhs}; - return lhs.data() == rhs.data() - && lhs.size() == rhs.size(); -} +template +constexpr void test() { + ASSERT_NOEXCEPT(std::span(std::declval const&>())); + ASSERT_NOEXCEPT(std::span{std::declval const&>()}); -struct A{}; - -template -void testCV () -{ - int arr[] = {1,2,3}; - assert((doCopy(std::span () ))); - assert((doCopy(std::span() ))); - assert((doCopy(std::span (&arr[0], 1)))); - assert((doCopy(std::span(&arr[0], 1)))); - assert((doCopy(std::span (&arr[0], 2)))); - assert((doCopy(std::span(&arr[0], 2)))); + // dynamic_extent + { + std::span x; + std::span copy(x); + assert(copy.data() == x.data()); + assert(copy.size() == x.size()); + } + { + T array[3] = {}; + std::span x(array, 3); + std::span copy(x); + assert(copy.data() == array); + assert(copy.size() == 3); + } + { + T array[3] = {}; + std::span x(array, 2); + std::span copy(x); + assert(copy.data() == array); + assert(copy.size() == 2); + } + + // static extent + { + std::span x; + std::span copy(x); + assert(copy.data() == x.data()); + assert(copy.size() == x.size()); + } + { + T array[3] = {}; + std::span x(array); + std::span copy(x); + assert(copy.data() == array); + assert(copy.size() == 3); + } + { + T array[2] = {}; + std::span x(array); + std::span copy(x); + assert(copy.data() == array); + assert(copy.size() == 2); + } } +struct Foo {}; + +constexpr bool test_all() { + test(); + test(); + test(); + test(); -int main(int, char**) -{ - constexpr int carr[] = {1,2,3}; + test(); + test(); + test(); + test(); - static_assert(doCopy(std::span< int> ()), ""); - static_assert(doCopy(std::span< int,0>()), ""); - static_assert(doCopy(std::span (&carr[0], 1)), ""); - static_assert(doCopy(std::span(&carr[0], 1)), ""); - static_assert(doCopy(std::span (&carr[0], 2)), ""); - static_assert(doCopy(std::span(&carr[0], 2)), ""); + test(); + test(); + test(); + test(); - static_assert(doCopy(std::span()), ""); - static_assert(doCopy(std::span()), ""); - static_assert(doCopy(std::span()), ""); + // Note: Can't test non-fundamental types with volatile because we require `T*` to be indirectly_readable, + // which isn't the case when T is volatile. + test(); + test(); - std::string s; - assert(doCopy(std::span () )); - assert(doCopy(std::span() )); - assert(doCopy(std::span (&s, 1))); - assert(doCopy(std::span(&s, 1))); + test(); + test(); + + // Regression test for https://github.com/llvm/llvm-project/issues/104496 + { + struct Incomplete; + std::span x; + std::span copy(x); + assert(copy.data() == x.data()); + assert(copy.size() == x.size()); + } + + return true; +} - testCV< int>(); - testCV(); - testCV< volatile int>(); - testCV(); +int main(int, char**) { + test_all(); + static_assert(test_all()); return 0; }