1a8cf78c7SLouis Dionne //===----------------------------------------------------------------------===// 2a8cf78c7SLouis Dionne // 3a8cf78c7SLouis Dionne // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4a8cf78c7SLouis Dionne // See https://llvm.org/LICENSE.txt for license information. 5a8cf78c7SLouis Dionne // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6a8cf78c7SLouis Dionne // 7a8cf78c7SLouis Dionne //===----------------------------------------------------------------------===// 8a8cf78c7SLouis Dionne // UNSUPPORTED: c++03, c++11, c++14, c++17 9a8cf78c7SLouis Dionne 10a8cf78c7SLouis Dionne // <span> 11a8cf78c7SLouis Dionne 12a8cf78c7SLouis Dionne // template<size_t N> 13a8cf78c7SLouis Dionne // constexpr span(element_type (&arr)[N]) noexcept; 14a8cf78c7SLouis Dionne // 15a8cf78c7SLouis Dionne // Remarks: These constructors shall not participate in overload resolution unless: 16355e0ce3SLouis Dionne // - extent == dynamic_extent || N == extent is true, and 17355e0ce3SLouis Dionne // - remove_pointer_t<decltype(data(arr))>(*)[] is convertible to ElementType(*)[]. 18a8cf78c7SLouis Dionne // 19a8cf78c7SLouis Dionne 20a8cf78c7SLouis Dionne #include <cassert> 21dc71a77dSLouis Dionne #include <span> 22a8cf78c7SLouis Dionne #include <string> 23dc71a77dSLouis Dionne #include <type_traits> 24a8cf78c7SLouis Dionne 25a8cf78c7SLouis Dionne #include "test_macros.h" 26a8cf78c7SLouis Dionne 27a8cf78c7SLouis Dionne 28a8cf78c7SLouis Dionne void checkCV() 29a8cf78c7SLouis Dionne { 30a8cf78c7SLouis Dionne int arr[] = {1,2,3}; 31a8cf78c7SLouis Dionne const int carr[] = {4,5,6}; 32a8cf78c7SLouis Dionne volatile int varr[] = {7,8,9}; 33a8cf78c7SLouis Dionne const volatile int cvarr[] = {1,3,5}; 34a8cf78c7SLouis Dionne 35a8cf78c7SLouis Dionne // Types the same (dynamic sized) 36a8cf78c7SLouis Dionne { 37a8cf78c7SLouis Dionne std::span< int> s1{ arr}; // a span< int> pointing at int. 38a8cf78c7SLouis Dionne std::span<const int> s2{ carr}; // a span<const int> pointing at const int. 39a8cf78c7SLouis Dionne std::span< volatile int> s3{ varr}; // a span< volatile int> pointing at volatile int. 40a8cf78c7SLouis Dionne std::span<const volatile int> s4{cvarr}; // a span<const volatile int> pointing at const volatile int. 41a8cf78c7SLouis Dionne assert(s1.size() + s2.size() + s3.size() + s4.size() == 12); 42a8cf78c7SLouis Dionne } 43a8cf78c7SLouis Dionne 44a8cf78c7SLouis Dionne // Types the same (static sized) 45a8cf78c7SLouis Dionne { 46a8cf78c7SLouis Dionne std::span< int,3> s1{ arr}; // a span< int> pointing at int. 47a8cf78c7SLouis Dionne std::span<const int,3> s2{ carr}; // a span<const int> pointing at const int. 48a8cf78c7SLouis Dionne std::span< volatile int,3> s3{ varr}; // a span< volatile int> pointing at volatile int. 49a8cf78c7SLouis Dionne std::span<const volatile int,3> s4{cvarr}; // a span<const volatile int> pointing at const volatile int. 50a8cf78c7SLouis Dionne assert(s1.size() + s2.size() + s3.size() + s4.size() == 12); 51a8cf78c7SLouis Dionne } 52a8cf78c7SLouis Dionne 53a8cf78c7SLouis Dionne 54a8cf78c7SLouis Dionne // types different (dynamic sized) 55a8cf78c7SLouis Dionne { 56a8cf78c7SLouis Dionne std::span<const int> s1{ arr}; // a span<const int> pointing at int. 57a8cf78c7SLouis Dionne std::span< volatile int> s2{ arr}; // a span< volatile int> pointing at int. 58a8cf78c7SLouis Dionne std::span< volatile int> s3{ arr}; // a span< volatile int> pointing at const int. 59a8cf78c7SLouis Dionne std::span<const volatile int> s4{ arr}; // a span<const volatile int> pointing at int. 60a8cf78c7SLouis Dionne std::span<const volatile int> s5{carr}; // a span<const volatile int> pointing at const int. 61a8cf78c7SLouis Dionne std::span<const volatile int> s6{varr}; // a span<const volatile int> pointing at volatile int. 62a8cf78c7SLouis Dionne assert(s1.size() + s2.size() + s3.size() + s4.size() + s5.size() + s6.size() == 18); 63a8cf78c7SLouis Dionne } 64a8cf78c7SLouis Dionne 65a8cf78c7SLouis Dionne // types different (static sized) 66a8cf78c7SLouis Dionne { 67a8cf78c7SLouis Dionne std::span<const int,3> s1{ arr}; // a span<const int> pointing at int. 68a8cf78c7SLouis Dionne std::span< volatile int,3> s2{ arr}; // a span< volatile int> pointing at int. 69a8cf78c7SLouis Dionne std::span< volatile int,3> s3{ arr}; // a span< volatile int> pointing at const int. 70a8cf78c7SLouis Dionne std::span<const volatile int,3> s4{ arr}; // a span<const volatile int> pointing at int. 71a8cf78c7SLouis Dionne std::span<const volatile int,3> s5{carr}; // a span<const volatile int> pointing at const int. 72a8cf78c7SLouis Dionne std::span<const volatile int,3> s6{varr}; // a span<const volatile int> pointing at volatile int. 73a8cf78c7SLouis Dionne assert(s1.size() + s2.size() + s3.size() + s4.size() + s5.size() + s6.size() == 18); 74a8cf78c7SLouis Dionne } 75a8cf78c7SLouis Dionne } 76a8cf78c7SLouis Dionne 77a8cf78c7SLouis Dionne template<class T> 78a8cf78c7SLouis Dionne constexpr bool testSpan() 79a8cf78c7SLouis Dionne { 80a8cf78c7SLouis Dionne T val[2] = {}; 81a8cf78c7SLouis Dionne 82a8cf78c7SLouis Dionne ASSERT_NOEXCEPT(std::span<T>{val}); 83a8cf78c7SLouis Dionne ASSERT_NOEXCEPT(std::span<T, 2>{val}); 84a8cf78c7SLouis Dionne ASSERT_NOEXCEPT(std::span<const T>{val}); 85a8cf78c7SLouis Dionne ASSERT_NOEXCEPT(std::span<const T, 2>{val}); 86a8cf78c7SLouis Dionne 87a8cf78c7SLouis Dionne std::span<T> s1 = val; 88a8cf78c7SLouis Dionne std::span<T, 2> s2 = val; 89a8cf78c7SLouis Dionne std::span<const T> s3 = val; 90a8cf78c7SLouis Dionne std::span<const T, 2> s4 = val; 91a8cf78c7SLouis Dionne assert(s1.data() == val && s1.size() == 2); 92a8cf78c7SLouis Dionne assert(s2.data() == val && s2.size() == 2); 93a8cf78c7SLouis Dionne assert(s3.data() == val && s3.size() == 2); 94a8cf78c7SLouis Dionne assert(s4.data() == val && s4.size() == 2); 95a8cf78c7SLouis Dionne 96*7f845cbaSNikolas Klauser TEST_DIAGNOSTIC_PUSH 97*7f845cbaSNikolas Klauser TEST_CLANG_DIAGNOSTIC_IGNORED("-Wdangling") 98a8cf78c7SLouis Dionne std::span<const int> s5 = {{1, 2}}; 99dbbeee6bSHristo Hristov #if TEST_STD_VER >= 26 100dbbeee6bSHristo Hristov std::span<const int, 2> s6({1, 2}); 101dbbeee6bSHristo Hristov #else 102a8cf78c7SLouis Dionne std::span<const int, 2> s6 = {{1,2}}; 103dbbeee6bSHristo Hristov #endif 104a8cf78c7SLouis Dionne assert(s5.size() == 2); // and it dangles 105a8cf78c7SLouis Dionne assert(s6.size() == 2); // and it dangles 106*7f845cbaSNikolas Klauser TEST_DIAGNOSTIC_POP 107a8cf78c7SLouis Dionne 108a8cf78c7SLouis Dionne return true; 109a8cf78c7SLouis Dionne } 110a8cf78c7SLouis Dionne 111a8cf78c7SLouis Dionne 112a8cf78c7SLouis Dionne struct A {}; 113a8cf78c7SLouis Dionne 114a8cf78c7SLouis Dionne int main(int, char**) 115a8cf78c7SLouis Dionne { 116a8cf78c7SLouis Dionne testSpan<int>(); 117a8cf78c7SLouis Dionne testSpan<double>(); 118a8cf78c7SLouis Dionne testSpan<A>(); 119a8cf78c7SLouis Dionne testSpan<std::string>(); 120a8cf78c7SLouis Dionne 121a8cf78c7SLouis Dionne static_assert(testSpan<int>()); 122a8cf78c7SLouis Dionne static_assert(testSpan<double>()); 123a8cf78c7SLouis Dionne static_assert(testSpan<A>()); 124a8cf78c7SLouis Dionne 125a8cf78c7SLouis Dionne checkCV(); 126a8cf78c7SLouis Dionne 127dc71a77dSLouis Dionne // Size wrong 128dc71a77dSLouis Dionne { 129dc71a77dSLouis Dionne static_assert(!std::is_constructible<std::span<int, 2>, int (&)[3]>::value, ""); 130dc71a77dSLouis Dionne } 131dc71a77dSLouis Dionne 132dc71a77dSLouis Dionne // Type wrong 133dc71a77dSLouis Dionne { 134dc71a77dSLouis Dionne static_assert(!std::is_constructible<std::span<float>, int (&)[3]>::value, ""); 135dc71a77dSLouis Dionne static_assert(!std::is_constructible<std::span<float, 3>, int (&)[3]>::value, ""); 136dc71a77dSLouis Dionne } 137dc71a77dSLouis Dionne 138dc71a77dSLouis Dionne // CV wrong (dynamically sized) 139dc71a77dSLouis Dionne { 140dc71a77dSLouis Dionne static_assert(!std::is_constructible<std::span<int>, const int (&)[3]>::value, ""); 141dc71a77dSLouis Dionne static_assert(!std::is_constructible<std::span<int>, volatile int (&)[3]>::value, ""); 142dc71a77dSLouis Dionne static_assert(!std::is_constructible<std::span<int>, const volatile int (&)[3]>::value, ""); 143dc71a77dSLouis Dionne 144dc71a77dSLouis Dionne static_assert(!std::is_constructible<std::span<const int>, volatile int (&)[3]>::value, ""); 145dc71a77dSLouis Dionne static_assert(!std::is_constructible<std::span<const int>, const volatile int (&)[3]>::value, ""); 146dc71a77dSLouis Dionne 147dc71a77dSLouis Dionne static_assert(!std::is_constructible<std::span<volatile int>, const int (&)[3]>::value, ""); 148dc71a77dSLouis Dionne static_assert(!std::is_constructible<std::span<volatile int>, const volatile int (&)[3]>::value, ""); 149dc71a77dSLouis Dionne } 150dc71a77dSLouis Dionne 151dc71a77dSLouis Dionne // CV wrong (statically sized) 152dc71a77dSLouis Dionne { 153dc71a77dSLouis Dionne static_assert(!std::is_constructible<std::span<int, 3>, const int (&)[3]>::value, ""); 154dc71a77dSLouis Dionne static_assert(!std::is_constructible<std::span<int, 3>, volatile int (&)[3]>::value, ""); 155dc71a77dSLouis Dionne static_assert(!std::is_constructible<std::span<int, 3>, const volatile int (&)[3]>::value, ""); 156dc71a77dSLouis Dionne 157dc71a77dSLouis Dionne static_assert(!std::is_constructible<std::span<const int, 3>, volatile int (&)[3]>::value, ""); 158dc71a77dSLouis Dionne static_assert(!std::is_constructible<std::span<const int, 3>, const volatile int (&)[3]>::value, ""); 159dc71a77dSLouis Dionne 160dc71a77dSLouis Dionne static_assert(!std::is_constructible<std::span<volatile int, 3>, const int (&)[3]>::value, ""); 161dc71a77dSLouis Dionne static_assert(!std::is_constructible<std::span<volatile int, 3>, const volatile int (&)[3]>::value, ""); 162dc71a77dSLouis Dionne } 163dc71a77dSLouis Dionne 164a8cf78c7SLouis Dionne return 0; 165a8cf78c7SLouis Dionne } 166