1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // UNSUPPORTED: c++03, c++11, c++14, c++17 9 10 // <span> 11 12 // template<class OtherElementType, size_t OtherExtent> 13 // constexpr span(const span<OtherElementType, OtherExtent>& s) noexcept; 14 // 15 // Remarks: This constructor shall not participate in overload resolution unless: 16 // Extent == dynamic_extent || Extent == OtherExtent is true, and 17 // OtherElementType(*)[] is convertible to ElementType(*)[]. 18 19 20 #include <span> 21 #include <cassert> 22 #include <string> 23 24 #include "test_macros.h" 25 26 void checkCV() 27 { 28 std::span< int> sp; 29 // std::span<const int> csp; 30 std::span< volatile int> vsp; 31 // std::span<const volatile int> cvsp; 32 33 std::span< int, 0> sp0; 34 // std::span<const int, 0> csp0; 35 std::span< volatile int, 0> vsp0; 36 // std::span<const volatile int, 0> cvsp0; 37 38 // dynamic -> dynamic 39 { 40 std::span<const int> s1{ sp}; // a span<const int> pointing at int. 41 std::span< volatile int> s2{ sp}; // a span< volatile int> pointing at int. 42 std::span<const volatile int> s3{ sp}; // a span<const volatile int> pointing at int. 43 std::span<const volatile int> s4{ vsp}; // a span<const volatile int> pointing at volatile int. 44 assert(s1.size() + s2.size() + s3.size() + s4.size() == 0); 45 } 46 47 // static -> static 48 { 49 std::span<const int, 0> s1{ sp0}; // a span<const int> pointing at int. 50 std::span< volatile int, 0> s2{ sp0}; // a span< volatile int> pointing at int. 51 std::span<const volatile int, 0> s3{ sp0}; // a span<const volatile int> pointing at int. 52 std::span<const volatile int, 0> s4{ vsp0}; // a span<const volatile int> pointing at volatile int. 53 assert(s1.size() + s2.size() + s3.size() + s4.size() == 0); 54 } 55 56 // static -> dynamic 57 { 58 std::span<const int> s1{ sp0}; // a span<const int> pointing at int. 59 std::span< volatile int> s2{ sp0}; // a span< volatile int> pointing at int. 60 std::span<const volatile int> s3{ sp0}; // a span<const volatile int> pointing at int. 61 std::span<const volatile int> s4{ vsp0}; // a span<const volatile int> pointing at volatile int. 62 assert(s1.size() + s2.size() + s3.size() + s4.size() == 0); 63 } 64 65 // dynamic -> static (not allowed) 66 } 67 68 69 template <typename T> 70 constexpr bool testConstexprSpan() 71 { 72 std::span<T> s0{}; 73 std::span<T, 0> s1{}; 74 std::span<T> s2(s1); // static -> dynamic 75 ASSERT_NOEXCEPT(std::span<T> {s0}); 76 ASSERT_NOEXCEPT(std::span<T, 0>{s1}); 77 ASSERT_NOEXCEPT(std::span<T> {s1}); 78 79 return 80 s1.data() == nullptr && s1.size() == 0 81 && s2.data() == nullptr && s2.size() == 0; 82 } 83 84 85 template <typename T> 86 void testRuntimeSpan() 87 { 88 std::span<T> s0{}; 89 std::span<T, 0> s1{}; 90 std::span<T> s2(s1); // static -> dynamic 91 ASSERT_NOEXCEPT(std::span<T> {s0}); 92 ASSERT_NOEXCEPT(std::span<T, 0>{s1}); 93 ASSERT_NOEXCEPT(std::span<T> {s1}); 94 95 assert(s1.data() == nullptr && s1.size() == 0); 96 assert(s2.data() == nullptr && s2.size() == 0); 97 } 98 99 100 struct A{}; 101 102 int main(int, char**) 103 { 104 static_assert(testConstexprSpan<int>(), ""); 105 static_assert(testConstexprSpan<long>(), ""); 106 static_assert(testConstexprSpan<double>(), ""); 107 static_assert(testConstexprSpan<A>(), ""); 108 109 testRuntimeSpan<int>(); 110 testRuntimeSpan<long>(); 111 testRuntimeSpan<double>(); 112 testRuntimeSpan<std::string>(); 113 testRuntimeSpan<A>(); 114 115 checkCV(); 116 117 return 0; 118 } 119