1 ///////////////////////////////////////////////////////////////////////////////
3 // Copyright (c) 2015 Microsoft Corporation. All rights reserved.
5 // This code is licensed under the MIT License (MIT).
7 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
8 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
10 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
11 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
12 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
15 ///////////////////////////////////////////////////////////////////////////////
17 #include <gtest/gtest.h>
19 #include <gsl/gsl_util> // for narrow_cast, at
20 #include <gsl/span_ext> // for operator==, operator!=, make_span
22 #include <array> // for array
23 #include <iostream> // for cerr
24 #include <vector> // for vector
31 static constexpr char deathstring
[] = "Expected Death";
34 TEST(span_ext_test
, make_span_from_pointer_length_constructor
)
36 std::set_terminate([] {
37 std::cerr
<< "Expected Death. from_pointer_length_constructor";
40 int arr
[4] = {1, 2, 3, 4};
43 auto s
= make_span(&arr
[0], 2);
44 EXPECT_TRUE(s
.size() == 2);
45 EXPECT_TRUE(s
.data() == &arr
[0]);
46 EXPECT_TRUE(s
[0] == 1);
47 EXPECT_TRUE(s
[1] == 2);
52 auto s
= make_span(p
, narrow_cast
<span
<int>::size_type
>(0));
53 EXPECT_TRUE(s
.size() == 0);
54 EXPECT_TRUE(s
.data() == nullptr);
59 auto workaround_macro
= [=]() { make_span(p
, 2); };
60 EXPECT_DEATH(workaround_macro(), deathstring
);
64 TEST(span_ext_test
, make_span_from_pointer_pointer_construction
)
66 int arr
[4] = {1, 2, 3, 4};
69 auto s
= make_span(&arr
[0], &arr
[2]);
70 EXPECT_TRUE(s
.size() == 2);
71 EXPECT_TRUE(s
.data() == &arr
[0]);
72 EXPECT_TRUE(s
[0] == 1);
73 EXPECT_TRUE(s
[1] == 2);
77 auto s
= make_span(&arr
[0], &arr
[0]);
78 EXPECT_TRUE(s
.size() == 0);
79 EXPECT_TRUE(s
.data() == &arr
[0]);
84 auto s
= make_span(p
, p
);
85 EXPECT_TRUE(s
.size() == 0);
86 EXPECT_TRUE(s
.data() == nullptr);
90 TEST(span_ext_test
, make_span_from_array_constructor
)
92 int arr
[5] = {1, 2, 3, 4, 5};
93 int arr2d
[2][3] = {1, 2, 3, 4, 5, 6};
94 int arr3d
[2][3][2] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
97 const auto s
= make_span(arr
);
98 EXPECT_TRUE(s
.size() == 5);
99 EXPECT_TRUE(s
.data() == std::addressof(arr
[0]));
103 const auto s
= make_span(std::addressof(arr2d
[0]), 1);
104 EXPECT_TRUE(s
.size() == 1);
105 EXPECT_TRUE(s
.data() == std::addressof(arr2d
[0]));
109 const auto s
= make_span(std::addressof(arr3d
[0]), 1);
110 EXPECT_TRUE(s
.size() == 1);
111 EXPECT_TRUE(s
.data() == std::addressof(arr3d
[0]));
115 TEST(span_ext_test
, make_span_from_dynamic_array_constructor
)
117 double(*arr
)[3][4] = new double[100][3][4];
120 auto s
= make_span(&arr
[0][0][0], 10);
121 EXPECT_TRUE(s
.size() == 10);
122 EXPECT_TRUE(s
.data() == &arr
[0][0][0]);
128 TEST(span_ext_test
, make_span_from_std_array_constructor
)
130 std::array
<int, 4> arr
= {1, 2, 3, 4};
133 auto s
= make_span(arr
);
134 EXPECT_TRUE(s
.size() == arr
.size());
135 EXPECT_TRUE(s
.data() == arr
.data());
138 // This test checks for the bug found in gcc 6.1, 6.2, 6.3, 6.4, 6.5 7.1, 7.2, 7.3 - issue #590
140 span
<int> s1
= make_span(arr
);
145 #if defined(__GNUC__) && __GNUC__ == 6 && (__GNUC_MINOR__ == 4 || __GNUC_MINOR__ == 5) && \
146 __GNUC_PATCHLEVEL__ == 0 && defined(__OPTIMIZE__)
147 // Known to be broken in gcc 6.4 and 6.5 with optimizations
148 // Issue in gcc: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83116
149 EXPECT_TRUE(s1
.size() == 4);
150 EXPECT_TRUE(s2
.size() == 0);
152 EXPECT_TRUE(s1
.size() == s2
.size());
157 TEST(span_ext_test
, make_span_from_const_std_array_constructor
)
159 const std::array
<int, 4> arr
= {1, 2, 3, 4};
162 auto s
= make_span(arr
);
163 EXPECT_TRUE(s
.size() == arr
.size());
164 EXPECT_TRUE(s
.data() == arr
.data());
168 TEST(span_ext_test
, make_span_from_std_array_const_constructor
)
170 std::array
<const int, 4> arr
= {1, 2, 3, 4};
173 auto s
= make_span(arr
);
174 EXPECT_TRUE(s
.size() == arr
.size());
175 EXPECT_TRUE(s
.data() == arr
.data());
179 TEST(span_ext_test
, make_span_from_container_constructor
)
181 std::vector
<int> v
= {1, 2, 3};
182 const std::vector
<int> cv
= v
;
185 auto s
= make_span(v
);
186 EXPECT_TRUE(s
.size() == v
.size());
187 EXPECT_TRUE(s
.data() == v
.data());
189 auto cs
= make_span(cv
);
190 EXPECT_TRUE(cs
.size() == cv
.size());
191 EXPECT_TRUE(cs
.data() == cv
.data());
195 TEST(span_test
, interop_with_gsl_at
)
197 int arr
[5] = {1, 2, 3, 4, 5};
199 EXPECT_TRUE(at(s
, 0) == 1);
200 EXPECT_TRUE(at(s
, 1) == 2);
203 TEST(span_ext_test
, iterator_free_functions
)
205 int a
[] = {1, 2, 3, 4};
208 EXPECT_TRUE((std::is_same
<decltype(s
.begin()), decltype(begin(s
))>::value
));
209 EXPECT_TRUE((std::is_same
<decltype(s
.end()), decltype(end(s
))>::value
));
211 EXPECT_TRUE((std::is_same
<decltype(std::cbegin(s
)), decltype(cbegin(s
))>::value
));
212 EXPECT_TRUE((std::is_same
<decltype(std::cend(s
)), decltype(cend(s
))>::value
));
214 EXPECT_TRUE((std::is_same
<decltype(s
.rbegin()), decltype(rbegin(s
))>::value
));
215 EXPECT_TRUE((std::is_same
<decltype(s
.rend()), decltype(rend(s
))>::value
));
217 EXPECT_TRUE((std::is_same
<decltype(std::crbegin(s
)), decltype(crbegin(s
))>::value
));
218 EXPECT_TRUE((std::is_same
<decltype(std::crend(s
)), decltype(crend(s
))>::value
));
220 EXPECT_TRUE(s
.begin() == begin(s
));
221 EXPECT_TRUE(s
.end() == end(s
));
223 EXPECT_TRUE(s
.rbegin() == rbegin(s
));
224 EXPECT_TRUE(s
.rend() == rend(s
));
226 EXPECT_TRUE(s
.begin() == cbegin(s
));
227 EXPECT_TRUE(s
.end() == cend(s
));
229 EXPECT_TRUE(s
.rbegin() == crbegin(s
));
230 EXPECT_TRUE(s
.rend() == crend(s
));
233 TEST(span_ext_test
, ssize_free_function
)
235 int a
[] = {1, 2, 3, 4};
238 EXPECT_FALSE((std::is_same
<decltype(s
.size()), decltype(ssize(s
))>::value
));
239 EXPECT_TRUE(s
.size() == static_cast<std::size_t>(ssize(s
)));
242 TEST(span_ext_test
, comparison_operators
)
247 EXPECT_TRUE(s1
== s2
);
248 EXPECT_FALSE(s1
!= s2
);
249 EXPECT_FALSE(s1
< s2
);
250 EXPECT_TRUE(s1
<= s2
);
251 EXPECT_FALSE(s1
> s2
);
252 EXPECT_TRUE(s1
>= s2
);
253 EXPECT_TRUE(s2
== s1
);
254 EXPECT_FALSE(s2
!= s1
);
255 EXPECT_FALSE(s2
!= s1
);
256 EXPECT_TRUE(s2
<= s1
);
257 EXPECT_FALSE(s2
> s1
);
258 EXPECT_TRUE(s2
>= s1
);
266 EXPECT_TRUE(s1
== s2
);
267 EXPECT_FALSE(s1
!= s2
);
268 EXPECT_FALSE(s1
< s2
);
269 EXPECT_TRUE(s1
<= s2
);
270 EXPECT_FALSE(s1
> s2
);
271 EXPECT_TRUE(s1
>= s2
);
272 EXPECT_TRUE(s2
== s1
);
273 EXPECT_FALSE(s2
!= s1
);
274 EXPECT_FALSE(s2
< s1
);
275 EXPECT_TRUE(s2
<= s1
);
276 EXPECT_FALSE(s2
> s1
);
277 EXPECT_TRUE(s2
>= s1
);
281 int arr
[] = {2, 1}; // bigger
286 EXPECT_TRUE(s1
!= s2
);
287 EXPECT_TRUE(s2
!= s1
);
288 EXPECT_FALSE(s1
== s2
);
289 EXPECT_FALSE(s2
== s1
);
290 EXPECT_TRUE(s1
< s2
);
291 EXPECT_FALSE(s2
< s1
);
292 EXPECT_TRUE(s1
<= s2
);
293 EXPECT_FALSE(s2
<= s1
);
294 EXPECT_TRUE(s2
> s1
);
295 EXPECT_FALSE(s1
> s2
);
296 EXPECT_TRUE(s2
>= s1
);
297 EXPECT_FALSE(s1
>= s2
);
306 EXPECT_TRUE(s1
== s2
);
307 EXPECT_FALSE(s1
!= s2
);
308 EXPECT_FALSE(s1
< s2
);
309 EXPECT_TRUE(s1
<= s2
);
310 EXPECT_FALSE(s1
> s2
);
311 EXPECT_TRUE(s1
>= s2
);
312 EXPECT_TRUE(s2
== s1
);
313 EXPECT_FALSE(s2
!= s1
);
314 EXPECT_FALSE(s2
< s1
);
315 EXPECT_TRUE(s2
<= s1
);
316 EXPECT_FALSE(s2
> s1
);
317 EXPECT_TRUE(s2
>= s1
);
321 int arr
[] = {1, 2, 3};
323 span
<int> s1
= {&arr
[0], 2}; // shorter
324 span
<int> s2
= arr
; // longer
326 EXPECT_TRUE(s1
!= s2
);
327 EXPECT_TRUE(s2
!= s1
);
328 EXPECT_FALSE(s1
== s2
);
329 EXPECT_FALSE(s2
== s1
);
330 EXPECT_TRUE(s1
< s2
);
331 EXPECT_FALSE(s2
< s1
);
332 EXPECT_TRUE(s1
<= s2
);
333 EXPECT_FALSE(s2
<= s1
);
334 EXPECT_TRUE(s2
> s1
);
335 EXPECT_FALSE(s1
> s2
);
336 EXPECT_TRUE(s2
>= s1
);
337 EXPECT_FALSE(s1
>= s2
);
341 int arr1
[] = {1, 2}; // smaller
342 int arr2
[] = {2, 1}; // bigger
347 EXPECT_TRUE(s1
!= s2
);
348 EXPECT_TRUE(s2
!= s1
);
349 EXPECT_FALSE(s1
== s2
);
350 EXPECT_FALSE(s2
== s1
);
351 EXPECT_TRUE(s1
< s2
);
352 EXPECT_FALSE(s2
< s1
);
353 EXPECT_TRUE(s1
<= s2
);
354 EXPECT_FALSE(s2
<= s1
);
355 EXPECT_TRUE(s2
> s1
);
356 EXPECT_FALSE(s1
> s2
);
357 EXPECT_TRUE(s2
>= s1
);
358 EXPECT_FALSE(s1
>= s2
);