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

source code of libcxx/test/std/containers/views/views.span/span.cons/array.pass.cpp