• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 //  constexpr span& operator=(const span& other) noexcept = default;
15 
16 #include <span>
17 #include <cassert>
18 #include <string>
19 #include <utility>
20 
21 #include "test_macros.h"
22 
23 template <typename T>
doAssign(T lhs,T rhs)24 constexpr bool doAssign(T lhs, T rhs)
25 {
26     ASSERT_NOEXCEPT(std::declval<T&>() = rhs);
27     lhs = rhs;
28     return lhs.data() == rhs.data()
29      &&    lhs.size() == rhs.size();
30 }
31 
32 struct A{};
33 
34 constexpr int carr1[] = {1,2,3,4};
35 constexpr int carr2[] = {3,4,5};
36 constexpr int carr3[] = {7,8};
37           int   arr[] = {5,6,7,9};
38 std::string strs[] = {"ABC", "DEF", "GHI"};
39 
40 
main()41 int main ()
42 {
43 
44 //  constexpr dynamically sized assignment
45     {
46 //  On systems where 'ptrdiff_t' is a synonym for 'int',
47 //  the call span(ptr, 0) selects the (pointer, index_type) constructor.
48 //  On systems where 'ptrdiff_t' is NOT a synonym for 'int',
49 //  it is ambiguous, because of 0 also being convertible to a null pointer
50 //  and so the compiler can't choose between:
51 //      span(pointer, index_type)
52 //  and span(pointer, pointer)
53 //  We cast zero to std::ptrdiff_t to remove that ambiguity.
54 //  Example:
55 //      On darwin x86_64, ptrdiff_t is the same as long int.
56 //      On darwin i386, ptrdiff_t is the same as int.
57         constexpr std::span<const int> spans[] = {
58             {},
59             {carr1, static_cast<std::ptrdiff_t>(0)},
60             {carr1,     1},
61             {carr1,     2},
62             {carr1,     3},
63             {carr1,     4},
64             {carr2, static_cast<std::ptrdiff_t>(0)},
65             {carr2,     1},
66             {carr2,     2},
67             {carr2,     3},
68             {carr3, static_cast<std::ptrdiff_t>(0)},
69             {carr3,     1},
70             {carr3,     2}
71             };
72 
73         static_assert(std::size(spans) == 13, "" );
74 
75 //  No for loops in constexpr land :-(
76         static_assert(doAssign(spans[0], spans[0]), "");
77         static_assert(doAssign(spans[0], spans[1]), "");
78         static_assert(doAssign(spans[0], spans[2]), "");
79         static_assert(doAssign(spans[0], spans[3]), "");
80         static_assert(doAssign(spans[0], spans[4]), "");
81         static_assert(doAssign(spans[0], spans[5]), "");
82         static_assert(doAssign(spans[0], spans[6]), "");
83         static_assert(doAssign(spans[0], spans[7]), "");
84         static_assert(doAssign(spans[0], spans[8]), "");
85         static_assert(doAssign(spans[0], spans[9]), "");
86         static_assert(doAssign(spans[0], spans[10]), "");
87         static_assert(doAssign(spans[0], spans[11]), "");
88         static_assert(doAssign(spans[0], spans[12]), "");
89 
90         static_assert(doAssign(spans[1], spans[1]), "");
91         static_assert(doAssign(spans[1], spans[2]), "");
92         static_assert(doAssign(spans[1], spans[3]), "");
93         static_assert(doAssign(spans[1], spans[4]), "");
94         static_assert(doAssign(spans[1], spans[5]), "");
95         static_assert(doAssign(spans[1], spans[6]), "");
96         static_assert(doAssign(spans[1], spans[7]), "");
97         static_assert(doAssign(spans[1], spans[8]), "");
98         static_assert(doAssign(spans[1], spans[9]), "");
99         static_assert(doAssign(spans[1], spans[10]), "");
100         static_assert(doAssign(spans[1], spans[11]), "");
101         static_assert(doAssign(spans[1], spans[12]), "");
102 
103         static_assert(doAssign(spans[2], spans[2]), "");
104         static_assert(doAssign(spans[2], spans[3]), "");
105         static_assert(doAssign(spans[2], spans[4]), "");
106         static_assert(doAssign(spans[2], spans[5]), "");
107         static_assert(doAssign(spans[2], spans[6]), "");
108         static_assert(doAssign(spans[2], spans[7]), "");
109         static_assert(doAssign(spans[2], spans[8]), "");
110         static_assert(doAssign(spans[2], spans[9]), "");
111         static_assert(doAssign(spans[2], spans[10]), "");
112         static_assert(doAssign(spans[2], spans[11]), "");
113         static_assert(doAssign(spans[2], spans[12]), "");
114 
115         static_assert(doAssign(spans[3], spans[3]), "");
116         static_assert(doAssign(spans[3], spans[4]), "");
117         static_assert(doAssign(spans[3], spans[4]), "");
118         static_assert(doAssign(spans[3], spans[4]), "");
119         static_assert(doAssign(spans[3], spans[4]), "");
120         static_assert(doAssign(spans[3], spans[4]), "");
121         static_assert(doAssign(spans[3], spans[4]), "");
122         static_assert(doAssign(spans[3], spans[4]), "");
123         static_assert(doAssign(spans[3], spans[4]), "");
124         static_assert(doAssign(spans[3], spans[10]), "");
125         static_assert(doAssign(spans[3], spans[11]), "");
126         static_assert(doAssign(spans[3], spans[12]), "");
127 
128         static_assert(doAssign(spans[4], spans[4]), "");
129         static_assert(doAssign(spans[4], spans[5]), "");
130         static_assert(doAssign(spans[4], spans[6]), "");
131         static_assert(doAssign(spans[4], spans[7]), "");
132         static_assert(doAssign(spans[4], spans[8]), "");
133         static_assert(doAssign(spans[4], spans[9]), "");
134         static_assert(doAssign(spans[4], spans[10]), "");
135         static_assert(doAssign(spans[4], spans[11]), "");
136         static_assert(doAssign(spans[4], spans[12]), "");
137 
138         static_assert(doAssign(spans[5], spans[5]), "");
139         static_assert(doAssign(spans[5], spans[6]), "");
140         static_assert(doAssign(spans[5], spans[7]), "");
141         static_assert(doAssign(spans[5], spans[8]), "");
142         static_assert(doAssign(spans[5], spans[9]), "");
143         static_assert(doAssign(spans[5], spans[10]), "");
144         static_assert(doAssign(spans[5], spans[11]), "");
145         static_assert(doAssign(spans[5], spans[12]), "");
146 
147         static_assert(doAssign(spans[6], spans[6]), "");
148         static_assert(doAssign(spans[6], spans[7]), "");
149         static_assert(doAssign(spans[6], spans[8]), "");
150         static_assert(doAssign(spans[6], spans[9]), "");
151         static_assert(doAssign(spans[6], spans[10]), "");
152         static_assert(doAssign(spans[6], spans[11]), "");
153         static_assert(doAssign(spans[6], spans[12]), "");
154 
155         static_assert(doAssign(spans[7], spans[7]), "");
156         static_assert(doAssign(spans[7], spans[8]), "");
157         static_assert(doAssign(spans[7], spans[9]), "");
158         static_assert(doAssign(spans[7], spans[10]), "");
159         static_assert(doAssign(spans[7], spans[11]), "");
160         static_assert(doAssign(spans[7], spans[12]), "");
161 
162         static_assert(doAssign(spans[8], spans[8]), "");
163         static_assert(doAssign(spans[8], spans[9]), "");
164         static_assert(doAssign(spans[8], spans[10]), "");
165         static_assert(doAssign(spans[8], spans[11]), "");
166         static_assert(doAssign(spans[8], spans[12]), "");
167 
168         static_assert(doAssign(spans[9], spans[9]), "");
169         static_assert(doAssign(spans[9], spans[10]), "");
170         static_assert(doAssign(spans[9], spans[11]), "");
171         static_assert(doAssign(spans[9], spans[12]), "");
172 
173         static_assert(doAssign(spans[10], spans[10]), "");
174         static_assert(doAssign(spans[10], spans[11]), "");
175         static_assert(doAssign(spans[10], spans[12]), "");
176 
177         static_assert(doAssign(spans[11], spans[11]), "");
178         static_assert(doAssign(spans[11], spans[12]), "");
179 
180         static_assert(doAssign(spans[12], spans[12]), "");
181 
182 //      for (size_t i = 0; i < std::size(spans); ++i)
183 //          for (size_t j = i; j < std::size(spans); ++j)
184 //              static_assert(doAssign(spans[i], spans[j]), "");
185     }
186 
187 //  constexpr statically sized assignment
188     {
189         constexpr std::span<const int,2> spans[] = {
190             {carr1, 2},
191             {carr1 + 1, 2},
192             {carr1 + 2, 2},
193             {carr2, 2},
194             {carr2 + 1, 2},
195             {carr3, 2}
196             };
197 
198         static_assert(std::size(spans) == 6, "" );
199 
200 //  No for loops in constexpr land :-(
201         static_assert(doAssign(spans[0], spans[0]), "");
202         static_assert(doAssign(spans[0], spans[1]), "");
203         static_assert(doAssign(spans[0], spans[2]), "");
204         static_assert(doAssign(spans[0], spans[3]), "");
205         static_assert(doAssign(spans[0], spans[4]), "");
206         static_assert(doAssign(spans[0], spans[5]), "");
207 
208         static_assert(doAssign(spans[1], spans[1]), "");
209         static_assert(doAssign(spans[1], spans[2]), "");
210         static_assert(doAssign(spans[1], spans[3]), "");
211         static_assert(doAssign(spans[1], spans[4]), "");
212         static_assert(doAssign(spans[1], spans[5]), "");
213 
214         static_assert(doAssign(spans[2], spans[2]), "");
215         static_assert(doAssign(spans[2], spans[3]), "");
216         static_assert(doAssign(spans[2], spans[4]), "");
217         static_assert(doAssign(spans[2], spans[5]), "");
218 
219         static_assert(doAssign(spans[3], spans[3]), "");
220         static_assert(doAssign(spans[3], spans[4]), "");
221         static_assert(doAssign(spans[3], spans[5]), "");
222 
223         static_assert(doAssign(spans[4], spans[4]), "");
224         static_assert(doAssign(spans[4], spans[5]), "");
225 
226         static_assert(doAssign(spans[5], spans[5]), "");
227 
228 //      for (size_t i = 0; i < std::size(spans); ++i)
229 //          for (size_t j = i; j < std::size(spans); ++j)
230 //              static_assert(doAssign(spans[i], spans[j]), "");
231     }
232 
233 
234 //  dynamically sized assignment
235     {
236         std::span<int> spans[] = {
237             {},
238             {arr,     arr + 1},
239             {arr,     arr + 2},
240             {arr,     arr + 3},
241             {arr + 1, arr + 3} // same size as s2
242             };
243 
244         for (size_t i = 0; i < std::size(spans); ++i)
245             for (size_t j = i; j < std::size(spans); ++j)
246                 assert((doAssign(spans[i], spans[j])));
247     }
248 
249 //  statically sized assignment
250     {
251         std::span<int,2> spans[] = {
252             {arr,     arr + 2},
253             {arr + 1, arr + 3},
254             {arr + 2, arr + 4}
255             };
256 
257         for (size_t i = 0; i < std::size(spans); ++i)
258             for (size_t j = i; j < std::size(spans); ++j)
259                 assert((doAssign(spans[i], spans[j])));
260     }
261 
262 //  dynamically sized assignment
263     {
264     std::span<std::string> spans[] = {
265             {strs,     strs},
266             {strs,     strs + 1},
267             {strs,     strs + 2},
268             {strs,     strs + 3},
269             {strs + 1, strs + 1},
270             {strs + 1, strs + 2},
271             {strs + 1, strs + 3},
272             {strs + 2, strs + 2},
273             {strs + 2, strs + 3},
274             {strs + 3, strs + 3}
275             };
276 
277         for (size_t i = 0; i < std::size(spans); ++i)
278             for (size_t j = i; j < std::size(spans); ++j)
279                 assert((doAssign(spans[i], spans[j])));
280     }
281 
282     {
283     std::span<std::string, 1> spans[] = {
284             {strs,     strs + 1},
285             {strs + 1, strs + 2},
286             {strs + 2, strs + 3}
287             };
288 
289         for (size_t i = 0; i < std::size(spans); ++i)
290             for (size_t j = i; j < std::size(spans); ++j)
291                 assert((doAssign(spans[i], spans[j])));
292     }
293 }
294