libstdc++: range_access.h Source File

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