1 // Copyright (C) 2019 Free Software Foundation, Inc.
3 // This file is part of the GNU ISO C++ Library. This library is free
4 // software; you can redistribute it and/or modify it under the
5 // terms of the GNU General Public License as published by the
6 // Free Software Foundation; either version 3, or (at your option)
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License along
15 // with this library; see the file COPYING3. If not see
16 // <http://www.gnu.org/licenses/>.
18 // { dg-options "-std=c++2a" }
19 // { dg-do run { target c++2a } }
21 #include <testsuite_hooks.h>
24 #include <type_traits>
33 struct alignas(256) strawman
53 static_assert(sizeof(std::span
<char, 0>) <= sizeof(char*));
54 static_assert(sizeof(std::span
<const char, 0>) <= sizeof(const char*));
55 static_assert(sizeof(std::span
<strawman
, 0>) <= sizeof(strawman
*));
56 static_assert(sizeof(std::span
<strawman
, 1>) <= sizeof(strawman
*));
57 static_assert(sizeof(std::span
<char>) <= sizeof(naked_span
));
58 static_assert(sizeof(std::span
<strawman
>) <= sizeof(strawman_span
));
60 constexpr static std::array
<int, 9> arr_data
{ 0, 1, 2, 3, 4, 5, 6, 7, 8 };
61 constexpr auto arr_data_span
= std::span(arr_data
);
62 static_assert(arr_data_span
.size() == 9);
63 static_assert(arr_data_span
.size_bytes() == 9 * sizeof(int));
64 static_assert(*arr_data_span
.begin() == 0);
65 static_assert(*arr_data_span
.data() == 0);
66 static_assert(arr_data_span
.front() == 0);
67 static_assert(arr_data_span
.back() == 8);
68 static_assert(arr_data_span
[0] == 0);
69 static_assert(arr_data_span
[1] == 1);
70 static_assert(arr_data_span
[2] == 2);
71 static_assert(arr_data_span
[3] == 3);
72 static_assert(arr_data_span
[4] == 4);
73 static_assert(arr_data_span
[5] == 5);
74 static_assert(arr_data_span
[6] == 6);
75 static_assert(arr_data_span
[7] == 7);
76 static_assert(arr_data_span
[8] == 8);
77 static_assert(!arr_data_span
.empty());
78 static_assert(decltype(arr_data_span
)::extent
== 9);
80 constexpr static int data
[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
81 constexpr auto data_span
= std::span(data
);
82 static_assert(data_span
.size() == 9);
83 static_assert(data_span
.size_bytes() == 9 * sizeof(int));
84 static_assert(*data_span
.begin() == 0);
85 static_assert(*data_span
.data() == 0);
86 static_assert(data_span
.front() == 0);
87 static_assert(data_span
.back() == 8);
88 static_assert(data_span
[0] == 0);
89 static_assert(data_span
[1] == 1);
90 static_assert(data_span
[2] == 2);
91 static_assert(data_span
[3] == 3);
92 static_assert(data_span
[4] == 4);
93 static_assert(data_span
[5] == 5);
94 static_assert(data_span
[6] == 6);
95 static_assert(data_span
[7] == 7);
96 static_assert(data_span
[8] == 8);
97 static_assert(!data_span
.empty());
98 static_assert(decltype(data_span
)::extent
== 9);
100 constexpr auto data_span_first
= data_span
.first
<3>();
102 std::is_same_v
<std::remove_cv_t
<decltype(data_span_first
)>, std::span
<const int, 3>>);
103 static_assert(decltype(data_span_first
)::extent
== 3);
104 static_assert(data_span_first
.size() == 3);
105 static_assert(data_span_first
.front() == 0);
106 static_assert(data_span_first
.back() == 2);
107 static_assert(std::tuple_size_v
<decltype(data_span_first
)> == 3);
108 static_assert(std::is_same_v
<std::tuple_element_t
<0, decltype(data_span_first
)>, const int>);
110 constexpr auto data_span_first_dyn
= data_span
.first(4);
112 std::is_same_v
<std::remove_cv_t
<decltype(data_span_first_dyn
)>, std::span
<const int>>);
113 static_assert(decltype(data_span_first_dyn
)::extent
== std::dynamic_extent
);
114 static_assert(data_span_first_dyn
.size() == 4);
115 static_assert(data_span_first_dyn
.front() == 0);
116 static_assert(data_span_first_dyn
.back() == 3);
118 constexpr auto data_span_last
= data_span
.last
<5>();
120 std::is_same_v
<std::remove_cv_t
<decltype(data_span_last
)>, std::span
<const int, 5>>);
121 static_assert(decltype(data_span_last
)::extent
== 5);
122 static_assert(data_span_last
.size() == 5);
123 static_assert(data_span_last
.front() == 4);
124 static_assert(data_span_last
.back() == 8);
125 static_assert(std::tuple_size_v
<decltype(data_span_last
)> == 5);
126 static_assert(std::is_same_v
<std::tuple_element_t
<0, decltype(data_span_last
)>, const int>);
128 constexpr auto data_span_last_dyn
= data_span
.last(6);
130 std::is_same_v
<std::remove_cv_t
<decltype(data_span_last_dyn
)>, std::span
<const int>>);
131 static_assert(decltype(data_span_last_dyn
)::extent
== std::dynamic_extent
);
132 static_assert(data_span_last_dyn
.size() == 6);
133 static_assert(data_span_last_dyn
.front() == 3);
134 static_assert(data_span_last_dyn
.back() == 8);
136 constexpr auto data_span_subspan
= data_span
.subspan
<1, 3>();
138 std::is_same_v
<std::remove_cv_t
<decltype(data_span_subspan
)>, std::span
<const int, 3>>);
139 static_assert(decltype(data_span_subspan
)::extent
== 3);
140 static_assert(data_span_subspan
.size() == 3);
141 static_assert(data_span_subspan
.front() == 1);
142 static_assert(data_span_subspan
.back() == 3);
144 constexpr auto data_span_subspan_offset
= data_span
.subspan
<8>();
146 std::is_same_v
<std::remove_cv_t
<decltype(data_span_subspan_offset
)>, std::span
<const int, 1>>);
147 static_assert(decltype(data_span_subspan_offset
)::extent
== 1);
148 static_assert(data_span_subspan_offset
.size() == 1);
149 static_assert(data_span_subspan_offset
.front() == 8);
150 static_assert(data_span_subspan_offset
.back() == 8);
152 constexpr auto data_span_subspan_empty
= data_span
.subspan(9, 0);
154 std::is_same_v
<std::remove_cv_t
<decltype(data_span_subspan_empty
)>, std::span
<const int>>);
155 static_assert(decltype(data_span_subspan_empty
)::extent
== std::dynamic_extent
);
156 static_assert(data_span_subspan_empty
.size() == 0);
158 constexpr auto data_span_subspan_empty_static
= data_span
.subspan
<9>();
159 static_assert(std::is_same_v
<std::remove_cv_t
<decltype(data_span_subspan_empty_static
)>,
160 std::span
<const int, 0>>);
161 static_assert(decltype(data_span_subspan_empty_static
)::extent
== 0);
162 static_assert(data_span_subspan_empty
.size() == 0);
164 std::span
<short> shorts
{};
165 bool really_empty0
= shorts
.empty();
166 bool really_empty1
= std::empty(shorts
);
167 bool really_empty2
= shorts
.data() == nullptr;
168 bool really_empty3
= shorts
.begin() == shorts
.end();
169 bool really_empty4
= shorts
.cbegin() == shorts
.cend();
171 really_empty0
&& really_empty1
&& really_empty2
&& really_empty3
&& really_empty4
;
173 VERIFY(really_empty
);
175 std::vector
<std::int_least32_t> value
{ 0 };
176 std::span
<int32_t> muh_span(value
);
177 VERIFY(muh_span
.size() == 1);
178 std::byte
* original_bytes
= reinterpret_cast<std::byte
*>(value
.data());
179 original_bytes
[0] = static_cast<std::byte
>(1);
180 original_bytes
[1] = static_cast<std::byte
>(2);
181 original_bytes
[2] = static_cast<std::byte
>(3);
182 original_bytes
[3] = static_cast<std::byte
>(4);
183 std::span
<const std::byte
> muh_byte_span
= std::as_bytes(muh_span
);
184 std::span
<std::byte
> muh_mutable_byte_span
= std::as_writable_bytes(muh_span
);
185 std::span
<std::byte
> muh_original_byte_span(original_bytes
, original_bytes
+ 4);
186 bool definitely_reinterpret_casted0
= std::equal(muh_byte_span
.cbegin(), muh_byte_span
.cend(),
187 muh_original_byte_span
.cbegin(), muh_original_byte_span
.cend());
188 bool definitely_reinterpret_casted1
= std::equal(muh_mutable_byte_span
.cbegin(),
189 muh_mutable_byte_span
.cend(), muh_original_byte_span
.cbegin(), muh_original_byte_span
.cend());
190 bool definitely_reinterpret_casted
=
191 definitely_reinterpret_casted0
&& definitely_reinterpret_casted1
;
192 (void)definitely_reinterpret_casted
;
193 VERIFY(definitely_reinterpret_casted
);
195 std::span
<std::byte
> muh_original_byte_span_ptr_size(original_bytes
, 4);
196 bool definitely_equivalent
=
197 std::equal(muh_original_byte_span_ptr_size
.cbegin(), muh_original_byte_span_ptr_size
.cend(),
198 muh_original_byte_span
.cbegin(), muh_original_byte_span
.cend());
199 (void)definitely_equivalent
;
200 VERIFY(definitely_equivalent
);
202 return definitely_equivalent
&& definitely_reinterpret_casted
&& really_empty
? 0 : 1;