• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // -*- C++ -*-
2 //===------------------------------ span ---------------------------------===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===---------------------------------------------------------------------===//
9 // UNSUPPORTED: c++03, c++11, c++14, c++17
10 
11 // <span>
12 
13 //  constexpr span& operator=(const span& other) noexcept = default;
14 
15 #include <span>
16 #include <cassert>
17 #include <string>
18 #include <utility>
19 
20 #include "test_macros.h"
21 
22 template <typename T>
doAssign(T lhs,T rhs)23 constexpr bool doAssign(T lhs, T rhs)
24 {
25     ASSERT_NOEXCEPT(std::declval<T&>() = rhs);
26     lhs = rhs;
27     return lhs.data() == rhs.data()
28      &&    lhs.size() == rhs.size();
29 }
30 
31 struct A{};
32 
33 constexpr int carr1[] = {1,2,3,4};
34 constexpr int carr2[] = {3,4,5};
35 constexpr int carr3[] = {7,8};
36           int   arr[] = {5,6,7,9};
37 std::string strs[] = {"ABC", "DEF", "GHI"};
38 
39 
main(int,char **)40 int main(int, char**)
41 {
42 
43 //  constexpr dynamically sized assignment
44     {
45 //  On systems where 'ptrdiff_t' is a synonym for 'int',
46 //  the call span(ptr, 0) selects the (pointer, size_type) constructor.
47 //  On systems where 'ptrdiff_t' is NOT a synonym for 'int',
48 //  it is ambiguous, because of 0 also being convertible to a null pointer
49 //  and so the compiler can't choose between:
50 //      span(pointer, size_type)
51 //  and span(pointer, pointer)
52 //  We cast zero to std::ptrdiff_t to remove that ambiguity.
53 //  Example:
54 //      On darwin x86_64, ptrdiff_t is the same as long int.
55 //      On darwin i386, ptrdiff_t is the same as int.
56         constexpr std::span<const int> spans[] = {
57             {},
58             {carr1, static_cast<std::size_t>(0)},
59             {carr1,     1U},
60             {carr1,     2U},
61             {carr1,     3U},
62             {carr1,     4U},
63             {carr2, static_cast<std::size_t>(0)},
64             {carr2,     1U},
65             {carr2,     2U},
66             {carr2,     3U},
67             {carr3, static_cast<std::size_t>(0)},
68             {carr3,     1U},
69             {carr3,     2U}
70             };
71 
72         static_assert(std::size(spans) == 13, "" );
73 
74 //  No for loops in constexpr land :-(
75         static_assert(doAssign(spans[0], spans[0]), "");
76         static_assert(doAssign(spans[0], spans[1]), "");
77         static_assert(doAssign(spans[0], spans[2]), "");
78         static_assert(doAssign(spans[0], spans[3]), "");
79         static_assert(doAssign(spans[0], spans[4]), "");
80         static_assert(doAssign(spans[0], spans[5]), "");
81         static_assert(doAssign(spans[0], spans[6]), "");
82         static_assert(doAssign(spans[0], spans[7]), "");
83         static_assert(doAssign(spans[0], spans[8]), "");
84         static_assert(doAssign(spans[0], spans[9]), "");
85         static_assert(doAssign(spans[0], spans[10]), "");
86         static_assert(doAssign(spans[0], spans[11]), "");
87         static_assert(doAssign(spans[0], spans[12]), "");
88 
89         static_assert(doAssign(spans[1], spans[1]), "");
90         static_assert(doAssign(spans[1], spans[2]), "");
91         static_assert(doAssign(spans[1], spans[3]), "");
92         static_assert(doAssign(spans[1], spans[4]), "");
93         static_assert(doAssign(spans[1], spans[5]), "");
94         static_assert(doAssign(spans[1], spans[6]), "");
95         static_assert(doAssign(spans[1], spans[7]), "");
96         static_assert(doAssign(spans[1], spans[8]), "");
97         static_assert(doAssign(spans[1], spans[9]), "");
98         static_assert(doAssign(spans[1], spans[10]), "");
99         static_assert(doAssign(spans[1], spans[11]), "");
100         static_assert(doAssign(spans[1], spans[12]), "");
101 
102         static_assert(doAssign(spans[2], spans[2]), "");
103         static_assert(doAssign(spans[2], spans[3]), "");
104         static_assert(doAssign(spans[2], spans[4]), "");
105         static_assert(doAssign(spans[2], spans[5]), "");
106         static_assert(doAssign(spans[2], spans[6]), "");
107         static_assert(doAssign(spans[2], spans[7]), "");
108         static_assert(doAssign(spans[2], spans[8]), "");
109         static_assert(doAssign(spans[2], spans[9]), "");
110         static_assert(doAssign(spans[2], spans[10]), "");
111         static_assert(doAssign(spans[2], spans[11]), "");
112         static_assert(doAssign(spans[2], spans[12]), "");
113 
114         static_assert(doAssign(spans[3], spans[3]), "");
115         static_assert(doAssign(spans[3], spans[4]), "");
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[10]), "");
124         static_assert(doAssign(spans[3], spans[11]), "");
125         static_assert(doAssign(spans[3], spans[12]), "");
126 
127         static_assert(doAssign(spans[4], spans[4]), "");
128         static_assert(doAssign(spans[4], spans[5]), "");
129         static_assert(doAssign(spans[4], spans[6]), "");
130         static_assert(doAssign(spans[4], spans[7]), "");
131         static_assert(doAssign(spans[4], spans[8]), "");
132         static_assert(doAssign(spans[4], spans[9]), "");
133         static_assert(doAssign(spans[4], spans[10]), "");
134         static_assert(doAssign(spans[4], spans[11]), "");
135         static_assert(doAssign(spans[4], spans[12]), "");
136 
137         static_assert(doAssign(spans[5], spans[5]), "");
138         static_assert(doAssign(spans[5], spans[6]), "");
139         static_assert(doAssign(spans[5], spans[7]), "");
140         static_assert(doAssign(spans[5], spans[8]), "");
141         static_assert(doAssign(spans[5], spans[9]), "");
142         static_assert(doAssign(spans[5], spans[10]), "");
143         static_assert(doAssign(spans[5], spans[11]), "");
144         static_assert(doAssign(spans[5], spans[12]), "");
145 
146         static_assert(doAssign(spans[6], spans[6]), "");
147         static_assert(doAssign(spans[6], spans[7]), "");
148         static_assert(doAssign(spans[6], spans[8]), "");
149         static_assert(doAssign(spans[6], spans[9]), "");
150         static_assert(doAssign(spans[6], spans[10]), "");
151         static_assert(doAssign(spans[6], spans[11]), "");
152         static_assert(doAssign(spans[6], spans[12]), "");
153 
154         static_assert(doAssign(spans[7], spans[7]), "");
155         static_assert(doAssign(spans[7], spans[8]), "");
156         static_assert(doAssign(spans[7], spans[9]), "");
157         static_assert(doAssign(spans[7], spans[10]), "");
158         static_assert(doAssign(spans[7], spans[11]), "");
159         static_assert(doAssign(spans[7], spans[12]), "");
160 
161         static_assert(doAssign(spans[8], spans[8]), "");
162         static_assert(doAssign(spans[8], spans[9]), "");
163         static_assert(doAssign(spans[8], spans[10]), "");
164         static_assert(doAssign(spans[8], spans[11]), "");
165         static_assert(doAssign(spans[8], spans[12]), "");
166 
167         static_assert(doAssign(spans[9], spans[9]), "");
168         static_assert(doAssign(spans[9], spans[10]), "");
169         static_assert(doAssign(spans[9], spans[11]), "");
170         static_assert(doAssign(spans[9], spans[12]), "");
171 
172         static_assert(doAssign(spans[10], spans[10]), "");
173         static_assert(doAssign(spans[10], spans[11]), "");
174         static_assert(doAssign(spans[10], spans[12]), "");
175 
176         static_assert(doAssign(spans[11], spans[11]), "");
177         static_assert(doAssign(spans[11], spans[12]), "");
178 
179         static_assert(doAssign(spans[12], spans[12]), "");
180 
181 //      for (size_t i = 0; i < std::size(spans); ++i)
182 //          for (size_t j = i; j < std::size(spans); ++j)
183 //              static_assert(doAssign(spans[i], spans[j]), "");
184     }
185 
186 //  constexpr statically sized assignment
187     {
188         using spanType = std::span<const int,2>;
189         constexpr spanType spans[] = {
190             spanType{carr1, 2},
191             spanType{carr1 + 1, 2},
192             spanType{carr1 + 2, 2},
193             spanType{carr2, 2},
194             spanType{carr2 + 1, 2},
195             spanType{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         using spanType = std::span<int,2>;
252         spanType spans[] = {
253             spanType{arr,     arr + 2},
254             spanType{arr + 1, arr + 3},
255             spanType{arr + 2, arr + 4}
256             };
257 
258         for (size_t i = 0; i < std::size(spans); ++i)
259             for (size_t j = i; j < std::size(spans); ++j)
260                 assert((doAssign(spans[i], spans[j])));
261     }
262 
263 //  dynamically sized assignment
264     {
265     std::span<std::string> spans[] = {
266             {strs,     strs},
267             {strs,     strs + 1},
268             {strs,     strs + 2},
269             {strs,     strs + 3},
270             {strs + 1, strs + 1},
271             {strs + 1, strs + 2},
272             {strs + 1, strs + 3},
273             {strs + 2, strs + 2},
274             {strs + 2, strs + 3},
275             {strs + 3, strs + 3}
276             };
277 
278         for (size_t i = 0; i < std::size(spans); ++i)
279             for (size_t j = i; j < std::size(spans); ++j)
280                 assert((doAssign(spans[i], spans[j])));
281     }
282 
283     {
284     using spanType = std::span<std::string, 1>;
285     spanType spans[] = {
286             spanType{strs,     strs + 1},
287             spanType{strs + 1, strs + 2},
288             spanType{strs + 2, strs + 3}
289             };
290 
291         for (size_t i = 0; i < std::size(spans); ++i)
292             for (size_t j = i; j < std::size(spans); ++j)
293                 assert((doAssign(spans[i], spans[j])));
294     }
295 
296   return 0;
297 }
298