xref: /dflybsd-src/contrib/gcc-8.0/libstdc++-v3/include/bits/range_access.h (revision 38fd149817dfbff97799f62fcb70be98c4e32523)
1*38fd1498Szrj // <range_access.h> -*- C++ -*-
2*38fd1498Szrj 
3*38fd1498Szrj // Copyright (C) 2010-2018 Free Software Foundation, Inc.
4*38fd1498Szrj //
5*38fd1498Szrj // This file is part of the GNU ISO C++ Library.  This library is free
6*38fd1498Szrj // software; you can redistribute it and/or modify it under the
7*38fd1498Szrj // terms of the GNU General Public License as published by the
8*38fd1498Szrj // Free Software Foundation; either version 3, or (at your option)
9*38fd1498Szrj // any later version.
10*38fd1498Szrj 
11*38fd1498Szrj // This library is distributed in the hope that it will be useful,
12*38fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of
13*38fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*38fd1498Szrj // GNU General Public License for more details.
15*38fd1498Szrj 
16*38fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional
17*38fd1498Szrj // permissions described in the GCC Runtime Library Exception, version
18*38fd1498Szrj // 3.1, as published by the Free Software Foundation.
19*38fd1498Szrj 
20*38fd1498Szrj // You should have received a copy of the GNU General Public License and
21*38fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program;
22*38fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23*38fd1498Szrj // <http://www.gnu.org/licenses/>.
24*38fd1498Szrj 
25*38fd1498Szrj /** @file bits/range_access.h
26*38fd1498Szrj  *  This is an internal header file, included by other library headers.
27*38fd1498Szrj  *  Do not attempt to use it directly. @headername{iterator}
28*38fd1498Szrj  */
29*38fd1498Szrj 
30*38fd1498Szrj #ifndef _GLIBCXX_RANGE_ACCESS_H
31*38fd1498Szrj #define _GLIBCXX_RANGE_ACCESS_H 1
32*38fd1498Szrj 
33*38fd1498Szrj #pragma GCC system_header
34*38fd1498Szrj 
35*38fd1498Szrj #if __cplusplus >= 201103L
36*38fd1498Szrj #include <initializer_list>
_GLIBCXX_VISIBILITY(default)37*38fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default)
38*38fd1498Szrj {
39*38fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION
40*38fd1498Szrj 
41*38fd1498Szrj   /**
42*38fd1498Szrj    *  @brief  Return an iterator pointing to the first element of
43*38fd1498Szrj    *          the container.
44*38fd1498Szrj    *  @param  __cont  Container.
45*38fd1498Szrj    */
46*38fd1498Szrj   template<typename _Container>
47*38fd1498Szrj     inline _GLIBCXX17_CONSTEXPR auto
48*38fd1498Szrj     begin(_Container& __cont) -> decltype(__cont.begin())
49*38fd1498Szrj     { return __cont.begin(); }
50*38fd1498Szrj 
51*38fd1498Szrj   /**
52*38fd1498Szrj    *  @brief  Return an iterator pointing to the first element of
53*38fd1498Szrj    *          the const container.
54*38fd1498Szrj    *  @param  __cont  Container.
55*38fd1498Szrj    */
56*38fd1498Szrj   template<typename _Container>
57*38fd1498Szrj     inline _GLIBCXX17_CONSTEXPR auto
58*38fd1498Szrj     begin(const _Container& __cont) -> decltype(__cont.begin())
59*38fd1498Szrj     { return __cont.begin(); }
60*38fd1498Szrj 
61*38fd1498Szrj   /**
62*38fd1498Szrj    *  @brief  Return an iterator pointing to one past the last element of
63*38fd1498Szrj    *          the container.
64*38fd1498Szrj    *  @param  __cont  Container.
65*38fd1498Szrj    */
66*38fd1498Szrj   template<typename _Container>
67*38fd1498Szrj     inline _GLIBCXX17_CONSTEXPR auto
68*38fd1498Szrj     end(_Container& __cont) -> decltype(__cont.end())
69*38fd1498Szrj     { return __cont.end(); }
70*38fd1498Szrj 
71*38fd1498Szrj   /**
72*38fd1498Szrj    *  @brief  Return an iterator pointing to one past the last element of
73*38fd1498Szrj    *          the const container.
74*38fd1498Szrj    *  @param  __cont  Container.
75*38fd1498Szrj    */
76*38fd1498Szrj   template<typename _Container>
77*38fd1498Szrj     inline _GLIBCXX17_CONSTEXPR auto
78*38fd1498Szrj     end(const _Container& __cont) -> decltype(__cont.end())
79*38fd1498Szrj     { return __cont.end(); }
80*38fd1498Szrj 
81*38fd1498Szrj   /**
82*38fd1498Szrj    *  @brief  Return an iterator pointing to the first element of the array.
83*38fd1498Szrj    *  @param  __arr  Array.
84*38fd1498Szrj    */
85*38fd1498Szrj   template<typename _Tp, size_t _Nm>
86*38fd1498Szrj     inline _GLIBCXX14_CONSTEXPR _Tp*
87*38fd1498Szrj     begin(_Tp (&__arr)[_Nm])
88*38fd1498Szrj     { return __arr; }
89*38fd1498Szrj 
90*38fd1498Szrj   /**
91*38fd1498Szrj    *  @brief  Return an iterator pointing to one past the last element
92*38fd1498Szrj    *          of the array.
93*38fd1498Szrj    *  @param  __arr  Array.
94*38fd1498Szrj    */
95*38fd1498Szrj   template<typename _Tp, size_t _Nm>
96*38fd1498Szrj     inline _GLIBCXX14_CONSTEXPR _Tp*
97*38fd1498Szrj     end(_Tp (&__arr)[_Nm])
98*38fd1498Szrj     { return __arr + _Nm; }
99*38fd1498Szrj 
100*38fd1498Szrj #if __cplusplus >= 201402L
101*38fd1498Szrj 
102*38fd1498Szrj   template<typename _Tp> class valarray;
103*38fd1498Szrj   // These overloads must be declared for cbegin and cend to use them.
104*38fd1498Szrj   template<typename _Tp> _Tp* begin(valarray<_Tp>&);
105*38fd1498Szrj   template<typename _Tp> const _Tp* begin(const valarray<_Tp>&);
106*38fd1498Szrj   template<typename _Tp> _Tp* end(valarray<_Tp>&);
107*38fd1498Szrj   template<typename _Tp> const _Tp* end(const valarray<_Tp>&);
108*38fd1498Szrj 
109*38fd1498Szrj   /**
110*38fd1498Szrj    *  @brief  Return an iterator pointing to the first element of
111*38fd1498Szrj    *          the const container.
112*38fd1498Szrj    *  @param  __cont  Container.
113*38fd1498Szrj    */
114*38fd1498Szrj   template<typename _Container>
115*38fd1498Szrj     inline constexpr auto
116*38fd1498Szrj     cbegin(const _Container& __cont) noexcept(noexcept(std::begin(__cont)))
117*38fd1498Szrj       -> decltype(std::begin(__cont))
118*38fd1498Szrj     { return std::begin(__cont); }
119*38fd1498Szrj 
120*38fd1498Szrj   /**
121*38fd1498Szrj    *  @brief  Return an iterator pointing to one past the last element of
122*38fd1498Szrj    *          the const container.
123*38fd1498Szrj    *  @param  __cont  Container.
124*38fd1498Szrj    */
125*38fd1498Szrj   template<typename _Container>
126*38fd1498Szrj     inline constexpr auto
127*38fd1498Szrj     cend(const _Container& __cont) noexcept(noexcept(std::end(__cont)))
128*38fd1498Szrj       -> decltype(std::end(__cont))
129*38fd1498Szrj     { return std::end(__cont); }
130*38fd1498Szrj 
131*38fd1498Szrj   /**
132*38fd1498Szrj    *  @brief  Return a reverse iterator pointing to the last element of
133*38fd1498Szrj    *          the container.
134*38fd1498Szrj    *  @param  __cont  Container.
135*38fd1498Szrj    */
136*38fd1498Szrj   template<typename _Container>
137*38fd1498Szrj     inline _GLIBCXX17_CONSTEXPR auto
138*38fd1498Szrj     rbegin(_Container& __cont) -> decltype(__cont.rbegin())
139*38fd1498Szrj     { return __cont.rbegin(); }
140*38fd1498Szrj 
141*38fd1498Szrj   /**
142*38fd1498Szrj    *  @brief  Return a reverse iterator pointing to the last element of
143*38fd1498Szrj    *          the const container.
144*38fd1498Szrj    *  @param  __cont  Container.
145*38fd1498Szrj    */
146*38fd1498Szrj   template<typename _Container>
147*38fd1498Szrj     inline _GLIBCXX17_CONSTEXPR auto
148*38fd1498Szrj     rbegin(const _Container& __cont) -> decltype(__cont.rbegin())
149*38fd1498Szrj     { return __cont.rbegin(); }
150*38fd1498Szrj 
151*38fd1498Szrj   /**
152*38fd1498Szrj    *  @brief  Return a reverse iterator pointing one past the first element of
153*38fd1498Szrj    *          the container.
154*38fd1498Szrj    *  @param  __cont  Container.
155*38fd1498Szrj    */
156*38fd1498Szrj   template<typename _Container>
157*38fd1498Szrj     inline _GLIBCXX17_CONSTEXPR auto
158*38fd1498Szrj     rend(_Container& __cont) -> decltype(__cont.rend())
159*38fd1498Szrj     { return __cont.rend(); }
160*38fd1498Szrj 
161*38fd1498Szrj   /**
162*38fd1498Szrj    *  @brief  Return a reverse iterator pointing one past the first element of
163*38fd1498Szrj    *          the const container.
164*38fd1498Szrj    *  @param  __cont  Container.
165*38fd1498Szrj    */
166*38fd1498Szrj   template<typename _Container>
167*38fd1498Szrj     inline _GLIBCXX17_CONSTEXPR auto
168*38fd1498Szrj     rend(const _Container& __cont) -> decltype(__cont.rend())
169*38fd1498Szrj     { return __cont.rend(); }
170*38fd1498Szrj 
171*38fd1498Szrj   /**
172*38fd1498Szrj    *  @brief  Return a reverse iterator pointing to the last element of
173*38fd1498Szrj    *          the array.
174*38fd1498Szrj    *  @param  __arr  Array.
175*38fd1498Szrj    */
176*38fd1498Szrj   template<typename _Tp, size_t _Nm>
177*38fd1498Szrj     inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Tp*>
178*38fd1498Szrj     rbegin(_Tp (&__arr)[_Nm])
179*38fd1498Szrj     { return reverse_iterator<_Tp*>(__arr + _Nm); }
180*38fd1498Szrj 
181*38fd1498Szrj   /**
182*38fd1498Szrj    *  @brief  Return a reverse iterator pointing one past the first element of
183*38fd1498Szrj    *          the array.
184*38fd1498Szrj    *  @param  __arr  Array.
185*38fd1498Szrj    */
186*38fd1498Szrj   template<typename _Tp, size_t _Nm>
187*38fd1498Szrj     inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Tp*>
188*38fd1498Szrj     rend(_Tp (&__arr)[_Nm])
189*38fd1498Szrj     { return reverse_iterator<_Tp*>(__arr); }
190*38fd1498Szrj 
191*38fd1498Szrj   /**
192*38fd1498Szrj    *  @brief  Return a reverse iterator pointing to the last element of
193*38fd1498Szrj    *          the initializer_list.
194*38fd1498Szrj    *  @param  __il  initializer_list.
195*38fd1498Szrj    */
196*38fd1498Szrj   template<typename _Tp>
197*38fd1498Szrj     inline _GLIBCXX17_CONSTEXPR reverse_iterator<const _Tp*>
198*38fd1498Szrj     rbegin(initializer_list<_Tp> __il)
199*38fd1498Szrj     { return reverse_iterator<const _Tp*>(__il.end()); }
200*38fd1498Szrj 
201*38fd1498Szrj   /**
202*38fd1498Szrj    *  @brief  Return a reverse iterator pointing one past the first element of
203*38fd1498Szrj    *          the initializer_list.
204*38fd1498Szrj    *  @param  __il  initializer_list.
205*38fd1498Szrj    */
206*38fd1498Szrj   template<typename _Tp>
207*38fd1498Szrj     inline _GLIBCXX17_CONSTEXPR reverse_iterator<const _Tp*>
208*38fd1498Szrj     rend(initializer_list<_Tp> __il)
209*38fd1498Szrj     { return reverse_iterator<const _Tp*>(__il.begin()); }
210*38fd1498Szrj 
211*38fd1498Szrj   /**
212*38fd1498Szrj    *  @brief  Return a reverse iterator pointing to the last element of
213*38fd1498Szrj    *          the const container.
214*38fd1498Szrj    *  @param  __cont  Container.
215*38fd1498Szrj    */
216*38fd1498Szrj   template<typename _Container>
217*38fd1498Szrj     inline _GLIBCXX17_CONSTEXPR auto
218*38fd1498Szrj     crbegin(const _Container& __cont) -> decltype(std::rbegin(__cont))
219*38fd1498Szrj     { return std::rbegin(__cont); }
220*38fd1498Szrj 
221*38fd1498Szrj   /**
222*38fd1498Szrj    *  @brief  Return a reverse iterator pointing one past the first element of
223*38fd1498Szrj    *          the const container.
224*38fd1498Szrj    *  @param  __cont  Container.
225*38fd1498Szrj    */
226*38fd1498Szrj   template<typename _Container>
227*38fd1498Szrj     inline _GLIBCXX17_CONSTEXPR auto
228*38fd1498Szrj     crend(const _Container& __cont) -> decltype(std::rend(__cont))
229*38fd1498Szrj     { return std::rend(__cont); }
230*38fd1498Szrj 
231*38fd1498Szrj #endif // C++14
232*38fd1498Szrj 
233*38fd1498Szrj #if __cplusplus >= 201703L
234*38fd1498Szrj #define __cpp_lib_nonmember_container_access 201411
235*38fd1498Szrj 
236*38fd1498Szrj   /**
237*38fd1498Szrj    *  @brief  Return the size of a container.
238*38fd1498Szrj    *  @param  __cont  Container.
239*38fd1498Szrj    */
240*38fd1498Szrj   template <typename _Container>
241*38fd1498Szrj     constexpr auto
242*38fd1498Szrj     size(const _Container& __cont) noexcept(noexcept(__cont.size()))
243*38fd1498Szrj     -> decltype(__cont.size())
244*38fd1498Szrj     { return __cont.size(); }
245*38fd1498Szrj 
246*38fd1498Szrj   /**
247*38fd1498Szrj    *  @brief  Return the size of an array.
248*38fd1498Szrj    *  @param  __array  Array.
249*38fd1498Szrj    */
250*38fd1498Szrj   template <typename _Tp, size_t _Nm>
251*38fd1498Szrj     constexpr size_t
252*38fd1498Szrj     size(const _Tp (&/*__array*/)[_Nm]) noexcept
253*38fd1498Szrj     { return _Nm; }
254*38fd1498Szrj 
255*38fd1498Szrj   /**
256*38fd1498Szrj    *  @brief  Return whether a container is empty.
257*38fd1498Szrj    *  @param  __cont  Container.
258*38fd1498Szrj    */
259*38fd1498Szrj   template <typename _Container>
260*38fd1498Szrj     [[nodiscard]] constexpr auto
261*38fd1498Szrj     empty(const _Container& __cont) noexcept(noexcept(__cont.empty()))
262*38fd1498Szrj     -> decltype(__cont.empty())
263*38fd1498Szrj     { return __cont.empty(); }
264*38fd1498Szrj 
265*38fd1498Szrj   /**
266*38fd1498Szrj    *  @brief  Return whether an array is empty (always false).
267*38fd1498Szrj    *  @param  __array  Container.
268*38fd1498Szrj    */
269*38fd1498Szrj   template <typename _Tp, size_t _Nm>
270*38fd1498Szrj     [[nodiscard]] constexpr bool
271*38fd1498Szrj     empty(const _Tp (&/*__array*/)[_Nm]) noexcept
272*38fd1498Szrj     { return false; }
273*38fd1498Szrj 
274*38fd1498Szrj   /**
275*38fd1498Szrj    *  @brief  Return whether an initializer_list is empty.
276*38fd1498Szrj    *  @param  __il  Initializer list.
277*38fd1498Szrj    */
278*38fd1498Szrj   template <typename _Tp>
279*38fd1498Szrj     [[nodiscard]] constexpr bool
280*38fd1498Szrj     empty(initializer_list<_Tp> __il) noexcept
281*38fd1498Szrj     { return __il.size() == 0;}
282*38fd1498Szrj 
283*38fd1498Szrj   /**
284*38fd1498Szrj    *  @brief  Return the data pointer of a container.
285*38fd1498Szrj    *  @param  __cont  Container.
286*38fd1498Szrj    */
287*38fd1498Szrj   template <typename _Container>
288*38fd1498Szrj     constexpr auto
289*38fd1498Szrj     data(_Container& __cont) noexcept(noexcept(__cont.data()))
290*38fd1498Szrj     -> decltype(__cont.data())
291*38fd1498Szrj     { return __cont.data(); }
292*38fd1498Szrj 
293*38fd1498Szrj   /**
294*38fd1498Szrj    *  @brief  Return the data pointer of a const container.
295*38fd1498Szrj    *  @param  __cont  Container.
296*38fd1498Szrj    */
297*38fd1498Szrj   template <typename _Container>
298*38fd1498Szrj     constexpr auto
299*38fd1498Szrj     data(const _Container& __cont) noexcept(noexcept(__cont.data()))
300*38fd1498Szrj     -> decltype(__cont.data())
301*38fd1498Szrj     { return __cont.data(); }
302*38fd1498Szrj 
303*38fd1498Szrj   /**
304*38fd1498Szrj    *  @brief  Return the data pointer of an array.
305*38fd1498Szrj    *  @param  __array  Array.
306*38fd1498Szrj    */
307*38fd1498Szrj   template <typename _Tp, size_t _Nm>
308*38fd1498Szrj     constexpr _Tp*
309*38fd1498Szrj     data(_Tp (&__array)[_Nm]) noexcept
310*38fd1498Szrj     { return __array; }
311*38fd1498Szrj 
312*38fd1498Szrj   /**
313*38fd1498Szrj    *  @brief  Return the data pointer of an initializer list.
314*38fd1498Szrj    *  @param  __il  Initializer list.
315*38fd1498Szrj    */
316*38fd1498Szrj   template <typename _Tp>
317*38fd1498Szrj     constexpr const _Tp*
318*38fd1498Szrj     data(initializer_list<_Tp> __il) noexcept
319*38fd1498Szrj     { return __il.begin(); }
320*38fd1498Szrj 
321*38fd1498Szrj #endif // C++17
322*38fd1498Szrj 
323*38fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION
324*38fd1498Szrj } // namespace
325*38fd1498Szrj 
326*38fd1498Szrj #endif // C++11
327*38fd1498Szrj 
328*38fd1498Szrj #endif // _GLIBCXX_RANGE_ACCESS_H
329