]>
Commit | Line | Data |
---|---|---|
160061ac | 1 | // Range access functions for containers -*- C++ -*- |
f67a9881 | 2 | |
7adcbafe | 3 | // Copyright (C) 2010-2022 Free Software Foundation, Inc. |
f67a9881 PC |
4 | // |
5 | // This file is part of the GNU ISO C++ Library. This library is free | |
6 | // software; you can redistribute it and/or modify it under the | |
7 | // terms of the GNU General Public License as published by the | |
8 | // Free Software Foundation; either version 3, or (at your option) | |
9 | // any later version. | |
10 | ||
11 | // This library is distributed in the hope that it will be useful, | |
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | // GNU General Public License for more details. | |
15 | ||
16 | // Under Section 7 of GPL version 3, you are granted additional | |
17 | // permissions described in the GCC Runtime Library Exception, version | |
18 | // 3.1, as published by the Free Software Foundation. | |
19 | ||
20 | // You should have received a copy of the GNU General Public License and | |
21 | // a copy of the GCC Runtime Library Exception along with this program; | |
22 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
23 | // <http://www.gnu.org/licenses/>. | |
24 | ||
25 | /** @file bits/range_access.h | |
26 | * This is an internal header file, included by other library headers. | |
f910786b | 27 | * Do not attempt to use it directly. @headername{iterator} |
f67a9881 PC |
28 | */ |
29 | ||
30 | #ifndef _GLIBCXX_RANGE_ACCESS_H | |
31 | #define _GLIBCXX_RANGE_ACCESS_H 1 | |
32 | ||
33 | #pragma GCC system_header | |
34 | ||
734f5023 | 35 | #if __cplusplus >= 201103L |
8bae22b7 | 36 | #include <initializer_list> |
160061ac | 37 | #include <type_traits> // common_type_t, make_signed_t |
47cca028 | 38 | #include <bits/stl_iterator.h> // reverse_iterator |
6d0dff49 | 39 | |
12ffa228 BK |
40 | namespace std _GLIBCXX_VISIBILITY(default) |
41 | { | |
42 | _GLIBCXX_BEGIN_NAMESPACE_VERSION | |
f67a9881 PC |
43 | |
44 | /** | |
45 | * @brief Return an iterator pointing to the first element of | |
46 | * the container. | |
93c66bc6 | 47 | * @param __cont Container. |
f67a9881 | 48 | */ |
a460d06d | 49 | template<typename _Container> |
240b01b0 | 50 | [[__nodiscard__]] |
06db9920 | 51 | inline _GLIBCXX17_CONSTEXPR auto |
f67a9881 PC |
52 | begin(_Container& __cont) -> decltype(__cont.begin()) |
53 | { return __cont.begin(); } | |
54 | ||
55 | /** | |
56 | * @brief Return an iterator pointing to the first element of | |
57 | * the const container. | |
93c66bc6 | 58 | * @param __cont Container. |
f67a9881 | 59 | */ |
a460d06d | 60 | template<typename _Container> |
240b01b0 | 61 | [[__nodiscard__]] |
06db9920 | 62 | inline _GLIBCXX17_CONSTEXPR auto |
f67a9881 PC |
63 | begin(const _Container& __cont) -> decltype(__cont.begin()) |
64 | { return __cont.begin(); } | |
65 | ||
66 | /** | |
67 | * @brief Return an iterator pointing to one past the last element of | |
68 | * the container. | |
93c66bc6 | 69 | * @param __cont Container. |
f67a9881 | 70 | */ |
a460d06d | 71 | template<typename _Container> |
240b01b0 | 72 | [[__nodiscard__]] |
06db9920 | 73 | inline _GLIBCXX17_CONSTEXPR auto |
f67a9881 PC |
74 | end(_Container& __cont) -> decltype(__cont.end()) |
75 | { return __cont.end(); } | |
76 | ||
77 | /** | |
78 | * @brief Return an iterator pointing to one past the last element of | |
79 | * the const container. | |
93c66bc6 | 80 | * @param __cont Container. |
f67a9881 | 81 | */ |
a460d06d | 82 | template<typename _Container> |
240b01b0 | 83 | [[__nodiscard__]] |
06db9920 | 84 | inline _GLIBCXX17_CONSTEXPR auto |
f67a9881 PC |
85 | end(const _Container& __cont) -> decltype(__cont.end()) |
86 | { return __cont.end(); } | |
87 | ||
88 | /** | |
89 | * @brief Return an iterator pointing to the first element of the array. | |
93c66bc6 | 90 | * @param __arr Array. |
f67a9881 | 91 | */ |
a460d06d | 92 | template<typename _Tp, size_t _Nm> |
240b01b0 | 93 | [[__nodiscard__]] |
8bae22b7 | 94 | inline _GLIBCXX14_CONSTEXPR _Tp* |
00b46c00 | 95 | begin(_Tp (&__arr)[_Nm]) noexcept |
f67a9881 PC |
96 | { return __arr; } |
97 | ||
98 | /** | |
99 | * @brief Return an iterator pointing to one past the last element | |
100 | * of the array. | |
93c66bc6 | 101 | * @param __arr Array. |
f67a9881 | 102 | */ |
a460d06d | 103 | template<typename _Tp, size_t _Nm> |
240b01b0 | 104 | [[__nodiscard__]] |
8bae22b7 | 105 | inline _GLIBCXX14_CONSTEXPR _Tp* |
00b46c00 | 106 | end(_Tp (&__arr)[_Nm]) noexcept |
f67a9881 PC |
107 | { return __arr + _Nm; } |
108 | ||
8bae22b7 | 109 | #if __cplusplus >= 201402L |
e994d230 JW |
110 | |
111 | template<typename _Tp> class valarray; | |
112 | // These overloads must be declared for cbegin and cend to use them. | |
2b2d97fc JW |
113 | template<typename _Tp> _Tp* begin(valarray<_Tp>&) noexcept; |
114 | template<typename _Tp> const _Tp* begin(const valarray<_Tp>&) noexcept; | |
115 | template<typename _Tp> _Tp* end(valarray<_Tp>&) noexcept; | |
116 | template<typename _Tp> const _Tp* end(const valarray<_Tp>&) noexcept; | |
e994d230 | 117 | |
8bae22b7 VV |
118 | /** |
119 | * @brief Return an iterator pointing to the first element of | |
120 | * the const container. | |
121 | * @param __cont Container. | |
122 | */ | |
a460d06d | 123 | template<typename _Container> |
240b01b0 | 124 | [[__nodiscard__]] |
9b11107e | 125 | constexpr auto |
8bae22b7 VV |
126 | cbegin(const _Container& __cont) noexcept(noexcept(std::begin(__cont))) |
127 | -> decltype(std::begin(__cont)) | |
128 | { return std::begin(__cont); } | |
129 | ||
130 | /** | |
131 | * @brief Return an iterator pointing to one past the last element of | |
132 | * the const container. | |
133 | * @param __cont Container. | |
134 | */ | |
a460d06d | 135 | template<typename _Container> |
240b01b0 | 136 | [[__nodiscard__]] |
9b11107e | 137 | constexpr auto |
8bae22b7 VV |
138 | cend(const _Container& __cont) noexcept(noexcept(std::end(__cont))) |
139 | -> decltype(std::end(__cont)) | |
140 | { return std::end(__cont); } | |
141 | ||
142 | /** | |
143 | * @brief Return a reverse iterator pointing to the last element of | |
144 | * the container. | |
145 | * @param __cont Container. | |
146 | */ | |
a460d06d | 147 | template<typename _Container> |
240b01b0 | 148 | [[__nodiscard__]] |
06db9920 | 149 | inline _GLIBCXX17_CONSTEXPR auto |
8bae22b7 VV |
150 | rbegin(_Container& __cont) -> decltype(__cont.rbegin()) |
151 | { return __cont.rbegin(); } | |
152 | ||
153 | /** | |
154 | * @brief Return a reverse iterator pointing to the last element of | |
155 | * the const container. | |
156 | * @param __cont Container. | |
157 | */ | |
a460d06d | 158 | template<typename _Container> |
240b01b0 | 159 | [[__nodiscard__]] |
06db9920 | 160 | inline _GLIBCXX17_CONSTEXPR auto |
8bae22b7 VV |
161 | rbegin(const _Container& __cont) -> decltype(__cont.rbegin()) |
162 | { return __cont.rbegin(); } | |
163 | ||
164 | /** | |
165 | * @brief Return a reverse iterator pointing one past the first element of | |
166 | * the container. | |
167 | * @param __cont Container. | |
168 | */ | |
a460d06d | 169 | template<typename _Container> |
240b01b0 | 170 | [[__nodiscard__]] |
06db9920 | 171 | inline _GLIBCXX17_CONSTEXPR auto |
8bae22b7 VV |
172 | rend(_Container& __cont) -> decltype(__cont.rend()) |
173 | { return __cont.rend(); } | |
174 | ||
175 | /** | |
176 | * @brief Return a reverse iterator pointing one past the first element of | |
177 | * the const container. | |
178 | * @param __cont Container. | |
179 | */ | |
a460d06d | 180 | template<typename _Container> |
240b01b0 | 181 | [[__nodiscard__]] |
06db9920 | 182 | inline _GLIBCXX17_CONSTEXPR auto |
8bae22b7 VV |
183 | rend(const _Container& __cont) -> decltype(__cont.rend()) |
184 | { return __cont.rend(); } | |
185 | ||
186 | /** | |
187 | * @brief Return a reverse iterator pointing to the last element of | |
188 | * the array. | |
189 | * @param __arr Array. | |
190 | */ | |
a460d06d | 191 | template<typename _Tp, size_t _Nm> |
240b01b0 | 192 | [[__nodiscard__]] |
06db9920 | 193 | inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Tp*> |
00b46c00 | 194 | rbegin(_Tp (&__arr)[_Nm]) noexcept |
8bae22b7 VV |
195 | { return reverse_iterator<_Tp*>(__arr + _Nm); } |
196 | ||
197 | /** | |
198 | * @brief Return a reverse iterator pointing one past the first element of | |
199 | * the array. | |
200 | * @param __arr Array. | |
201 | */ | |
a460d06d | 202 | template<typename _Tp, size_t _Nm> |
240b01b0 | 203 | [[__nodiscard__]] |
06db9920 | 204 | inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Tp*> |
00b46c00 | 205 | rend(_Tp (&__arr)[_Nm]) noexcept |
8bae22b7 VV |
206 | { return reverse_iterator<_Tp*>(__arr); } |
207 | ||
208 | /** | |
209 | * @brief Return a reverse iterator pointing to the last element of | |
210 | * the initializer_list. | |
211 | * @param __il initializer_list. | |
212 | */ | |
a460d06d | 213 | template<typename _Tp> |
240b01b0 | 214 | [[__nodiscard__]] |
06db9920 | 215 | inline _GLIBCXX17_CONSTEXPR reverse_iterator<const _Tp*> |
00b46c00 | 216 | rbegin(initializer_list<_Tp> __il) noexcept |
8bae22b7 VV |
217 | { return reverse_iterator<const _Tp*>(__il.end()); } |
218 | ||
219 | /** | |
220 | * @brief Return a reverse iterator pointing one past the first element of | |
221 | * the initializer_list. | |
222 | * @param __il initializer_list. | |
223 | */ | |
a460d06d | 224 | template<typename _Tp> |
240b01b0 | 225 | [[__nodiscard__]] |
06db9920 | 226 | inline _GLIBCXX17_CONSTEXPR reverse_iterator<const _Tp*> |
00b46c00 | 227 | rend(initializer_list<_Tp> __il) noexcept |
8bae22b7 VV |
228 | { return reverse_iterator<const _Tp*>(__il.begin()); } |
229 | ||
230 | /** | |
231 | * @brief Return a reverse iterator pointing to the last element of | |
232 | * the const container. | |
233 | * @param __cont Container. | |
234 | */ | |
a460d06d | 235 | template<typename _Container> |
240b01b0 | 236 | [[__nodiscard__]] |
06db9920 | 237 | inline _GLIBCXX17_CONSTEXPR auto |
8bae22b7 VV |
238 | crbegin(const _Container& __cont) -> decltype(std::rbegin(__cont)) |
239 | { return std::rbegin(__cont); } | |
240 | ||
241 | /** | |
242 | * @brief Return a reverse iterator pointing one past the first element of | |
243 | * the const container. | |
244 | * @param __cont Container. | |
245 | */ | |
a460d06d | 246 | template<typename _Container> |
240b01b0 | 247 | [[__nodiscard__]] |
06db9920 | 248 | inline _GLIBCXX17_CONSTEXPR auto |
8bae22b7 VV |
249 | crend(const _Container& __cont) -> decltype(std::rend(__cont)) |
250 | { return std::rend(__cont); } | |
251 | ||
252 | #endif // C++14 | |
253 | ||
19491228 | 254 | #if __cplusplus >= 201703L |
db23e4c4 | 255 | #define __cpp_lib_nonmember_container_access 201411 |
a460d06d VV |
256 | |
257 | /** | |
258 | * @brief Return the size of a container. | |
259 | * @param __cont Container. | |
260 | */ | |
261 | template <typename _Container> | |
240b01b0 | 262 | [[nodiscard]] |
a460d06d | 263 | constexpr auto |
19491228 JW |
264 | size(const _Container& __cont) noexcept(noexcept(__cont.size())) |
265 | -> decltype(__cont.size()) | |
a460d06d VV |
266 | { return __cont.size(); } |
267 | ||
268 | /** | |
269 | * @brief Return the size of an array. | |
a460d06d | 270 | */ |
93411db8 | 271 | template <typename _Tp, size_t _Nm> |
240b01b0 | 272 | [[nodiscard]] |
a460d06d | 273 | constexpr size_t |
8c6a71e4 | 274 | size(const _Tp (&)[_Nm]) noexcept |
93411db8 | 275 | { return _Nm; } |
a460d06d VV |
276 | |
277 | /** | |
278 | * @brief Return whether a container is empty. | |
279 | * @param __cont Container. | |
280 | */ | |
281 | template <typename _Container> | |
d69f1ec7 | 282 | [[nodiscard]] constexpr auto |
19491228 JW |
283 | empty(const _Container& __cont) noexcept(noexcept(__cont.empty())) |
284 | -> decltype(__cont.empty()) | |
a460d06d VV |
285 | { return __cont.empty(); } |
286 | ||
287 | /** | |
288 | * @brief Return whether an array is empty (always false). | |
a460d06d | 289 | */ |
93411db8 | 290 | template <typename _Tp, size_t _Nm> |
d69f1ec7 | 291 | [[nodiscard]] constexpr bool |
8c6a71e4 | 292 | empty(const _Tp (&)[_Nm]) noexcept |
a460d06d VV |
293 | { return false; } |
294 | ||
295 | /** | |
296 | * @brief Return whether an initializer_list is empty. | |
297 | * @param __il Initializer list. | |
298 | */ | |
299 | template <typename _Tp> | |
d69f1ec7 | 300 | [[nodiscard]] constexpr bool |
a460d06d VV |
301 | empty(initializer_list<_Tp> __il) noexcept |
302 | { return __il.size() == 0;} | |
303 | ||
304 | /** | |
305 | * @brief Return the data pointer of a container. | |
306 | * @param __cont Container. | |
307 | */ | |
308 | template <typename _Container> | |
240b01b0 | 309 | [[nodiscard]] |
a460d06d | 310 | constexpr auto |
19491228 JW |
311 | data(_Container& __cont) noexcept(noexcept(__cont.data())) |
312 | -> decltype(__cont.data()) | |
a460d06d VV |
313 | { return __cont.data(); } |
314 | ||
315 | /** | |
316 | * @brief Return the data pointer of a const container. | |
317 | * @param __cont Container. | |
318 | */ | |
319 | template <typename _Container> | |
240b01b0 | 320 | [[nodiscard]] |
a460d06d | 321 | constexpr auto |
19491228 JW |
322 | data(const _Container& __cont) noexcept(noexcept(__cont.data())) |
323 | -> decltype(__cont.data()) | |
a460d06d VV |
324 | { return __cont.data(); } |
325 | ||
326 | /** | |
327 | * @brief Return the data pointer of an array. | |
328 | * @param __array Array. | |
329 | */ | |
93411db8 | 330 | template <typename _Tp, size_t _Nm> |
240b01b0 | 331 | [[nodiscard]] |
a460d06d | 332 | constexpr _Tp* |
93411db8 | 333 | data(_Tp (&__array)[_Nm]) noexcept |
a460d06d VV |
334 | { return __array; } |
335 | ||
336 | /** | |
337 | * @brief Return the data pointer of an initializer list. | |
338 | * @param __il Initializer list. | |
339 | */ | |
340 | template <typename _Tp> | |
240b01b0 | 341 | [[nodiscard]] |
a460d06d VV |
342 | constexpr const _Tp* |
343 | data(initializer_list<_Tp> __il) noexcept | |
344 | { return __il.begin(); } | |
345 | ||
95e9a761 | 346 | #if __cplusplus > 201703L |
56772f62 | 347 | #define __cpp_lib_ssize 201902L |
4ef5bbd8 | 348 | template<typename _Container> |
240b01b0 | 349 | [[nodiscard]] |
4ef5bbd8 JW |
350 | constexpr auto |
351 | ssize(const _Container& __cont) | |
352 | noexcept(noexcept(__cont.size())) | |
353 | -> common_type_t<ptrdiff_t, make_signed_t<decltype(__cont.size())>> | |
354 | { | |
355 | using type = make_signed_t<decltype(__cont.size())>; | |
356 | return static_cast<common_type_t<ptrdiff_t, type>>(__cont.size()); | |
357 | } | |
358 | ||
359 | template<typename _Tp, ptrdiff_t _Num> | |
240b01b0 | 360 | [[nodiscard]] |
4ef5bbd8 JW |
361 | constexpr ptrdiff_t |
362 | ssize(const _Tp (&)[_Num]) noexcept | |
363 | { return _Num; } | |
6d0dff49 | 364 | #endif // C++20 |
160061ac JW |
365 | |
366 | #endif // C++17 | |
12ffa228 BK |
367 | _GLIBCXX_END_NAMESPACE_VERSION |
368 | } // namespace | |
f67a9881 | 369 | |
734f5023 | 370 | #endif // C++11 |
f67a9881 | 371 | #endif // _GLIBCXX_RANGE_ACCESS_H |