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 <list> 31 #include <forward_list> 32 #include <deque> 33 34 #include "test_macros.h" 35 36 // Look ma - I'm a container! 37 template <typename T> 38 struct IsAContainer { 39 constexpr IsAContainer() : v_{} {} 40 constexpr size_t size() const {return 1;} 41 constexpr T *data() {return &v_;} 42 constexpr const T *data() const {return &v_;} 43 44 constexpr const T *getV() const {return &v_;} // for checking 45 T v_; 46 }; 47 48 template <typename T> 49 struct NotAContainerNoData { 50 size_t size() const {return 0;} 51 }; 52 53 template <typename T> 54 struct NotAContainerNoSize { 55 const T *data() const {return nullptr;} 56 }; 57 58 template <typename T> 59 struct NotAContainerPrivate { 60 private: 61 size_t size() const {return 0;} 62 const T *data() const {return nullptr;} 63 }; 64 65 66 int main () 67 { 68 69 // Missing size and/or data 70 { 71 std::span<int> s1{IsAContainer<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}} 72 std::span<int, 0> s2{IsAContainer<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int, 0>'}} 73 std::span<int> s3{NotAContainerNoData<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}} 74 std::span<int, 0> s4{NotAContainerNoData<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int, 0>'}} 75 std::span<int> s5{NotAContainerNoSize<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}} 76 std::span<int, 0> s6{NotAContainerNoSize<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int, 0>'}} 77 std::span<int> s7{NotAContainerPrivate<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}} 78 std::span<int, 0> s8{NotAContainerPrivate<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int, 0>'}} 79 80 // Again with the standard containers 81 std::span<int> s11{std::deque<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}} 82 std::span<int, 0> s12{std::deque<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int, 0>'}} 83 std::span<int> s13{std::list<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}} 84 std::span<int, 0> s14{std::list<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int, 0>'}} 85 std::span<int> s15{std::forward_list<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}} 86 std::span<int, 0> s16{std::forward_list<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int, 0>'}} 87 } 88 89 // Not the same type 90 { 91 std::span<float> s1{IsAContainer<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<float>'}} 92 std::span<float, 0> s2{IsAContainer<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<float, 0>'}} 93 } 94 95 // CV wrong (dynamically sized) 96 { 97 std::span< int> s1{IsAContainer<const int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}} 98 std::span< int> s2{IsAContainer< volatile int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}} 99 std::span< int> s3{IsAContainer<const volatile int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}} 100 std::span<const int> s4{IsAContainer< volatile int>()}; // expected-error {{no matching constructor for initialization of 'std::span<const int>'}} 101 std::span<const int> s5{IsAContainer<const volatile int>()}; // expected-error {{no matching constructor for initialization of 'std::span<const int>'}} 102 std::span< volatile int> s6{IsAContainer<const int>()}; // expected-error {{no matching constructor for initialization of 'std::span<volatile int>'}} 103 std::span< volatile int> s7{IsAContainer<const volatile int>()}; // expected-error {{no matching constructor for initialization of 'std::span<volatile int>'}} 104 } 105 106 // CV wrong (statically sized) 107 { 108 std::span< int,1> s1{IsAContainer<const int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int, 1>'}} 109 std::span< int,1> s2{IsAContainer< volatile int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int, 1>'}} 110 std::span< int,1> s3{IsAContainer<const volatile int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int, 1>'}} 111 std::span<const int,1> s4{IsAContainer< volatile int>()}; // expected-error {{no matching constructor for initialization of 'std::span<const int, 1>'}} 112 std::span<const int,1> s5{IsAContainer<const volatile int>()}; // expected-error {{no matching constructor for initialization of 'std::span<const int, 1>'}} 113 std::span< volatile int,1> s6{IsAContainer<const int>()}; // expected-error {{no matching constructor for initialization of 'std::span<volatile int, 1>'}} 114 std::span< volatile int,1> s7{IsAContainer<const volatile int>()}; // expected-error {{no matching constructor for initialization of 'std::span<volatile int, 1>'}} 115 } 116 117 } 118