libstdc++
range_access.h
Go to the documentation of this file.
1// Range access functions for containers -*- C++ -*-
2
3// Copyright (C) 2010-2025 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) -> decltype(__cont.rbegin())
157 { return __cont.rbegin(); }
158
159 /**
160 * @brief Return a reverse iterator pointing to the last element of
161 * the const container.
162 * @param __cont Container.
163 */
164 template<typename _Container>
165 [[__nodiscard__, __gnu__::__always_inline__]]
166 inline _GLIBCXX17_CONSTEXPR auto
167 rbegin(const _Container& __cont) -> decltype(__cont.rbegin())
168 { return __cont.rbegin(); }
169
170 /**
171 * @brief Return a reverse iterator pointing one past the first element of
172 * the container.
173 * @param __cont Container.
174 */
175 template<typename _Container>
176 [[__nodiscard__, __gnu__::__always_inline__]]
177 inline _GLIBCXX17_CONSTEXPR auto
178 rend(_Container& __cont) -> decltype(__cont.rend())
179 { return __cont.rend(); }
180
181 /**
182 * @brief Return a reverse iterator pointing one past the first element of
183 * the const container.
184 * @param __cont Container.
185 */
186 template<typename _Container>
187 [[__nodiscard__, __gnu__::__always_inline__]]
188 inline _GLIBCXX17_CONSTEXPR auto
189 rend(const _Container& __cont) -> decltype(__cont.rend())
190 { return __cont.rend(); }
191
192 /**
193 * @brief Return a reverse iterator pointing to the last element of
194 * the array.
195 * @param __arr Array.
196 */
197 template<typename _Tp, size_t _Nm>
198 [[__nodiscard__]]
199 inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Tp*>
200 rbegin(_Tp (&__arr)[_Nm]) noexcept
201 { return reverse_iterator<_Tp*>(__arr + _Nm); }
202
203 /**
204 * @brief Return a reverse iterator pointing one past the first element of
205 * the array.
206 * @param __arr Array.
207 */
208 template<typename _Tp, size_t _Nm>
209 [[__nodiscard__]]
210 inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Tp*>
211 rend(_Tp (&__arr)[_Nm]) noexcept
212 { return reverse_iterator<_Tp*>(__arr); }
213
214 /**
215 * @brief Return a reverse iterator pointing to the last element of
216 * the initializer_list.
217 * @param __il initializer_list.
218 */
219 template<typename _Tp>
220 [[__nodiscard__]]
221 inline _GLIBCXX17_CONSTEXPR reverse_iterator<const _Tp*>
223 { return reverse_iterator<const _Tp*>(__il.end()); }
224
225 /**
226 * @brief Return a reverse iterator pointing one past the first element of
227 * the initializer_list.
228 * @param __il initializer_list.
229 */
230 template<typename _Tp>
231 [[__nodiscard__]]
232 inline _GLIBCXX17_CONSTEXPR reverse_iterator<const _Tp*>
234 { return reverse_iterator<const _Tp*>(__il.begin()); }
235
236 /**
237 * @brief Return a reverse iterator pointing to the last element of
238 * the const container.
239 * @param __cont Container.
240 */
241 template<typename _Container>
242 [[__nodiscard__, __gnu__::__always_inline__]]
243 inline _GLIBCXX17_CONSTEXPR auto
244 crbegin(const _Container& __cont) -> decltype(std::rbegin(__cont))
245 { return std::rbegin(__cont); }
246
247 /**
248 * @brief Return a reverse iterator pointing one past the first element of
249 * the const container.
250 * @param __cont Container.
251 */
252 template<typename _Container>
253 [[__nodiscard__, __gnu__::__always_inline__]]
254 inline _GLIBCXX17_CONSTEXPR auto
255 crend(const _Container& __cont) -> decltype(std::rend(__cont))
256 { return std::rend(__cont); }
257
258#endif // C++14
259
260#ifdef __glibcxx_nonmember_container_access // C++ >= 17
261 /**
262 * @brief Return the size of a container.
263 * @param __cont Container.
264 */
265 template <typename _Container>
266 [[nodiscard, __gnu__::__always_inline__]]
267 constexpr auto
268 size(const _Container& __cont) noexcept(noexcept(__cont.size()))
269 -> decltype(__cont.size())
270 { return __cont.size(); }
271
272 /**
273 * @brief Return the size of an array.
274 */
275 template <typename _Tp, size_t _Nm>
276 [[nodiscard, __gnu__::__always_inline__]]
277 constexpr size_t
278 size(const _Tp (&)[_Nm]) noexcept
279 { return _Nm; }
280
281 /**
282 * @brief Return whether a container is empty.
283 * @param __cont Container.
284 */
285 template <typename _Container>
286 [[nodiscard, __gnu__::__always_inline__]]
287 constexpr auto
288 empty(const _Container& __cont) noexcept(noexcept(__cont.empty()))
289 -> decltype(__cont.empty())
290 { return __cont.empty(); }
291
292 /**
293 * @brief Return whether an array is empty (always false).
294 */
295 template <typename _Tp, size_t _Nm>
296 [[nodiscard, __gnu__::__always_inline__]]
297 constexpr bool
298 empty(const _Tp (&)[_Nm]) noexcept
299 { return false; }
300
301 /**
302 * @brief Return whether an initializer_list is empty.
303 * @param __il Initializer list.
304 */
305 template <typename _Tp>
306 [[nodiscard, __gnu__::__always_inline__]]
307 constexpr bool
309 { return __il.size() == 0;}
310
311 /**
312 * @brief Return the data pointer of a container.
313 * @param __cont Container.
314 */
315 template <typename _Container>
316 [[nodiscard, __gnu__::__always_inline__]]
317 constexpr auto
318 data(_Container& __cont) noexcept(noexcept(__cont.data()))
319 -> decltype(__cont.data())
320 { return __cont.data(); }
321
322 /**
323 * @brief Return the data pointer of a const container.
324 * @param __cont Container.
325 */
326 template <typename _Container>
327 [[nodiscard, __gnu__::__always_inline__]]
328 constexpr auto
329 data(const _Container& __cont) noexcept(noexcept(__cont.data()))
330 -> decltype(__cont.data())
331 { return __cont.data(); }
332
333 /**
334 * @brief Return the data pointer of an array.
335 * @param __array Array.
336 */
337 template <typename _Tp, size_t _Nm>
338 [[nodiscard, __gnu__::__always_inline__]]
339 constexpr _Tp*
340 data(_Tp (&__array)[_Nm]) noexcept
341 { return __array; }
342
343 /**
344 * @brief Return the data pointer of an initializer list.
345 * @param __il Initializer list.
346 */
347 template <typename _Tp>
348 [[nodiscard, __gnu__::__always_inline__]]
349 constexpr const _Tp*
351 { return __il.begin(); }
352#endif // __glibcxx_nonmember_container_access
353
354#ifdef __glibcxx_ssize // C++ >= 20
355 template<typename _Container>
356 [[nodiscard, __gnu__::__always_inline__]]
357 constexpr auto
358 ssize(const _Container& __cont) noexcept(noexcept(__cont.size()))
359 -> common_type_t<ptrdiff_t, make_signed_t<decltype(__cont.size())>>
360 {
361 using type = make_signed_t<decltype(__cont.size())>;
362 return static_cast<common_type_t<ptrdiff_t, type>>(__cont.size());
363 }
364
365 template<typename _Tp, ptrdiff_t _Num>
366 [[nodiscard, __gnu__::__always_inline__]]
367 constexpr ptrdiff_t
368 ssize(const _Tp (&)[_Num]) noexcept
369 { return _Num; }
370#endif // __glibcxx_ssize
371_GLIBCXX_END_NAMESPACE_VERSION
372} // namespace
373
374#endif // C++11
375#endif // _GLIBCXX_RANGE_ACCESS_H
typename common_type< _Tp... >::type common_type_t
Alias template for common_type.
Definition type_traits:2844
typename make_signed< _Tp >::type make_signed_t
Alias template for make_signed.
Definition type_traits:2138
_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 crend(const _Container &__cont) -> decltype(std::rend(__cont))
Return a reverse iterator pointing one past the first element of the const container.
constexpr auto rend(_Container &__cont) -> decltype(__cont.rend())
Return a reverse iterator pointing one past the first 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 size(const _Container &__cont) noexcept(noexcept(__cont.size())) -> decltype(__cont.size())
Return the size of a container.
constexpr auto rbegin(_Container &__cont) -> decltype(__cont.rbegin())
Return a reverse iterator pointing to the last element of the container.
constexpr auto crbegin(const _Container &__cont) -> decltype(std::rbegin(__cont))
Return a reverse iterator pointing to the last element of the const 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.
initializer_list