Daily bump.
[gcc.git] / libstdc++-v3 / include / bits / range_access.h
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*>
200 rbegin(initializer_list<_Tp> __il)
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*>
210 rend(initializer_list<_Tp> __il)
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
280 empty(initializer_list<_Tp> __il) noexcept
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*
318 data(initializer_list<_Tp> __il) noexcept
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