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 | |
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 | |