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