container.pass.cpp (3519B)
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 Container> 15 // constexpr span(Container& cont); 16 // template<class Container> 17 // constexpr span(const Container& cont); 18 // 19 // Remarks: These constructors shall not participate in overload resolution unless: 20 // — Container is not a specialization of span, 21 // — Container is not a specialization of array, 22 // — is_array_v<Container> is false, 23 // — data(cont) and size(cont) are both well-formed, and 24 // — remove_pointer_t<decltype(data(cont))>(*)[] is convertible to ElementType(*)[]. 25 // 26 27 28 #include <span> 29 #include <cassert> 30 #include <string> 31 #include <vector> 32 33 #include "test_macros.h" 34 35 // Look ma - I'm a container! 36 template <typename T> 37 struct IsAContainer { 38 constexpr IsAContainer() : v_{} {} 39 constexpr size_t size() const {return 1;} 40 constexpr T *data() {return &v_;} 41 constexpr const T *data() const {return &v_;} 42 43 constexpr T const *getV() const {return &v_;} // for checking 44 T v_; 45 }; 46 47 48 void checkCV() 49 { 50 std::vector<int> v = {1,2,3}; 51 52 // Types the same (dynamic sized) 53 { 54 std::span< int> s1{v}; // a span< int> pointing at int. 55 } 56 57 // Types the same (static sized) 58 { 59 std::span< int,3> s1{v}; // a span< int> pointing at int. 60 } 61 62 // types different (dynamic sized) 63 { 64 std::span<const int> s1{v}; // a span<const int> pointing at int. 65 std::span< volatile int> s2{v}; // a span< volatile int> pointing at int. 66 std::span< volatile int> s3{v}; // a span< volatile int> pointing at const int. 67 std::span<const volatile int> s4{v}; // a span<const volatile int> pointing at int. 68 } 69 70 // types different (static sized) 71 { 72 std::span<const int,3> s1{v}; // a span<const int> pointing at int. 73 std::span< volatile int,3> s2{v}; // a span< volatile int> pointing at int. 74 std::span< volatile int,3> s3{v}; // a span< volatile int> pointing at const int. 75 std::span<const volatile int,3> s4{v}; // a span<const volatile int> pointing at int. 76 } 77 } 78 79 80 template <typename T> 81 constexpr bool testConstexprSpan() 82 { 83 constexpr IsAContainer<const T> val{}; 84 std::span<const T> s1{val}; 85 std::span<const T, 1> s2{val}; 86 return 87 s1.data() == val.getV() && s1.size() == 1 88 && s2.data() == val.getV() && s2.size() == 1; 89 } 90 91 92 template <typename T> 93 void testRuntimeSpan() 94 { 95 IsAContainer<T> val{}; 96 std::span<const T> s1{val}; 97 std::span<const T, 1> s2{val}; 98 assert(s1.data() == val.getV() && s1.size() == 1); 99 assert(s2.data() == val.getV() && s2.size() == 1); 100 } 101 102 struct A{}; 103 104 int main () 105 { 106 static_assert(testConstexprSpan<int>(), ""); 107 static_assert(testConstexprSpan<long>(), ""); 108 static_assert(testConstexprSpan<double>(), ""); 109 static_assert(testConstexprSpan<A>(), ""); 110 111 testRuntimeSpan<int>(); 112 testRuntimeSpan<long>(); 113 testRuntimeSpan<double>(); 114 testRuntimeSpan<std::string>(); 115 testRuntimeSpan<A>(); 116 117 checkCV(); 118 }