libstdc++
range_access.h
Go to the documentation of this file.
1// Range access functions for containers -*- C++ -*-
2
3// Copyright (C) 2010-2026 Free Software Foundation, Inc.
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.
27 * Do not attempt to use it directly. @headername{iterator}
28 */
29
30#ifndef _GLIBCXX_RANGE_ACCESS_H
31#define _GLIBCXX_RANGE_ACCESS_H 1
32
33#ifdef _GLIBCXX_SYSHDR
34#pragma GCC system_header
35#endif
36
37#if __cplusplus >= 201103L
38#include <initializer_list>
39#include <type_traits> // common_type_t, make_signed_t
40#include <bits/stl_iterator.h> // reverse_iterator
41
42namespace std _GLIBCXX_VISIBILITY(default)
43{
44_GLIBCXX_BEGIN_NAMESPACE_VERSION
45
46 /**
47 * @brief Return an iterator pointing to the first element of
48 * the container.
49 * @param __cont Container.
50 * @since C++11
51 */
52 template<typename _Container>
53 [[__nodiscard__, __gnu__::__always_inline__]]
54 inline _GLIBCXX17_CONSTEXPR auto
55 begin(_Container& __cont) noexcept(noexcept(__cont.begin()))
56 -> decltype(__cont.begin())
57 { return __cont.begin(); }
58
59 /**
60 * @brief Return an iterator pointing to the first element of
61 * the const container.
62 * @param __cont Container.
63 */
64 template<typename _Container>
65 [[__nodiscard__, __gnu__::__always_inline__]]
66 inline _GLIBCXX17_CONSTEXPR auto
67 begin(const _Container& __cont) noexcept(noexcept(__cont.begin()))
68 -> decltype(__cont.begin())
69 { return __cont.begin(); }
70
71 /**
72 * @brief Return an iterator pointing to one past the last element of
73 * the container.
74 * @param __cont Container.
75 * @since C++11
76 */
77 template<typename _Container>
78 [[__nodiscard__, __gnu__::__always_inline__]]
79 inline _GLIBCXX17_CONSTEXPR auto
80 end(_Container& __cont) noexcept(noexcept(__cont.end()))
81 -> decltype(__cont.end())
82 { return __cont.end(); }
83
84 /**
85 * @brief Return an iterator pointing to one past the last element of
86 * the const container.
87 * @param __cont Container.
88 * @since C++11
89 */
90 template<typename _Container>
91 [[__nodiscard__, __gnu__::__always_inline__]]
92 inline _GLIBCXX17_CONSTEXPR auto
93 end(const _Container& __cont) noexcept(noexcept(__cont.end()))
94 -> decltype(__cont.end())
95 { return __cont.end(); }
96
97 /**
98 * @brief Return an iterator pointing to the first element of the array.
99 * @param __arr Array.
100 * @since C++11
101 */
102 template<typename _Tp, size_t _Nm>
103 [[__nodiscard__, __gnu__::__always_inline__]]
104 inline _GLIBCXX14_CONSTEXPR _Tp*
105 begin(_Tp (&__arr)[_Nm]) noexcept
106 { return __arr; }
107
108 /**
109 * @brief Return an iterator pointing to one past the last element
110 * of the array.
111 * @param __arr Array.
112 * @since C++11
113 */
114 template<typename _Tp, size_t _Nm>
115 [[__nodiscard__, __gnu__::__always_inline__]]
116 inline _GLIBCXX14_CONSTEXPR _Tp*
117 end(_Tp (&__arr)[_Nm]) noexcept
118 { return __arr + _Nm; }
119
120#if __cplusplus >= 201402L
121
122 template<typename _Tp> class valarray;
123 // These overloads must be declared for cbegin and cend to use them.
124 template<typename _Tp> _Tp* begin(valarray<_Tp>&) noexcept;
125 template<typename _Tp> const _Tp* begin(const valarray<_Tp>&) noexcept;
126 template<typename _Tp> _Tp* end(valarray<_Tp>&) noexcept;
127 template<typename _Tp> const _Tp* end(const valarray<_Tp>&) noexcept;
128
129 /**
130 * @brief Return an iterator pointing to the first element of
131 * the const container.
132 * @param __cont Container.
133 * @since C++14
134 */
135 template<typename _Container>
136 [[__nodiscard__, __gnu__::__always_inline__]]
137 constexpr auto
138 cbegin(const _Container& __cont) noexcept(noexcept(std::begin(__cont)))
139 -> decltype(std::begin(__cont))
140 { return std::begin(__cont); }
141
142 /**
143 * @brief Return an iterator pointing to one past the last element of
144 * the const container.
145 * @param __cont Container.
146 * @since C++14
147 */
148 template<typename _Container>
149 [[__nodiscard__, __gnu__::__always_inline__]]
150 constexpr auto
151 cend(const _Container& __cont) noexcept(noexcept(std::end(__cont)))
152 -> decltype(std::end(__cont))
153 { return std::end(__cont); }
154
155 /**
156 * @brief Return a reverse iterator pointing to the last element of
157 * the container.
158 * @param __cont Container.
159 * @since C++14
160 */
161 template<typename _Container>
162 [[__nodiscard__, __gnu__::__always_inline__]]
163 inline _GLIBCXX17_CONSTEXPR auto
164 rbegin(_Container& __cont) noexcept(noexcept(__cont.rbegin()))
165 -> decltype(__cont.rbegin())
166 { return __cont.rbegin(); }
167
168 /**
169 * @brief Return a reverse iterator pointing to the last element of
170 * the const container.
171 * @param __cont Container.
172 * @since C++14
173 */
174 template<typename _Container>
175 [[__nodiscard__, __gnu__::__always_inline__]]
176 inline _GLIBCXX17_CONSTEXPR auto
177 rbegin(const _Container& __cont) noexcept(noexcept(__cont.rbegin()))
178 -> decltype(__cont.rbegin())
179 { return __cont.rbegin(); }
180
181 /**
182 * @brief Return a reverse iterator pointing one past the first element of
183 * the container.
184 * @param __cont Container.
185 * @since C++14
186 */
187 template<typename _Container>
188 [[__nodiscard__, __gnu__::__always_inline__]]
189 inline _GLIBCXX17_CONSTEXPR auto
190 rend(_Container& __cont) noexcept(noexcept(__cont.rend()))
191 -> decltype(__cont.rend())
192 { return __cont.rend(); }
193
194 /**
195 * @brief Return a reverse iterator pointing one past the first element of
196 * the const container.
197 * @param __cont Container.
198 * @since C++14
199 */
200 template<typename _Container>
201 [[__nodiscard__, __gnu__::__always_inline__]]
202 inline _GLIBCXX17_CONSTEXPR auto
203 rend(const _Container& __cont) noexcept(noexcept(__cont.rend()))
204 -> decltype(__cont.rend())
205 { return __cont.rend(); }
206
207 /**
208 * @brief Return a reverse iterator pointing to the last element of
209 * the array.
210 * @param __arr Array.
211 * @since C++14
212 */
213 template<typename _Tp, size_t _Nm>
214 [[__nodiscard__]]
215 inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Tp*>
216 rbegin(_Tp (&__arr)[_Nm]) noexcept
217 { return reverse_iterator<_Tp*>(__arr + _Nm); }
218
219 /**
220 * @brief Return a reverse iterator pointing one past the first element of
221 * the array.
222 * @param __arr Array.
223 * @since C++14
224 */
225 template<typename _Tp, size_t _Nm>
226 [[__nodiscard__]]
227 inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Tp*>
228 rend(_Tp (&__arr)[_Nm]) noexcept
229 { return reverse_iterator<_Tp*>(__arr); }
230
231 /**
232 * @brief Return a reverse iterator pointing to the last element of
233 * the initializer_list.
234 * @param __il initializer_list.
235 * @since C++14
236 */
237 template<typename _Tp>
238 [[__nodiscard__]]
239 inline _GLIBCXX17_CONSTEXPR reverse_iterator<const _Tp*>
241 { return reverse_iterator<const _Tp*>(__il.end()); }
242
243 /**
244 * @brief Return a reverse iterator pointing one past the first element of
245 * the initializer_list.
246 * @param __il initializer_list.
247 * @since C++14
248 */
249 template<typename _Tp>
250 [[__nodiscard__]]
251 inline _GLIBCXX17_CONSTEXPR reverse_iterator<const _Tp*>
253 { return reverse_iterator<const _Tp*>(__il.begin()); }
254
255 /**
256 * @brief Return a reverse iterator pointing to the last element of
257 * the const container.
258 * @param __cont Container.
259 * @since C++14
260 */
261 template<typename _Container>
262 [[__nodiscard__, __gnu__::__always_inline__]]
263 inline _GLIBCXX17_CONSTEXPR auto
264 crbegin(const _Container& __cont) noexcept(noexcept(std::rbegin(__cont)))
265 -> decltype(std::rbegin(__cont))
266 { return std::rbegin(__cont); }
267
268 /**
269 * @brief Return a reverse iterator pointing one past the first element of
270 * the const container.
271 * @param __cont Container.
272 * @since C++14
273 */
274 template<typename _Container>
275 [[__nodiscard__, __gnu__::__always_inline__]]
276 inline _GLIBCXX17_CONSTEXPR auto
277 crend(const _Container& __cont) noexcept(noexcept(std::rend(__cont)))
278 -> decltype(std::rend(__cont))
279 { return std::rend(__cont); }
280
281#endif // C++14
282
283#ifdef __glibcxx_nonmember_container_access // C++ >= 17
284 /**
285 * @brief Return the size of a container.
286 * @param __cont Container.
287 * @since C++17
288 */
289 template <typename _Container>
290 [[nodiscard, __gnu__::__always_inline__]]
291 constexpr auto
292 size(const _Container& __cont) noexcept(noexcept(__cont.size()))
293 -> decltype(__cont.size())
294 { return __cont.size(); }
295
296 /**
297 * @brief Return the size of an array.
298 * @param - An array.
299 * @return The number of elements in the array.
300 * @since C++17
301 */
302 template <typename _Tp, size_t _Nm>
303 [[nodiscard, __gnu__::__always_inline__]]
304 constexpr size_t
305 size(const _Tp (&)[_Nm]) noexcept
306 { return _Nm; }
307
308 /**
309 * @brief Return whether a container is empty.
310 * @param __cont Container.
311 * @since C++17
312 */
313 template <typename _Container>
314 [[nodiscard, __gnu__::__always_inline__]]
315 constexpr auto
316 empty(const _Container& __cont) noexcept(noexcept(__cont.empty()))
317 -> decltype(__cont.empty())
318 { return __cont.empty(); }
319
320 /**
321 * @brief Return whether an array is empty (always false).
322 * @param - An array.
323 * @since C++17
324 */
325 template <typename _Tp, size_t _Nm>
326 [[nodiscard, __gnu__::__always_inline__]]
327 constexpr bool
328 empty(const _Tp (&)[_Nm]) noexcept
329 { return false; }
330
331 /**
332 * @brief Return whether an initializer_list is empty.
333 * @param __il Initializer list.
334 * @since C++17
335 */
336 template <typename _Tp>
337 [[nodiscard, __gnu__::__always_inline__]]
338 constexpr bool
340 { return __il.size() == 0;}
341
342 /**
343 * @brief Return the data pointer of a container.
344 * @param __cont Container.
345 * @since C++17
346 */
347 template <typename _Container>
348 [[nodiscard, __gnu__::__always_inline__]]
349 constexpr auto
350 data(_Container& __cont) noexcept(noexcept(__cont.data()))
351 -> decltype(__cont.data())
352 { return __cont.data(); }
353
354 /**
355 * @brief Return the data pointer of a const container.
356 * @param __cont Container.
357 * @since C++17
358 */
359 template <typename _Container>
360 [[nodiscard, __gnu__::__always_inline__]]
361 constexpr auto
362 data(const _Container& __cont) noexcept(noexcept(__cont.data()))
363 -> decltype(__cont.data())
364 { return __cont.data(); }
365
366 /**
367 * @brief Return the data pointer of an array.
368 * @param __array Array.
369 * @since C++17
370 */
371 template <typename _Tp, size_t _Nm>
372 [[nodiscard, __gnu__::__always_inline__]]
373 constexpr _Tp*
374 data(_Tp (&__array)[_Nm]) noexcept
375 { return __array; }
376
377 /**
378 * @brief Return the data pointer of an initializer list.
379 * @param __il Initializer list.
380 * @since C++17
381 */
382 template <typename _Tp>
383 [[nodiscard, __gnu__::__always_inline__]]
384 constexpr const _Tp*
386 { return __il.begin(); }
387#endif // __glibcxx_nonmember_container_access
388
389#ifdef __glibcxx_ssize // C++ >= 20
390 /**
391 * @brief Return the size of a container, as a signed integer.
392 * @param __cont Container.
393 * @since C++20
394 */
395 template<typename _Container>
396 [[nodiscard, __gnu__::__always_inline__]]
397 constexpr auto
398 ssize(const _Container& __cont) noexcept(noexcept(__cont.size()))
399 -> common_type_t<ptrdiff_t, make_signed_t<decltype(__cont.size())>>
400 {
401 using type = make_signed_t<decltype(__cont.size())>;
402 return static_cast<common_type_t<ptrdiff_t, type>>(__cont.size());
403 }
404
405 /**
406 * @brief Return the length of an array, as a signed integer.
407 * @since C++20
408 */
409 template<typename _Tp, ptrdiff_t _Num>
410 [[nodiscard, __gnu__::__always_inline__]]
411 constexpr ptrdiff_t
412 ssize(const _Tp (&)[_Num]) noexcept
413 { return _Num; }
414#endif // __glibcxx_ssize
415_GLIBCXX_END_NAMESPACE_VERSION
416} // namespace
417
418#endif // C++11
419#endif // _GLIBCXX_RANGE_ACCESS_H
typename make_signed< _Tp >::type make_signed_t
Alias template for make_signed.
Definition type_traits:2246
typename common_type< _Tp... >::type common_type_t
Alias template for common_type.
Definition type_traits:2952
_Tp * end(valarray< _Tp > &__va) noexcept
Return an iterator pointing to one past the last element of the valarray.
Definition valarray:1251
_Tp * begin(valarray< _Tp > &__va) noexcept
Return an iterator pointing to the first element of the valarray.
Definition valarray:1229
ISO C++ entities toplevel namespace is std.
constexpr auto rbegin(_Container &__cont) noexcept(noexcept(__cont.rbegin())) -> decltype(__cont.rbegin())
Return a reverse iterator pointing to the last element of the container.
constexpr auto cend(const _Container &__cont) noexcept(noexcept(std::end(__cont))) -> decltype(std::end(__cont))
Return an iterator pointing to one past the last element of the const container.
constexpr auto empty(const _Container &__cont) noexcept(noexcept(__cont.empty())) -> decltype(__cont.empty())
Return whether a container is empty.
constexpr auto crbegin(const _Container &__cont) noexcept(noexcept(std::rbegin(__cont))) -> decltype(std::rbegin(__cont))
Return a reverse iterator pointing to the last element of the const container.
constexpr auto size(const _Container &__cont) noexcept(noexcept(__cont.size())) -> decltype(__cont.size())
Return the size of a container.
constexpr auto data(_Container &__cont) noexcept(noexcept(__cont.data())) -> decltype(__cont.data())
Return the data pointer of a container.
constexpr auto cbegin(const _Container &__cont) noexcept(noexcept(std::begin(__cont))) -> decltype(std::begin(__cont))
Return an iterator pointing to the first element of the const container.
constexpr auto rend(_Container &__cont) noexcept(noexcept(__cont.rend())) -> decltype(__cont.rend())
Return a reverse iterator pointing one past the first element of the container.
constexpr auto ssize(const _Container &__cont) noexcept(noexcept(__cont.size())) -> common_type_t< ptrdiff_t, make_signed_t< decltype(__cont.size())> >
Return the size of a container, as a signed integer.
constexpr auto crend(const _Container &__cont) noexcept(noexcept(std::rend(__cont))) -> decltype(std::rend(__cont))
Return a reverse iterator pointing one past the first element of the const container.
initializer_list