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 
42 namespace 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*>
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*>
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
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*
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
typename common_type< _Tp... >::type common_type_t
Alias template for common_type.
Definition: type_traits:2845
typename make_signed< _Tp >::type make_signed_t
Alias template for make_signed.
Definition: type_traits:2139
_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.
Definition: range_access.h:156
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
constexpr auto empty(const _Container &__cont) noexcept(noexcept(__cont.empty())) -> decltype(__cont.empty())
Return whether a container is empty.
Definition: range_access.h:294
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
constexpr auto size(const _Container &__cont) noexcept(noexcept(__cont.size())) -> decltype(__cont.size())
Return the size of a container.
Definition: range_access.h:274
constexpr auto data(_Container &__cont) noexcept(noexcept(__cont.data())) -> decltype(__cont.data())
Return the data pointer of a container.
Definition: range_access.h:324
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
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
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
initializer_list