1 // Copyright (C) 2019-2025 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-do run { target c++20 } }
20 #include <testsuite_hooks.h>
23 #include <type_traits>
32 struct alignas(256) strawman
52 static_assert(sizeof(std::span
<char, 0>) <= sizeof(char*));
53 static_assert(sizeof(std::span
<const char, 0>) <= sizeof(const char*));
54 static_assert(sizeof(std::span
<strawman
, 0>) <= sizeof(strawman
*));
55 static_assert(sizeof(std::span
<strawman
, 1>) <= sizeof(strawman
*));
56 static_assert(sizeof(std::span
<char>) <= sizeof(naked_span
));
57 static_assert(sizeof(std::span
<strawman
>) <= sizeof(strawman_span
));
59 constexpr static std::array
<int, 9> arr_data
{ 0, 1, 2, 3, 4, 5, 6, 7, 8 };
60 constexpr auto arr_data_span
= std::span(arr_data
);
61 static_assert(arr_data_span
.size() == 9);
62 static_assert(arr_data_span
.size_bytes() == 9 * sizeof(int));
63 static_assert(*arr_data_span
.begin() == 0);
64 static_assert(*arr_data_span
.data() == 0);
65 static_assert(arr_data_span
.front() == 0);
66 static_assert(arr_data_span
.back() == 8);
67 static_assert(arr_data_span
[0] == 0);
68 static_assert(arr_data_span
[1] == 1);
69 static_assert(arr_data_span
[2] == 2);
70 static_assert(arr_data_span
[3] == 3);
71 static_assert(arr_data_span
[4] == 4);
72 static_assert(arr_data_span
[5] == 5);
73 static_assert(arr_data_span
[6] == 6);
74 static_assert(arr_data_span
[7] == 7);
75 static_assert(arr_data_span
[8] == 8);
76 static_assert(!arr_data_span
.empty());
77 static_assert(decltype(arr_data_span
)::extent
== 9);
79 constexpr static int data
[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
80 constexpr auto data_span
= std::span(data
);
81 static_assert(data_span
.size() == 9);
82 static_assert(data_span
.size_bytes() == 9 * sizeof(int));
83 static_assert(*data_span
.begin() == 0);
84 static_assert(*data_span
.data() == 0);
85 static_assert(data_span
.front() == 0);
86 static_assert(data_span
.back() == 8);
87 static_assert(data_span
[0] == 0);
88 static_assert(data_span
[1] == 1);
89 static_assert(data_span
[2] == 2);
90 static_assert(data_span
[3] == 3);
91 static_assert(data_span
[4] == 4);
92 static_assert(data_span
[5] == 5);
93 static_assert(data_span
[6] == 6);
94 static_assert(data_span
[7] == 7);
95 static_assert(data_span
[8] == 8);
96 static_assert(!data_span
.empty());
97 static_assert(decltype(data_span
)::extent
== 9);
99 constexpr auto data_span_first
= data_span
.first
<3>();
101 std::is_same_v
<std::remove_cv_t
<decltype(data_span_first
)>, std::span
<const int, 3>>);
102 static_assert(decltype(data_span_first
)::extent
== 3);
103 static_assert(data_span_first
.size() == 3);
104 static_assert(data_span_first
.front() == 0);
105 static_assert(data_span_first
.back() == 2);
107 constexpr auto data_span_first_dyn
= data_span
.first(4);
109 std::is_same_v
<std::remove_cv_t
<decltype(data_span_first_dyn
)>, std::span
<const int>>);
110 static_assert(decltype(data_span_first_dyn
)::extent
== std::dynamic_extent
);
111 static_assert(data_span_first_dyn
.size() == 4);
112 static_assert(data_span_first_dyn
.front() == 0);
113 static_assert(data_span_first_dyn
.back() == 3);
115 constexpr auto data_span_last
= data_span
.last
<5>();
117 std::is_same_v
<std::remove_cv_t
<decltype(data_span_last
)>, std::span
<const int, 5>>);
118 static_assert(decltype(data_span_last
)::extent
== 5);
119 static_assert(data_span_last
.size() == 5);
120 static_assert(data_span_last
.front() == 4);
121 static_assert(data_span_last
.back() == 8);
123 constexpr auto data_span_last_dyn
= data_span
.last(6);
125 std::is_same_v
<std::remove_cv_t
<decltype(data_span_last_dyn
)>, std::span
<const int>>);
126 static_assert(decltype(data_span_last_dyn
)::extent
== std::dynamic_extent
);
127 static_assert(data_span_last_dyn
.size() == 6);
128 static_assert(data_span_last_dyn
.front() == 3);
129 static_assert(data_span_last_dyn
.back() == 8);
131 constexpr auto data_span_subspan
= data_span
.subspan
<1, 3>();
133 std::is_same_v
<std::remove_cv_t
<decltype(data_span_subspan
)>, std::span
<const int, 3>>);
134 static_assert(decltype(data_span_subspan
)::extent
== 3);
135 static_assert(data_span_subspan
.size() == 3);
136 static_assert(data_span_subspan
.front() == 1);
137 static_assert(data_span_subspan
.back() == 3);
139 constexpr auto data_span_subspan_offset
= data_span
.subspan
<8>();
141 std::is_same_v
<std::remove_cv_t
<decltype(data_span_subspan_offset
)>, std::span
<const int, 1>>);
142 static_assert(decltype(data_span_subspan_offset
)::extent
== 1);
143 static_assert(data_span_subspan_offset
.size() == 1);
144 static_assert(data_span_subspan_offset
.front() == 8);
145 static_assert(data_span_subspan_offset
.back() == 8);
147 constexpr auto data_span_subspan_empty
= data_span
.subspan(9, 0);
149 std::is_same_v
<std::remove_cv_t
<decltype(data_span_subspan_empty
)>, std::span
<const int>>);
150 static_assert(decltype(data_span_subspan_empty
)::extent
== std::dynamic_extent
);
151 static_assert(data_span_subspan_empty
.size() == 0);
153 constexpr auto data_span_subspan_empty_static
= data_span
.subspan
<9>();
154 static_assert(std::is_same_v
<std::remove_cv_t
<decltype(data_span_subspan_empty_static
)>,
155 std::span
<const int, 0>>);
156 static_assert(decltype(data_span_subspan_empty_static
)::extent
== 0);
157 static_assert(data_span_subspan_empty
.size() == 0);
159 std::span
<short> shorts
{};
160 bool really_empty0
= shorts
.empty();
161 bool really_empty1
= std::empty(shorts
);
162 bool really_empty2
= shorts
.data() == nullptr;
163 bool really_empty3
= shorts
.begin() == shorts
.end();
165 really_empty0
&& really_empty1
&& really_empty2
&& really_empty3
;
167 VERIFY(really_empty
);
169 std::vector
<std::int_least32_t> value
{ 0 };
170 std::span
<int32_t> muh_span(value
);
171 VERIFY(muh_span
.size() == 1);
172 std::byte
* original_bytes
= reinterpret_cast<std::byte
*>(value
.data());
173 original_bytes
[0] = static_cast<std::byte
>(1);
174 original_bytes
[1] = static_cast<std::byte
>(2);
175 original_bytes
[2] = static_cast<std::byte
>(3);
176 original_bytes
[3] = static_cast<std::byte
>(4);
177 std::span
<const std::byte
> muh_byte_span
= std::as_bytes(muh_span
);
178 std::span
<std::byte
> muh_mutable_byte_span
= std::as_writable_bytes(muh_span
);
179 std::span
<std::byte
> muh_original_byte_span(original_bytes
, original_bytes
+ 4);
180 bool definitely_reinterpret_casted0
= std::equal(muh_byte_span
.begin(), muh_byte_span
.end(),
181 muh_original_byte_span
.begin(), muh_original_byte_span
.end());
182 bool definitely_reinterpret_casted1
= std::equal(muh_mutable_byte_span
.begin(),
183 muh_mutable_byte_span
.end(), muh_original_byte_span
.begin(), muh_original_byte_span
.end());
184 bool definitely_reinterpret_casted
=
185 definitely_reinterpret_casted0
&& definitely_reinterpret_casted1
;
186 (void)definitely_reinterpret_casted
;
187 VERIFY(definitely_reinterpret_casted
);
189 std::span
<std::byte
> muh_original_byte_span_ptr_size(original_bytes
, 4);
190 bool definitely_equivalent
=
191 std::equal(muh_original_byte_span_ptr_size
.begin(), muh_original_byte_span_ptr_size
.end(),
192 muh_original_byte_span
.begin(), muh_original_byte_span
.end());
193 (void)definitely_equivalent
;
194 VERIFY(definitely_equivalent
);
196 return definitely_equivalent
&& definitely_reinterpret_casted
&& really_empty
? 0 : 1;