span.pass.cpp (5121B)
1 // -*- C++ -*- 2 //===------------------------------ span ---------------------------------===// 3 // 4 // The LLVM Compiler Infrastructure 5 // 6 // This file is dual licensed under the MIT and the University of Illinois Open 7 // Source Licenses. See LICENSE.TXT for details. 8 // 9 //===---------------------------------------------------------------------===// 10 // UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 11 12 // <span> 13 14 // template<class OtherElementType, ptrdiff_t OtherExtent> 15 // constexpr span(const span<OtherElementType, OtherExtent>& s) noexcept; 16 // 17 // Remarks: This constructor shall not participate in overload resolution unless: 18 // Extent == dynamic_extent || Extent == OtherExtent is true, and 19 // OtherElementType(*)[] is convertible to ElementType(*)[]. 20 21 22 #include <span> 23 #include <cassert> 24 #include <string> 25 26 #include "test_macros.h" 27 28 void checkCV() 29 { 30 std::span< int> sp; 31 // std::span<const int> csp; 32 std::span< volatile int> vsp; 33 // std::span<const volatile int> cvsp; 34 35 std::span< int, 0> sp0; 36 // std::span<const int, 0> csp0; 37 std::span< volatile int, 0> vsp0; 38 // std::span<const volatile int, 0> cvsp0; 39 40 // dynamic -> dynamic 41 { 42 std::span<const int> s1{ sp}; // a span<const int> pointing at int. 43 std::span< volatile int> s2{ sp}; // a span< volatile int> pointing at int. 44 std::span<const volatile int> s3{ sp}; // a span<const volatile int> pointing at int. 45 std::span<const volatile int> s4{ vsp}; // a span<const volatile int> pointing at volatile int. 46 assert(s1.size() + s2.size() + s3.size() + s4.size() == 0); 47 } 48 49 // static -> static 50 { 51 std::span<const int, 0> s1{ sp0}; // a span<const int> pointing at int. 52 std::span< volatile int, 0> s2{ sp0}; // a span< volatile int> pointing at int. 53 std::span<const volatile int, 0> s3{ sp0}; // a span<const volatile int> pointing at int. 54 std::span<const volatile int, 0> s4{ vsp0}; // a span<const volatile int> pointing at volatile int. 55 assert(s1.size() + s2.size() + s3.size() + s4.size() == 0); 56 } 57 58 // static -> dynamic 59 { 60 std::span<const int> s1{ sp0}; // a span<const int> pointing at int. 61 std::span< volatile int> s2{ sp0}; // a span< volatile int> pointing at int. 62 std::span<const volatile int> s3{ sp0}; // a span<const volatile int> pointing at int. 63 std::span<const volatile int> s4{ vsp0}; // a span<const volatile int> pointing at volatile int. 64 assert(s1.size() + s2.size() + s3.size() + s4.size() == 0); 65 } 66 67 // dynamic -> static 68 { 69 std::span<const int, 0> s1{ sp}; // a span<const int> pointing at int. 70 std::span< volatile int, 0> s2{ sp}; // a span< volatile int> pointing at int. 71 std::span<const volatile int, 0> s3{ sp}; // a span<const volatile int> pointing at int. 72 std::span<const volatile int, 0> s4{ vsp}; // a span<const volatile int> pointing at volatile int. 73 assert(s1.size() + s2.size() + s3.size() + s4.size() == 0); 74 } 75 } 76 77 78 template <typename T> 79 constexpr bool testConstexprSpan() 80 { 81 std::span<T> s0{}; 82 std::span<T, 0> s1(s0); // dynamic -> static 83 std::span<T> s2(s1); // static -> dynamic 84 ASSERT_NOEXCEPT(std::span<T> {s0}); 85 ASSERT_NOEXCEPT(std::span<T, 0>{s1}); 86 ASSERT_NOEXCEPT(std::span<T> {s1}); 87 ASSERT_NOEXCEPT(std::span<T, 0>{s0}); 88 89 return 90 s1.data() == nullptr && s1.size() == 0 91 && s2.data() == nullptr && s2.size() == 0; 92 } 93 94 95 template <typename T> 96 void testRuntimeSpan() 97 { 98 std::span<T> s0{}; 99 std::span<T, 0> s1(s0); // dynamic -> static 100 std::span<T> s2(s1); // static -> dynamic 101 ASSERT_NOEXCEPT(std::span<T> {s0}); 102 ASSERT_NOEXCEPT(std::span<T, 0>{s1}); 103 ASSERT_NOEXCEPT(std::span<T> {s1}); 104 ASSERT_NOEXCEPT(std::span<T, 0>{s0}); 105 106 assert(s1.data() == nullptr && s1.size() == 0); 107 assert(s2.data() == nullptr && s2.size() == 0); 108 } 109 110 111 template <typename Dest, typename Src> 112 bool testConversionSpan() 113 { 114 static_assert(std::is_convertible_v<Src(*)[], Dest(*)[]>, "Bad input types to 'testConversionSpan"); 115 std::span<Src> s0d{}; 116 std::span<Src> s0s{}; 117 std::span<Dest, 0> s1(s0d); // dynamic -> static 118 std::span<Dest> s2(s0s); // static -> dynamic 119 s1.data() == nullptr && s1.size() == 0 120 && s2.data() == nullptr && s2.size() == 0; 121 } 122 123 struct A{}; 124 125 int main () 126 { 127 static_assert(testConstexprSpan<int>(), ""); 128 static_assert(testConstexprSpan<long>(), ""); 129 static_assert(testConstexprSpan<double>(), ""); 130 static_assert(testConstexprSpan<A>(), ""); 131 132 testRuntimeSpan<int>(); 133 testRuntimeSpan<long>(); 134 testRuntimeSpan<double>(); 135 testRuntimeSpan<std::string>(); 136 testRuntimeSpan<A>(); 137 138 // TODO: Add some conversion tests here that aren't "X --> const X" 139 // assert((testConversionSpan<unsigned char, char>())); 140 141 checkCV(); 142 }