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#if __glibcxx_valarray < 202511L
123 template<typename _Tp> class valarray;
124 // These overloads must be declared for cbegin and cend to use them.
125 template<typename _Tp> _Tp* begin(valarray<_Tp>&) noexcept;
126 template<typename _Tp> const _Tp* begin(const valarray<_Tp>&) noexcept;
127 template<typename _Tp> _Tp* end(valarray<_Tp>&) noexcept;
128 template<typename _Tp> const _Tp* end(const valarray<_Tp>&) noexcept;
129#endif
130
131 /**
132 * @brief Return an iterator pointing to the first element of
133 * the const container.
134 * @param __cont Container.
135 * @since C++14
136 */
137 template<typename _Container>
138 [[__nodiscard__, __gnu__::__always_inline__]]
139 constexpr auto
140 cbegin(const _Container& __cont) noexcept(noexcept(std::begin(__cont)))
141 -> decltype(std::begin(__cont))
142 { return std::begin(__cont); }
143
144 /**
145 * @brief Return an iterator pointing to one past the last element of
146 * the const container.
147 * @param __cont Container.
148 * @since C++14
149 */
150 template<typename _Container>
151 [[__nodiscard__, __gnu__::__always_inline__]]
152 constexpr auto
153 cend(const _Container& __cont) noexcept(noexcept(std::end(__cont)))
154 -> decltype(std::end(__cont))
155 { return std::end(__cont); }
156
157 /**
158 * @brief Return a reverse iterator pointing to the last element of
159 * the container.
160 * @param __cont Container.
161 * @since C++14
162 */
163 template<typename _Container>
164 [[__nodiscard__, __gnu__::__always_inline__]]
165 inline _GLIBCXX17_CONSTEXPR auto
166 rbegin(_Container& __cont) noexcept(noexcept(__cont.rbegin()))
167 -> decltype(__cont.rbegin())
168 { return __cont.rbegin(); }
169
170 /**
171 * @brief Return a reverse iterator pointing to the last element of
172 * the const container.
173 * @param __cont Container.
174 * @since C++14
175 */
176 template<typename _Container>
177 [[__nodiscard__, __gnu__::__always_inline__]]
178 inline _GLIBCXX17_CONSTEXPR auto
179 rbegin(const _Container& __cont) noexcept(noexcept(__cont.rbegin()))
180 -> decltype(__cont.rbegin())
181 { return __cont.rbegin(); }
182
183 /**
184 * @brief Return a reverse iterator pointing one past the first element of
185 * the container.
186 * @param __cont Container.
187 * @since C++14
188 */
189 template<typename _Container>
190 [[__nodiscard__, __gnu__::__always_inline__]]
191 inline _GLIBCXX17_CONSTEXPR auto
192 rend(_Container& __cont) noexcept(noexcept(__cont.rend()))
193 -> decltype(__cont.rend())
194 { return __cont.rend(); }
195
196 /**
197 * @brief Return a reverse iterator pointing one past the first element of
198 * the const container.
199 * @param __cont Container.
200 * @since C++14
201 */
202 template<typename _Container>
203 [[__nodiscard__, __gnu__::__always_inline__]]
204 inline _GLIBCXX17_CONSTEXPR auto
205 rend(const _Container& __cont) noexcept(noexcept(__cont.rend()))
206 -> decltype(__cont.rend())
207 { return __cont.rend(); }
208
209 /**
210 * @brief Return a reverse iterator pointing to the last element of
211 * the array.
212 * @param __arr Array.
213 * @since C++14
214 */
215 template<typename _Tp, size_t _Nm>
216 [[__nodiscard__]]
217 inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Tp*>
218 rbegin(_Tp (&__arr)[_Nm]) noexcept
219 { return reverse_iterator<_Tp*>(__arr + _Nm); }
220
221 /**
222 * @brief Return a reverse iterator pointing one past the first element of
223 * the array.
224 * @param __arr Array.
225 * @since C++14
226 */
227 template<typename _Tp, size_t _Nm>
228 [[__nodiscard__]]
229 inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Tp*>
230 rend(_Tp (&__arr)[_Nm]) noexcept
231 { return reverse_iterator<_Tp*>(__arr); }
232
233 /**
234 * @brief Return a reverse iterator pointing to the last element of
235 * the initializer_list.
236 * @param __il initializer_list.
237 * @since C++14
238 */
239 template<typename _Tp>
240 [[__nodiscard__]]
241 inline _GLIBCXX17_CONSTEXPR reverse_iterator<const _Tp*>
243 { return reverse_iterator<const _Tp*>(__il.end()); }
244
245 /**
246 * @brief Return a reverse iterator pointing one past the first element of
247 * the initializer_list.
248 * @param __il initializer_list.
249 * @since C++14
250 */
251 template<typename _Tp>
252 [[__nodiscard__]]
253 inline _GLIBCXX17_CONSTEXPR reverse_iterator<const _Tp*>
255 { return reverse_iterator<const _Tp*>(__il.begin()); }
256
257 /**
258 * @brief Return a reverse iterator pointing to the last element of
259 * the const container.
260 * @param __cont Container.
261 * @since C++14
262 */
263 template<typename _Container>
264 [[__nodiscard__, __gnu__::__always_inline__]]
265 inline _GLIBCXX17_CONSTEXPR auto
266 crbegin(const _Container& __cont) noexcept(noexcept(std::rbegin(__cont)))
267 -> decltype(std::rbegin(__cont))
268 { return std::rbegin(__cont); }
269
270 /**
271 * @brief Return a reverse iterator pointing one past the first element of
272 * the const container.
273 * @param __cont Container.
274 * @since C++14
275 */
276 template<typename _Container>
277 [[__nodiscard__, __gnu__::__always_inline__]]
278 inline _GLIBCXX17_CONSTEXPR auto
279 crend(const _Container& __cont) noexcept(noexcept(std::rend(__cont)))
280 -> decltype(std::rend(__cont))
281 { return std::rend(__cont); }
282
283#endif // C++14
284
285#ifdef __glibcxx_nonmember_container_access // C++ >= 17
286 /**
287 * @brief Return the size of a container.
288 * @param __cont Container.
289 * @since C++17
290 */
291 template <typename _Container>
292 [[nodiscard, __gnu__::__always_inline__]]
293 constexpr auto
294 size(const _Container& __cont) noexcept(noexcept(__cont.size()))
295 -> decltype(__cont.size())
296 { return __cont.size(); }
297
298 /**
299 * @brief Return the size of an array.
300 * @param - An array.
301 * @return The number of elements in the array.
302 * @since C++17
303 */
304 template <typename _Tp, size_t _Nm>
305 [[nodiscard, __gnu__::__always_inline__]]
306 constexpr size_t
307 size(const _Tp (&)[_Nm]) noexcept
308 { return _Nm; }
309
310 /**
311 * @brief Return whether a container is empty.
312 * @param __cont Container.
313 * @since C++17
314 */
315 template <typename _Container>
316 [[nodiscard, __gnu__::__always_inline__]]
317 constexpr auto
318 empty(const _Container& __cont) noexcept(noexcept(__cont.empty()))
319 -> decltype(__cont.empty())
320 { return __cont.empty(); }
321
322 /**
323 * @brief Return whether an array is empty (always false).
324 * @param - An array.
325 * @since C++17
326 */
327 template <typename _Tp, size_t _Nm>
328 [[nodiscard, __gnu__::__always_inline__]]
329 constexpr bool
330 empty(const _Tp (&)[_Nm]) noexcept
331 { return false; }
332
333#if __glibcxx_initializer_list < 202511L
334 /**
335 * @brief Return whether an initializer_list is empty.
336 * @param __il Initializer list.
337 * @since C++17
338 */
339 template <typename _Tp>
340 [[nodiscard, __gnu__::__always_inline__]]
341 constexpr bool
342 empty(initializer_list<_Tp> __il) noexcept
343 { return __il.size() == 0;}
344#endif
345
346 /**
347 * @brief Return the data pointer of a container.
348 * @param __cont Container.
349 * @since C++17
350 */
351 template <typename _Container>
352 [[nodiscard, __gnu__::__always_inline__]]
353 constexpr auto
354 data(_Container& __cont) noexcept(noexcept(__cont.data()))
355 -> decltype(__cont.data())
356 { return __cont.data(); }
357
358 /**
359 * @brief Return the data pointer of a const container.
360 * @param __cont Container.
361 * @since C++17
362 */
363 template <typename _Container>
364 [[nodiscard, __gnu__::__always_inline__]]
365 constexpr auto
366 data(const _Container& __cont) noexcept(noexcept(__cont.data()))
367 -> decltype(__cont.data())
368 { return __cont.data(); }
369
370 /**
371 * @brief Return the data pointer of an array.
372 * @param __array Array.
373 * @since C++17
374 */
375 template <typename _Tp, size_t _Nm>
376 [[nodiscard, __gnu__::__always_inline__]]
377 constexpr _Tp*
378 data(_Tp (&__array)[_Nm]) noexcept
379 { return __array; }
380
381#if __glibcxx_initializer_list < 202511L
382 /**
383 * @brief Return the data pointer of an initializer list.
384 * @param __il Initializer list.
385 * @since C++17
386 */
387 template <typename _Tp>
388 [[nodiscard, __gnu__::__always_inline__]]
389 constexpr const _Tp*
390 data(initializer_list<_Tp> __il) noexcept
391 { return __il.begin(); }
392#endif
393#endif // __glibcxx_nonmember_container_access
394
395#ifdef __glibcxx_ssize // C++ >= 20
396 /**
397 * @brief Return the size of a container, as a signed integer.
398 * @param __cont Container.
399 * @since C++20
400 */
401 template<typename _Container>
402 [[nodiscard, __gnu__::__always_inline__]]
403 constexpr auto
404 ssize(const _Container& __cont) noexcept(noexcept(__cont.size()))
405 -> common_type_t<ptrdiff_t, make_signed_t<decltype(__cont.size())>>
406 {
407 using type = make_signed_t<decltype(__cont.size())>;
408 return static_cast<common_type_t<ptrdiff_t, type>>(__cont.size());
409 }
410
411 /**
412 * @brief Return the length of an array, as a signed integer.
413 * @since C++20
414 */
415 template<typename _Tp, ptrdiff_t _Num>
416 [[nodiscard, __gnu__::__always_inline__]]
417 constexpr ptrdiff_t
418 ssize(const _Tp (&)[_Num]) noexcept
419 { return _Num; }
420#endif // __glibcxx_ssize
421_GLIBCXX_END_NAMESPACE_VERSION
422} // namespace
423
424#endif // C++11
425#endif // _GLIBCXX_RANGE_ACCESS_H
typename make_signed< _Tp >::type make_signed_t
Alias template for make_signed.
Definition type_traits:2269
typename common_type< _Tp... >::type common_type_t
Alias template for common_type.
Definition type_traits:2975
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 end(_Container &__cont) noexcept(noexcept(__cont.end())) -> decltype(__cont.end())
Return an iterator pointing to one past the last element of the 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 begin(_Container &__cont) noexcept(noexcept(__cont.begin())) -> decltype(__cont.begin())
Return an iterator pointing to the first element of the container.
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