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<size_t N> 13 // constexpr span(array<value_type, N>& arr) noexcept; 14 // template<size_t N> 15 // constexpr span(const array<value_type, N>& arr) noexcept; 16 // 17 // Remarks: These constructors shall not participate in overload resolution unless: 18 // — extent == dynamic_extent || N == extent is true, and 19 // — remove_pointer_t<decltype(data(arr))>(*)[] is convertible to ElementType(*)[]. 20 // 21 22 23 #include <span> 24 #include <array> 25 #include <cassert> 26 #include <string> 27 28 #include "test_macros.h" 29 30 void checkCV() 31 { 32 std::array<int, 3> arr = {1,2,3}; 33 // STL says these are not cromulent 34 // std::array<const int,3> carr = {4,5,6}; 35 // std::array<volatile int, 3> varr = {7,8,9}; 36 // std::array<const volatile int, 3> cvarr = {1,3,5}; 37 38 // Types the same (dynamic sized) 39 { 40 std::span< int> s1{ arr}; // a span< int> pointing at int. 41 } 42 43 // Types the same (static sized) 44 { 45 std::span< int,3> s1{ arr}; // a span< int> pointing at int. 46 } 47 48 49 // types different (dynamic sized) 50 { 51 std::span<const int> s1{ arr}; // a span<const int> pointing at int. 52 std::span< volatile int> s2{ arr}; // a span< volatile int> pointing at int. 53 std::span< volatile int> s3{ arr}; // a span< volatile int> pointing at const int. 54 std::span<const volatile int> s4{ arr}; // a span<const volatile int> pointing at int. 55 } 56 57 // types different (static sized) 58 { 59 std::span<const int,3> s1{ arr}; // a span<const int> pointing at int. 60 std::span< volatile int,3> s2{ arr}; // a span< volatile int> pointing at int. 61 std::span< volatile int,3> s3{ arr}; // a span< volatile int> pointing at const int. 62 std::span<const volatile int,3> s4{ arr}; // a span<const volatile int> pointing at int. 63 } 64 } 65 66 template <typename T, typename U> 67 constexpr bool testConstructorArray() { 68 std::array<U, 2> val = {U(), U()}; 69 ASSERT_NOEXCEPT(std::span<T>{val}); 70 ASSERT_NOEXCEPT(std::span<T, 2>{val}); 71 std::span<T> s1{val}; 72 std::span<T, 2> s2{val}; 73 return s1.data() == &val[0] && s1.size() == 2 && s2.data() == &val[0] && 74 s2.size() == 2; 75 } 76 77 template <typename T, typename U> 78 constexpr bool testConstructorConstArray() { 79 const std::array<U, 2> val = {U(), U()}; 80 ASSERT_NOEXCEPT(std::span<const T>{val}); 81 ASSERT_NOEXCEPT(std::span<const T, 2>{val}); 82 std::span<const T> s1{val}; 83 std::span<const T, 2> s2{val}; 84 return s1.data() == &val[0] && s1.size() == 2 && s2.data() == &val[0] && 85 s2.size() == 2; 86 } 87 88 template <typename T> 89 constexpr bool testConstructors() { 90 static_assert(testConstructorArray<T, T>(), ""); 91 static_assert(testConstructorArray<const T, const T>(), ""); 92 static_assert(testConstructorArray<const T, T>(), ""); 93 static_assert(testConstructorConstArray<T, T>(), ""); 94 static_assert(testConstructorConstArray<const T, const T>(), ""); 95 static_assert(testConstructorConstArray<const T, T>(), ""); 96 97 return testConstructorArray<T, T>() && 98 testConstructorArray<const T, const T>() && 99 testConstructorArray<const T, T>() && 100 testConstructorConstArray<T, T>() && 101 testConstructorConstArray<const T, const T>() && 102 testConstructorConstArray<const T, T>(); 103 } 104 105 struct A{}; 106 107 int main(int, char**) 108 { 109 assert(testConstructors<int>()); 110 assert(testConstructors<long>()); 111 assert(testConstructors<double>()); 112 assert(testConstructors<A>()); 113 114 assert(testConstructors<int*>()); 115 assert(testConstructors<const int*>()); 116 117 checkCV(); 118 119 return 0; 120 } 121