1 // Copyright (C) 2019-2023 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);
108 constexpr auto data_span_first_dyn
= data_span
.first(4);
110 std::is_same_v
<std::remove_cv_t
<decltype(data_span_first_dyn
)>, std::span
<const int>>);
111 static_assert(decltype(data_span_first_dyn
)::extent
== std::dynamic_extent
);
112 static_assert(data_span_first_dyn
.size() == 4);
113 static_assert(data_span_first_dyn
.front() == 0);
114 static_assert(data_span_first_dyn
.back() == 3);
116 constexpr auto data_span_last
= data_span
.last
<5>();
118 std::is_same_v
<std::remove_cv_t
<decltype(data_span_last
)>, std::span
<const int, 5>>);
119 static_assert(decltype(data_span_last
)::extent
== 5);
120 static_assert(data_span_last
.size() == 5);
121 static_assert(data_span_last
.front() == 4);
122 static_assert(data_span_last
.back() == 8);
124 constexpr auto data_span_last_dyn
= data_span
.last(6);
126 std::is_same_v
<std::remove_cv_t
<decltype(data_span_last_dyn
)>, std::span
<const int>>);
127 static_assert(decltype(data_span_last_dyn
)::extent
== std::dynamic_extent
);
128 static_assert(data_span_last_dyn
.size() == 6);
129 static_assert(data_span_last_dyn
.front() == 3);
130 static_assert(data_span_last_dyn
.back() == 8);
132 constexpr auto data_span_subspan
= data_span
.subspan
<1, 3>();
134 std::is_same_v
<std::remove_cv_t
<decltype(data_span_subspan
)>, std::span
<const int, 3>>);
135 static_assert(decltype(data_span_subspan
)::extent
== 3);
136 static_assert(data_span_subspan
.size() == 3);
137 static_assert(data_span_subspan
.front() == 1);
138 static_assert(data_span_subspan
.back() == 3);
140 constexpr auto data_span_subspan_offset
= data_span
.subspan
<8>();
142 std::is_same_v
<std::remove_cv_t
<decltype(data_span_subspan_offset
)>, std::span
<const int, 1>>);
143 static_assert(decltype(data_span_subspan_offset
)::extent
== 1);
144 static_assert(data_span_subspan_offset
.size() == 1);
145 static_assert(data_span_subspan_offset
.front() == 8);
146 static_assert(data_span_subspan_offset
.back() == 8);
148 constexpr auto data_span_subspan_empty
= data_span
.subspan(9, 0);
150 std::is_same_v
<std::remove_cv_t
<decltype(data_span_subspan_empty
)>, std::span
<const int>>);
151 static_assert(decltype(data_span_subspan_empty
)::extent
== std::dynamic_extent
);
152 static_assert(data_span_subspan_empty
.size() == 0);
154 constexpr auto data_span_subspan_empty_static
= data_span
.subspan
<9>();
155 static_assert(std::is_same_v
<std::remove_cv_t
<decltype(data_span_subspan_empty_static
)>,
156 std::span
<const int, 0>>);
157 static_assert(decltype(data_span_subspan_empty_static
)::extent
== 0);
158 static_assert(data_span_subspan_empty
.size() == 0);
160 std::span
<short> shorts
{};
161 bool really_empty0
= shorts
.empty();
162 bool really_empty1
= std::empty(shorts
);
163 bool really_empty2
= shorts
.data() == nullptr;
164 bool really_empty3
= shorts
.begin() == shorts
.end();
166 really_empty0
&& really_empty1
&& really_empty2
&& really_empty3
;
168 VERIFY(really_empty
);
170 std::vector
<std::int_least32_t> value
{ 0 };
171 std::span
<int32_t> muh_span(value
);
172 VERIFY(muh_span
.size() == 1);
173 std::byte
* original_bytes
= reinterpret_cast<std::byte
*>(value
.data());
174 original_bytes
[0] = static_cast<std::byte
>(1);
175 original_bytes
[1] = static_cast<std::byte
>(2);
176 original_bytes
[2] = static_cast<std::byte
>(3);
177 original_bytes
[3] = static_cast<std::byte
>(4);
178 std::span
<const std::byte
> muh_byte_span
= std::as_bytes(muh_span
);
179 std::span
<std::byte
> muh_mutable_byte_span
= std::as_writable_bytes(muh_span
);
180 std::span
<std::byte
> muh_original_byte_span(original_bytes
, original_bytes
+ 4);
181 bool definitely_reinterpret_casted0
= std::equal(muh_byte_span
.begin(), muh_byte_span
.end(),
182 muh_original_byte_span
.begin(), muh_original_byte_span
.end());
183 bool definitely_reinterpret_casted1
= std::equal(muh_mutable_byte_span
.begin(),
184 muh_mutable_byte_span
.end(), muh_original_byte_span
.begin(), muh_original_byte_span
.end());
185 bool definitely_reinterpret_casted
=
186 definitely_reinterpret_casted0
&& definitely_reinterpret_casted1
;
187 (void)definitely_reinterpret_casted
;
188 VERIFY(definitely_reinterpret_casted
);
190 std::span
<std::byte
> muh_original_byte_span_ptr_size(original_bytes
, 4);
191 bool definitely_equivalent
=
192 std::equal(muh_original_byte_span_ptr_size
.begin(), muh_original_byte_span_ptr_size
.end(),
193 muh_original_byte_span
.begin(), muh_original_byte_span
.end());
194 (void)definitely_equivalent
;
195 VERIFY(definitely_equivalent
);
197 return definitely_equivalent
&& definitely_reinterpret_casted
&& really_empty
? 0 : 1;