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