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