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