1 | // <ranges> -*- C++ -*-
|
---|
2 |
|
---|
3 | // Copyright (C) 2019-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 include/ranges
|
---|
26 | * This is a Standard C++ Library header.
|
---|
27 | * @ingroup concepts
|
---|
28 | */
|
---|
29 |
|
---|
30 | #ifndef _GLIBCXX_RANGES
|
---|
31 | #define _GLIBCXX_RANGES 1
|
---|
32 |
|
---|
33 | #if __cplusplus > 201703L
|
---|
34 |
|
---|
35 | #pragma GCC system_header
|
---|
36 |
|
---|
37 | #include <concepts>
|
---|
38 |
|
---|
39 | #if __cpp_lib_concepts
|
---|
40 |
|
---|
41 | #include <compare>
|
---|
42 | #include <initializer_list>
|
---|
43 | #include <iterator>
|
---|
44 | #include <optional>
|
---|
45 | #include <tuple>
|
---|
46 | #include <bits/ranges_util.h>
|
---|
47 | #include <bits/refwrap.h>
|
---|
48 |
|
---|
49 | /**
|
---|
50 | * @defgroup ranges Ranges
|
---|
51 | *
|
---|
52 | * Components for dealing with ranges of elements.
|
---|
53 | */
|
---|
54 |
|
---|
55 | namespace std _GLIBCXX_VISIBILITY(default)
|
---|
56 | {
|
---|
57 | _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
---|
58 | namespace ranges
|
---|
59 | {
|
---|
60 | // [range.access] customization point objects
|
---|
61 | // [range.req] range and view concepts
|
---|
62 | // [range.dangling] dangling iterator handling
|
---|
63 | // Defined in <bits/ranges_base.h>
|
---|
64 |
|
---|
65 | // [view.interface] View interface
|
---|
66 | // [range.subrange] Sub-ranges
|
---|
67 | // Defined in <bits/ranges_util.h>
|
---|
68 |
|
---|
69 | // C++20 24.6 [range.factories] Range factories
|
---|
70 |
|
---|
71 | /// A view that contains no elements.
|
---|
72 | template<typename _Tp> requires is_object_v<_Tp>
|
---|
73 | class empty_view
|
---|
74 | : public view_interface<empty_view<_Tp>>
|
---|
75 | {
|
---|
76 | public:
|
---|
77 | static constexpr _Tp* begin() noexcept { return nullptr; }
|
---|
78 | static constexpr _Tp* end() noexcept { return nullptr; }
|
---|
79 | static constexpr _Tp* data() noexcept { return nullptr; }
|
---|
80 | static constexpr size_t size() noexcept { return 0; }
|
---|
81 | static constexpr bool empty() noexcept { return true; }
|
---|
82 | };
|
---|
83 |
|
---|
84 | template<typename _Tp>
|
---|
85 | inline constexpr bool enable_borrowed_range<empty_view<_Tp>> = true;
|
---|
86 |
|
---|
87 | namespace __detail
|
---|
88 | {
|
---|
89 | template<typename _Tp>
|
---|
90 | concept __boxable = copy_constructible<_Tp> && is_object_v<_Tp>;
|
---|
91 |
|
---|
92 | template<__boxable _Tp>
|
---|
93 | struct __box : std::optional<_Tp>
|
---|
94 | {
|
---|
95 | using std::optional<_Tp>::optional;
|
---|
96 |
|
---|
97 | constexpr
|
---|
98 | __box()
|
---|
99 | noexcept(is_nothrow_default_constructible_v<_Tp>)
|
---|
100 | requires default_initializable<_Tp>
|
---|
101 | : std::optional<_Tp>{std::in_place}
|
---|
102 | { }
|
---|
103 |
|
---|
104 | __box(const __box&) = default;
|
---|
105 | __box(__box&&) = default;
|
---|
106 |
|
---|
107 | using std::optional<_Tp>::operator=;
|
---|
108 |
|
---|
109 | // _GLIBCXX_RESOLVE_LIB_DEFECTS
|
---|
110 | // 3477. Simplify constraints for semiregular-box
|
---|
111 | __box&
|
---|
112 | operator=(const __box& __that)
|
---|
113 | noexcept(is_nothrow_copy_constructible_v<_Tp>)
|
---|
114 | requires (!copyable<_Tp>)
|
---|
115 | {
|
---|
116 | if ((bool)__that)
|
---|
117 | this->emplace(*__that);
|
---|
118 | else
|
---|
119 | this->reset();
|
---|
120 | return *this;
|
---|
121 | }
|
---|
122 |
|
---|
123 | __box&
|
---|
124 | operator=(__box&& __that)
|
---|
125 | noexcept(is_nothrow_move_constructible_v<_Tp>)
|
---|
126 | requires (!movable<_Tp>)
|
---|
127 | {
|
---|
128 | if ((bool)__that)
|
---|
129 | this->emplace(std::move(*__that));
|
---|
130 | else
|
---|
131 | this->reset();
|
---|
132 | return *this;
|
---|
133 | }
|
---|
134 | };
|
---|
135 |
|
---|
136 | // For types which are already semiregular, this specialization of the
|
---|
137 | // semiregular wrapper stores the object directly without going through
|
---|
138 | // std::optional. It provides just the subset of the primary template's
|
---|
139 | // API that we currently use.
|
---|
140 | template<__boxable _Tp> requires semiregular<_Tp>
|
---|
141 | struct __box<_Tp>
|
---|
142 | {
|
---|
143 | private:
|
---|
144 | [[no_unique_address]] _Tp _M_value = _Tp();
|
---|
145 |
|
---|
146 | public:
|
---|
147 | __box() = default;
|
---|
148 |
|
---|
149 | constexpr explicit
|
---|
150 | __box(const _Tp& __t)
|
---|
151 | noexcept(is_nothrow_copy_constructible_v<_Tp>)
|
---|
152 | : _M_value{__t}
|
---|
153 | { }
|
---|
154 |
|
---|
155 | constexpr explicit
|
---|
156 | __box(_Tp&& __t)
|
---|
157 | noexcept(is_nothrow_move_constructible_v<_Tp>)
|
---|
158 | : _M_value{std::move(__t)}
|
---|
159 | { }
|
---|
160 |
|
---|
161 | template<typename... _Args>
|
---|
162 | requires constructible_from<_Tp, _Args...>
|
---|
163 | constexpr explicit
|
---|
164 | __box(in_place_t, _Args&&... __args)
|
---|
165 | noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
|
---|
166 | : _M_value(std::forward<_Args>(__args)...)
|
---|
167 | { }
|
---|
168 |
|
---|
169 | constexpr bool
|
---|
170 | has_value() const noexcept
|
---|
171 | { return true; };
|
---|
172 |
|
---|
173 | constexpr _Tp&
|
---|
174 | operator*() noexcept
|
---|
175 | { return _M_value; }
|
---|
176 |
|
---|
177 | constexpr const _Tp&
|
---|
178 | operator*() const noexcept
|
---|
179 | { return _M_value; }
|
---|
180 |
|
---|
181 | constexpr _Tp*
|
---|
182 | operator->() noexcept
|
---|
183 | { return std::__addressof(_M_value); }
|
---|
184 |
|
---|
185 | constexpr const _Tp*
|
---|
186 | operator->() const noexcept
|
---|
187 | { return std::__addressof(_M_value); }
|
---|
188 | };
|
---|
189 | } // namespace __detail
|
---|
190 |
|
---|
191 | /// A view that contains exactly one element.
|
---|
192 | template<copy_constructible _Tp> requires is_object_v<_Tp>
|
---|
193 | class single_view : public view_interface<single_view<_Tp>>
|
---|
194 | {
|
---|
195 | public:
|
---|
196 | single_view() = default;
|
---|
197 |
|
---|
198 | constexpr explicit
|
---|
199 | single_view(const _Tp& __t)
|
---|
200 | : _M_value(__t)
|
---|
201 | { }
|
---|
202 |
|
---|
203 | constexpr explicit
|
---|
204 | single_view(_Tp&& __t)
|
---|
205 | : _M_value(std::move(__t))
|
---|
206 | { }
|
---|
207 |
|
---|
208 | // _GLIBCXX_RESOLVE_LIB_DEFECTS
|
---|
209 | // 3428. single_view's in place constructor should be explicit
|
---|
210 | template<typename... _Args>
|
---|
211 | requires constructible_from<_Tp, _Args...>
|
---|
212 | constexpr explicit
|
---|
213 | single_view(in_place_t, _Args&&... __args)
|
---|
214 | : _M_value{in_place, std::forward<_Args>(__args)...}
|
---|
215 | { }
|
---|
216 |
|
---|
217 | constexpr _Tp*
|
---|
218 | begin() noexcept
|
---|
219 | { return data(); }
|
---|
220 |
|
---|
221 | constexpr const _Tp*
|
---|
222 | begin() const noexcept
|
---|
223 | { return data(); }
|
---|
224 |
|
---|
225 | constexpr _Tp*
|
---|
226 | end() noexcept
|
---|
227 | { return data() + 1; }
|
---|
228 |
|
---|
229 | constexpr const _Tp*
|
---|
230 | end() const noexcept
|
---|
231 | { return data() + 1; }
|
---|
232 |
|
---|
233 | static constexpr size_t
|
---|
234 | size() noexcept
|
---|
235 | { return 1; }
|
---|
236 |
|
---|
237 | constexpr _Tp*
|
---|
238 | data() noexcept
|
---|
239 | { return _M_value.operator->(); }
|
---|
240 |
|
---|
241 | constexpr const _Tp*
|
---|
242 | data() const noexcept
|
---|
243 | { return _M_value.operator->(); }
|
---|
244 |
|
---|
245 | private:
|
---|
246 | [[no_unique_address]] __detail::__box<_Tp> _M_value;
|
---|
247 | };
|
---|
248 |
|
---|
249 | template<typename _Tp>
|
---|
250 | single_view(_Tp) -> single_view<_Tp>;
|
---|
251 |
|
---|
252 | namespace __detail
|
---|
253 | {
|
---|
254 | template<typename _Wp>
|
---|
255 | constexpr auto __to_signed_like(_Wp __w) noexcept
|
---|
256 | {
|
---|
257 | if constexpr (!integral<_Wp>)
|
---|
258 | return iter_difference_t<_Wp>();
|
---|
259 | else if constexpr (sizeof(iter_difference_t<_Wp>) > sizeof(_Wp))
|
---|
260 | return iter_difference_t<_Wp>(__w);
|
---|
261 | else if constexpr (sizeof(ptrdiff_t) > sizeof(_Wp))
|
---|
262 | return ptrdiff_t(__w);
|
---|
263 | else if constexpr (sizeof(long long) > sizeof(_Wp))
|
---|
264 | return (long long)(__w);
|
---|
265 | #ifdef __SIZEOF_INT128__
|
---|
266 | else if constexpr (__SIZEOF_INT128__ > sizeof(_Wp))
|
---|
267 | return __int128(__w);
|
---|
268 | #endif
|
---|
269 | else
|
---|
270 | return __max_diff_type(__w);
|
---|
271 | }
|
---|
272 |
|
---|
273 | template<typename _Wp>
|
---|
274 | using __iota_diff_t = decltype(__to_signed_like(std::declval<_Wp>()));
|
---|
275 |
|
---|
276 | template<typename _It>
|
---|
277 | concept __decrementable = incrementable<_It>
|
---|
278 | && requires(_It __i)
|
---|
279 | {
|
---|
280 | { --__i } -> same_as<_It&>;
|
---|
281 | { __i-- } -> same_as<_It>;
|
---|
282 | };
|
---|
283 |
|
---|
284 | template<typename _It>
|
---|
285 | concept __advanceable = __decrementable<_It> && totally_ordered<_It>
|
---|
286 | && requires( _It __i, const _It __j, const __iota_diff_t<_It> __n)
|
---|
287 | {
|
---|
288 | { __i += __n } -> same_as<_It&>;
|
---|
289 | { __i -= __n } -> same_as<_It&>;
|
---|
290 | _It(__j + __n);
|
---|
291 | _It(__n + __j);
|
---|
292 | _It(__j - __n);
|
---|
293 | { __j - __j } -> convertible_to<__iota_diff_t<_It>>;
|
---|
294 | };
|
---|
295 |
|
---|
296 | template<typename _Winc>
|
---|
297 | struct __iota_view_iter_cat
|
---|
298 | { };
|
---|
299 |
|
---|
300 | template<incrementable _Winc>
|
---|
301 | struct __iota_view_iter_cat<_Winc>
|
---|
302 | { using iterator_category = input_iterator_tag; };
|
---|
303 | } // namespace __detail
|
---|
304 |
|
---|
305 | template<weakly_incrementable _Winc,
|
---|
306 | semiregular _Bound = unreachable_sentinel_t>
|
---|
307 | requires std::__detail::__weakly_eq_cmp_with<_Winc, _Bound>
|
---|
308 | && semiregular<_Winc>
|
---|
309 | class iota_view : public view_interface<iota_view<_Winc, _Bound>>
|
---|
310 | {
|
---|
311 | private:
|
---|
312 | struct _Sentinel;
|
---|
313 |
|
---|
314 | struct _Iterator : __detail::__iota_view_iter_cat<_Winc>
|
---|
315 | {
|
---|
316 | private:
|
---|
317 | static auto
|
---|
318 | _S_iter_concept()
|
---|
319 | {
|
---|
320 | using namespace __detail;
|
---|
321 | if constexpr (__advanceable<_Winc>)
|
---|
322 | return random_access_iterator_tag{};
|
---|
323 | else if constexpr (__decrementable<_Winc>)
|
---|
324 | return bidirectional_iterator_tag{};
|
---|
325 | else if constexpr (incrementable<_Winc>)
|
---|
326 | return forward_iterator_tag{};
|
---|
327 | else
|
---|
328 | return input_iterator_tag{};
|
---|
329 | }
|
---|
330 |
|
---|
331 | public:
|
---|
332 | using iterator_concept = decltype(_S_iter_concept());
|
---|
333 | // iterator_category defined in __iota_view_iter_cat
|
---|
334 | using value_type = _Winc;
|
---|
335 | using difference_type = __detail::__iota_diff_t<_Winc>;
|
---|
336 |
|
---|
337 | _Iterator() = default;
|
---|
338 |
|
---|
339 | constexpr explicit
|
---|
340 | _Iterator(_Winc __value)
|
---|
341 | : _M_value(__value) { }
|
---|
342 |
|
---|
343 | constexpr _Winc
|
---|
344 | operator*() const noexcept(is_nothrow_copy_constructible_v<_Winc>)
|
---|
345 | { return _M_value; }
|
---|
346 |
|
---|
347 | constexpr _Iterator&
|
---|
348 | operator++()
|
---|
349 | {
|
---|
350 | ++_M_value;
|
---|
351 | return *this;
|
---|
352 | }
|
---|
353 |
|
---|
354 | constexpr void
|
---|
355 | operator++(int)
|
---|
356 | { ++*this; }
|
---|
357 |
|
---|
358 | constexpr _Iterator
|
---|
359 | operator++(int) requires incrementable<_Winc>
|
---|
360 | {
|
---|
361 | auto __tmp = *this;
|
---|
362 | ++*this;
|
---|
363 | return __tmp;
|
---|
364 | }
|
---|
365 |
|
---|
366 | constexpr _Iterator&
|
---|
367 | operator--() requires __detail::__decrementable<_Winc>
|
---|
368 | {
|
---|
369 | --_M_value;
|
---|
370 | return *this;
|
---|
371 | }
|
---|
372 |
|
---|
373 | constexpr _Iterator
|
---|
374 | operator--(int) requires __detail::__decrementable<_Winc>
|
---|
375 | {
|
---|
376 | auto __tmp = *this;
|
---|
377 | --*this;
|
---|
378 | return __tmp;
|
---|
379 | }
|
---|
380 |
|
---|
381 | constexpr _Iterator&
|
---|
382 | operator+=(difference_type __n) requires __detail::__advanceable<_Winc>
|
---|
383 | {
|
---|
384 | using __detail::__is_integer_like;
|
---|
385 | using __detail::__is_signed_integer_like;
|
---|
386 | if constexpr (__is_integer_like<_Winc>
|
---|
387 | && !__is_signed_integer_like<_Winc>)
|
---|
388 | {
|
---|
389 | if (__n >= difference_type(0))
|
---|
390 | _M_value += static_cast<_Winc>(__n);
|
---|
391 | else
|
---|
392 | _M_value -= static_cast<_Winc>(-__n);
|
---|
393 | }
|
---|
394 | else
|
---|
395 | _M_value += __n;
|
---|
396 | return *this;
|
---|
397 | }
|
---|
398 |
|
---|
399 | constexpr _Iterator&
|
---|
400 | operator-=(difference_type __n) requires __detail::__advanceable<_Winc>
|
---|
401 | {
|
---|
402 | using __detail::__is_integer_like;
|
---|
403 | using __detail::__is_signed_integer_like;
|
---|
404 | if constexpr (__is_integer_like<_Winc>
|
---|
405 | && !__is_signed_integer_like<_Winc>)
|
---|
406 | {
|
---|
407 | if (__n >= difference_type(0))
|
---|
408 | _M_value -= static_cast<_Winc>(__n);
|
---|
409 | else
|
---|
410 | _M_value += static_cast<_Winc>(-__n);
|
---|
411 | }
|
---|
412 | else
|
---|
413 | _M_value -= __n;
|
---|
414 | return *this;
|
---|
415 | }
|
---|
416 |
|
---|
417 | constexpr _Winc
|
---|
418 | operator[](difference_type __n) const
|
---|
419 | requires __detail::__advanceable<_Winc>
|
---|
420 | { return _Winc(_M_value + __n); }
|
---|
421 |
|
---|
422 | friend constexpr bool
|
---|
423 | operator==(const _Iterator& __x, const _Iterator& __y)
|
---|
424 | requires equality_comparable<_Winc>
|
---|
425 | { return __x._M_value == __y._M_value; }
|
---|
426 |
|
---|
427 | friend constexpr bool
|
---|
428 | operator<(const _Iterator& __x, const _Iterator& __y)
|
---|
429 | requires totally_ordered<_Winc>
|
---|
430 | { return __x._M_value < __y._M_value; }
|
---|
431 |
|
---|
432 | friend constexpr bool
|
---|
433 | operator>(const _Iterator& __x, const _Iterator& __y)
|
---|
434 | requires totally_ordered<_Winc>
|
---|
435 | { return __y < __x; }
|
---|
436 |
|
---|
437 | friend constexpr bool
|
---|
438 | operator<=(const _Iterator& __x, const _Iterator& __y)
|
---|
439 | requires totally_ordered<_Winc>
|
---|
440 | { return !(__y < __x); }
|
---|
441 |
|
---|
442 | friend constexpr bool
|
---|
443 | operator>=(const _Iterator& __x, const _Iterator& __y)
|
---|
444 | requires totally_ordered<_Winc>
|
---|
445 | { return !(__x < __y); }
|
---|
446 |
|
---|
447 | #ifdef __cpp_lib_three_way_comparison
|
---|
448 | friend constexpr auto
|
---|
449 | operator<=>(const _Iterator& __x, const _Iterator& __y)
|
---|
450 | requires totally_ordered<_Winc> && three_way_comparable<_Winc>
|
---|
451 | { return __x._M_value <=> __y._M_value; }
|
---|
452 | #endif
|
---|
453 |
|
---|
454 | friend constexpr _Iterator
|
---|
455 | operator+(_Iterator __i, difference_type __n)
|
---|
456 | requires __detail::__advanceable<_Winc>
|
---|
457 | { return __i += __n; }
|
---|
458 |
|
---|
459 | friend constexpr _Iterator
|
---|
460 | operator+(difference_type __n, _Iterator __i)
|
---|
461 | requires __detail::__advanceable<_Winc>
|
---|
462 | { return __i += __n; }
|
---|
463 |
|
---|
464 | friend constexpr _Iterator
|
---|
465 | operator-(_Iterator __i, difference_type __n)
|
---|
466 | requires __detail::__advanceable<_Winc>
|
---|
467 | { return __i -= __n; }
|
---|
468 |
|
---|
469 | friend constexpr difference_type
|
---|
470 | operator-(const _Iterator& __x, const _Iterator& __y)
|
---|
471 | requires __detail::__advanceable<_Winc>
|
---|
472 | {
|
---|
473 | using __detail::__is_integer_like;
|
---|
474 | using __detail::__is_signed_integer_like;
|
---|
475 | using _Dt = difference_type;
|
---|
476 | if constexpr (__is_integer_like<_Winc>)
|
---|
477 | {
|
---|
478 | if constexpr (__is_signed_integer_like<_Winc>)
|
---|
479 | return _Dt(_Dt(__x._M_value) - _Dt(__y._M_value));
|
---|
480 | else
|
---|
481 | return (__y._M_value > __x._M_value)
|
---|
482 | ? _Dt(-_Dt(__y._M_value - __x._M_value))
|
---|
483 | : _Dt(__x._M_value - __y._M_value);
|
---|
484 | }
|
---|
485 | else
|
---|
486 | return __x._M_value - __y._M_value;
|
---|
487 | }
|
---|
488 |
|
---|
489 | private:
|
---|
490 | _Winc _M_value = _Winc();
|
---|
491 |
|
---|
492 | friend _Sentinel;
|
---|
493 | };
|
---|
494 |
|
---|
495 | struct _Sentinel
|
---|
496 | {
|
---|
497 | private:
|
---|
498 | constexpr bool
|
---|
499 | _M_equal(const _Iterator& __x) const
|
---|
500 | { return __x._M_value == _M_bound; }
|
---|
501 |
|
---|
502 | constexpr auto
|
---|
503 | _M_distance_from(const _Iterator& __x) const
|
---|
504 | { return _M_bound - __x._M_value; }
|
---|
505 |
|
---|
506 | _Bound _M_bound = _Bound();
|
---|
507 |
|
---|
508 | public:
|
---|
509 | _Sentinel() = default;
|
---|
510 |
|
---|
511 | constexpr explicit
|
---|
512 | _Sentinel(_Bound __bound)
|
---|
513 | : _M_bound(__bound) { }
|
---|
514 |
|
---|
515 | friend constexpr bool
|
---|
516 | operator==(const _Iterator& __x, const _Sentinel& __y)
|
---|
517 | { return __y._M_equal(__x); }
|
---|
518 |
|
---|
519 | friend constexpr iter_difference_t<_Winc>
|
---|
520 | operator-(const _Iterator& __x, const _Sentinel& __y)
|
---|
521 | requires sized_sentinel_for<_Bound, _Winc>
|
---|
522 | { return -__y._M_distance_from(__x); }
|
---|
523 |
|
---|
524 | friend constexpr iter_difference_t<_Winc>
|
---|
525 | operator-(const _Sentinel& __x, const _Iterator& __y)
|
---|
526 | requires sized_sentinel_for<_Bound, _Winc>
|
---|
527 | { return __x._M_distance_from(__y); }
|
---|
528 | };
|
---|
529 |
|
---|
530 | _Winc _M_value = _Winc();
|
---|
531 | [[no_unique_address]] _Bound _M_bound = _Bound();
|
---|
532 |
|
---|
533 | public:
|
---|
534 | iota_view() = default;
|
---|
535 |
|
---|
536 | constexpr explicit
|
---|
537 | iota_view(_Winc __value)
|
---|
538 | : _M_value(__value)
|
---|
539 | { }
|
---|
540 |
|
---|
541 | constexpr
|
---|
542 | iota_view(type_identity_t<_Winc> __value,
|
---|
543 | type_identity_t<_Bound> __bound)
|
---|
544 | : _M_value(__value), _M_bound(__bound)
|
---|
545 | {
|
---|
546 | if constexpr (totally_ordered_with<_Winc, _Bound>)
|
---|
547 | __glibcxx_assert( bool(__value <= __bound) );
|
---|
548 | }
|
---|
549 |
|
---|
550 | constexpr _Iterator
|
---|
551 | begin() const { return _Iterator{_M_value}; }
|
---|
552 |
|
---|
553 | constexpr auto
|
---|
554 | end() const
|
---|
555 | {
|
---|
556 | if constexpr (same_as<_Bound, unreachable_sentinel_t>)
|
---|
557 | return unreachable_sentinel;
|
---|
558 | else
|
---|
559 | return _Sentinel{_M_bound};
|
---|
560 | }
|
---|
561 |
|
---|
562 | constexpr _Iterator
|
---|
563 | end() const requires same_as<_Winc, _Bound>
|
---|
564 | { return _Iterator{_M_bound}; }
|
---|
565 |
|
---|
566 | constexpr auto
|
---|
567 | size() const
|
---|
568 | requires (same_as<_Winc, _Bound> && __detail::__advanceable<_Winc>)
|
---|
569 | || (integral<_Winc> && integral<_Bound>)
|
---|
570 | || sized_sentinel_for<_Bound, _Winc>
|
---|
571 | {
|
---|
572 | using __detail::__is_integer_like;
|
---|
573 | using __detail::__to_unsigned_like;
|
---|
574 | if constexpr (integral<_Winc> && integral<_Bound>)
|
---|
575 | {
|
---|
576 | using _Up = make_unsigned_t<decltype(_M_bound - _M_value)>;
|
---|
577 | return _Up(_M_bound) - _Up(_M_value);
|
---|
578 | }
|
---|
579 | else if constexpr (__is_integer_like<_Winc>)
|
---|
580 | return __to_unsigned_like(_M_bound) - __to_unsigned_like(_M_value);
|
---|
581 | else
|
---|
582 | return __to_unsigned_like(_M_bound - _M_value);
|
---|
583 | }
|
---|
584 | };
|
---|
585 |
|
---|
586 | template<typename _Winc, typename _Bound>
|
---|
587 | requires (!__detail::__is_integer_like<_Winc>
|
---|
588 | || !__detail::__is_integer_like<_Bound>
|
---|
589 | || (__detail::__is_signed_integer_like<_Winc>
|
---|
590 | == __detail::__is_signed_integer_like<_Bound>))
|
---|
591 | iota_view(_Winc, _Bound) -> iota_view<_Winc, _Bound>;
|
---|
592 |
|
---|
593 | template<weakly_incrementable _Winc, semiregular _Bound>
|
---|
594 | inline constexpr bool
|
---|
595 | enable_borrowed_range<iota_view<_Winc, _Bound>> = true;
|
---|
596 |
|
---|
597 | namespace views
|
---|
598 | {
|
---|
599 | template<typename _Tp>
|
---|
600 | inline constexpr empty_view<_Tp> empty{};
|
---|
601 |
|
---|
602 | struct _Single
|
---|
603 | {
|
---|
604 | template<typename _Tp>
|
---|
605 | constexpr auto
|
---|
606 | operator()(_Tp&& __e) const
|
---|
607 | { return single_view<decay_t<_Tp>>(std::forward<_Tp>(__e)); }
|
---|
608 | };
|
---|
609 |
|
---|
610 | inline constexpr _Single single{};
|
---|
611 |
|
---|
612 | struct _Iota
|
---|
613 | {
|
---|
614 | template<typename _Tp>
|
---|
615 | constexpr auto
|
---|
616 | operator()(_Tp&& __e) const
|
---|
617 | { return iota_view(std::forward<_Tp>(__e)); }
|
---|
618 |
|
---|
619 | template<typename _Tp, typename _Up>
|
---|
620 | constexpr auto
|
---|
621 | operator()(_Tp&& __e, _Up&& __f) const
|
---|
622 | { return iota_view(std::forward<_Tp>(__e), std::forward<_Up>(__f)); }
|
---|
623 | };
|
---|
624 |
|
---|
625 | inline constexpr _Iota iota{};
|
---|
626 | } // namespace views
|
---|
627 |
|
---|
628 | namespace __detail
|
---|
629 | {
|
---|
630 | template<typename _Val, typename _CharT, typename _Traits>
|
---|
631 | concept __stream_extractable
|
---|
632 | = requires(basic_istream<_CharT, _Traits>& is, _Val& t) { is >> t; };
|
---|
633 | } // namespace __detail
|
---|
634 |
|
---|
635 | template<movable _Val, typename _CharT, typename _Traits>
|
---|
636 | requires default_initializable<_Val>
|
---|
637 | && __detail::__stream_extractable<_Val, _CharT, _Traits>
|
---|
638 | class basic_istream_view
|
---|
639 | : public view_interface<basic_istream_view<_Val, _CharT, _Traits>>
|
---|
640 | {
|
---|
641 | public:
|
---|
642 | basic_istream_view() = default;
|
---|
643 |
|
---|
644 | constexpr explicit
|
---|
645 | basic_istream_view(basic_istream<_CharT, _Traits>& __stream)
|
---|
646 | : _M_stream(std::__addressof(__stream))
|
---|
647 | { }
|
---|
648 |
|
---|
649 | constexpr auto
|
---|
650 | begin()
|
---|
651 | {
|
---|
652 | if (_M_stream != nullptr)
|
---|
653 | *_M_stream >> _M_object;
|
---|
654 | return _Iterator{this};
|
---|
655 | }
|
---|
656 |
|
---|
657 | constexpr default_sentinel_t
|
---|
658 | end() const noexcept
|
---|
659 | { return default_sentinel; }
|
---|
660 |
|
---|
661 | private:
|
---|
662 | basic_istream<_CharT, _Traits>* _M_stream = nullptr;
|
---|
663 | _Val _M_object = _Val();
|
---|
664 |
|
---|
665 | struct _Iterator
|
---|
666 | {
|
---|
667 | public:
|
---|
668 | using iterator_concept = input_iterator_tag;
|
---|
669 | using difference_type = ptrdiff_t;
|
---|
670 | using value_type = _Val;
|
---|
671 |
|
---|
672 | _Iterator() = default;
|
---|
673 |
|
---|
674 | constexpr explicit
|
---|
675 | _Iterator(basic_istream_view* __parent) noexcept
|
---|
676 | : _M_parent(__parent)
|
---|
677 | { }
|
---|
678 |
|
---|
679 | _Iterator(const _Iterator&) = delete;
|
---|
680 | _Iterator(_Iterator&&) = default;
|
---|
681 | _Iterator& operator=(const _Iterator&) = delete;
|
---|
682 | _Iterator& operator=(_Iterator&&) = default;
|
---|
683 |
|
---|
684 | _Iterator&
|
---|
685 | operator++()
|
---|
686 | {
|
---|
687 | __glibcxx_assert(_M_parent->_M_stream != nullptr);
|
---|
688 | *_M_parent->_M_stream >> _M_parent->_M_object;
|
---|
689 | return *this;
|
---|
690 | }
|
---|
691 |
|
---|
692 | void
|
---|
693 | operator++(int)
|
---|
694 | { ++*this; }
|
---|
695 |
|
---|
696 | _Val&
|
---|
697 | operator*() const
|
---|
698 | {
|
---|
699 | __glibcxx_assert(_M_parent->_M_stream != nullptr);
|
---|
700 | return _M_parent->_M_object;
|
---|
701 | }
|
---|
702 |
|
---|
703 | friend bool
|
---|
704 | operator==(const _Iterator& __x, default_sentinel_t)
|
---|
705 | { return __x._M_at_end(); }
|
---|
706 |
|
---|
707 | private:
|
---|
708 | basic_istream_view* _M_parent = nullptr;
|
---|
709 |
|
---|
710 | bool
|
---|
711 | _M_at_end() const
|
---|
712 | { return _M_parent == nullptr || !*_M_parent->_M_stream; }
|
---|
713 | };
|
---|
714 |
|
---|
715 | friend _Iterator;
|
---|
716 | };
|
---|
717 |
|
---|
718 | template<typename _Val, typename _CharT, typename _Traits>
|
---|
719 | basic_istream_view<_Val, _CharT, _Traits>
|
---|
720 | istream_view(basic_istream<_CharT, _Traits>& __s)
|
---|
721 | { return basic_istream_view<_Val, _CharT, _Traits>{__s}; }
|
---|
722 |
|
---|
723 | // C++20 24.7 [range.adaptors] Range adaptors
|
---|
724 |
|
---|
725 | namespace __detail
|
---|
726 | {
|
---|
727 | struct _Empty { };
|
---|
728 |
|
---|
729 | // Alias for a type that is conditionally present
|
---|
730 | // (and is an empty type otherwise).
|
---|
731 | // Data members using this alias should use [[no_unique_address]] so that
|
---|
732 | // they take no space when not needed.
|
---|
733 | template<bool _Present, typename _Tp>
|
---|
734 | using __maybe_present_t = conditional_t<_Present, _Tp, _Empty>;
|
---|
735 |
|
---|
736 | // Alias for a type that is conditionally const.
|
---|
737 | template<bool _Const, typename _Tp>
|
---|
738 | using __maybe_const_t = conditional_t<_Const, const _Tp, _Tp>;
|
---|
739 |
|
---|
740 | } // namespace __detail
|
---|
741 |
|
---|
742 | namespace views::__adaptor
|
---|
743 | {
|
---|
744 | // True if the range adaptor _Adaptor can be applied with _Args.
|
---|
745 | template<typename _Adaptor, typename... _Args>
|
---|
746 | concept __adaptor_invocable
|
---|
747 | = requires { std::declval<_Adaptor>()(declval<_Args>()...); };
|
---|
748 |
|
---|
749 | // True if the range adaptor non-closure _Adaptor can be partially applied
|
---|
750 | // with _Args.
|
---|
751 | template<typename _Adaptor, typename... _Args>
|
---|
752 | concept __adaptor_partial_app_viable = (_Adaptor::_S_arity > 1)
|
---|
753 | && (sizeof...(_Args) == _Adaptor::_S_arity - 1)
|
---|
754 | && (constructible_from<decay_t<_Args>, _Args> && ...);
|
---|
755 |
|
---|
756 | template<typename _Adaptor, typename... _Args>
|
---|
757 | struct _Partial;
|
---|
758 |
|
---|
759 | template<typename _Lhs, typename _Rhs>
|
---|
760 | struct _Pipe;
|
---|
761 |
|
---|
762 | // The base class of every range adaptor closure.
|
---|
763 | //
|
---|
764 | // The derived class should define the optional static data member
|
---|
765 | // _S_has_simple_call_op to true if the behavior of this adaptor is
|
---|
766 | // independent of the constness/value category of the adaptor object.
|
---|
767 | struct _RangeAdaptorClosure
|
---|
768 | {
|
---|
769 | // range | adaptor is equivalent to adaptor(range).
|
---|
770 | template<typename _Self, typename _Range>
|
---|
771 | requires derived_from<remove_cvref_t<_Self>, _RangeAdaptorClosure>
|
---|
772 | && __adaptor_invocable<_Self, _Range>
|
---|
773 | friend constexpr auto
|
---|
774 | operator|(_Range&& __r, _Self&& __self)
|
---|
775 | { return std::forward<_Self>(__self)(std::forward<_Range>(__r)); }
|
---|
776 |
|
---|
777 | // Compose the adaptors __lhs and __rhs into a pipeline, returning
|
---|
778 | // another range adaptor closure object.
|
---|
779 | template<typename _Lhs, typename _Rhs>
|
---|
780 | requires derived_from<_Lhs, _RangeAdaptorClosure>
|
---|
781 | && derived_from<_Rhs, _RangeAdaptorClosure>
|
---|
782 | friend constexpr auto
|
---|
783 | operator|(_Lhs __lhs, _Rhs __rhs)
|
---|
784 | { return _Pipe<_Lhs, _Rhs>{std::move(__lhs), std::move(__rhs)}; }
|
---|
785 | };
|
---|
786 |
|
---|
787 | // The base class of every range adaptor non-closure.
|
---|
788 | //
|
---|
789 | // The static data member _Derived::_S_arity must contain the total number of
|
---|
790 | // arguments that the adaptor takes, and the class _Derived must introduce
|
---|
791 | // _RangeAdaptor::operator() into the class scope via a using-declaration.
|
---|
792 | //
|
---|
793 | // The optional static data member _Derived::_S_has_simple_extra_args should
|
---|
794 | // be defined to true if the behavior of this adaptor is independent of the
|
---|
795 | // constness/value category of the extra arguments. This data member could
|
---|
796 | // also be defined as a variable template parameterized by the types of the
|
---|
797 | // extra arguments.
|
---|
798 | template<typename _Derived>
|
---|
799 | struct _RangeAdaptor
|
---|
800 | {
|
---|
801 | // Partially apply the arguments __args to the range adaptor _Derived,
|
---|
802 | // returning a range adaptor closure object.
|
---|
803 | template<typename... _Args>
|
---|
804 | requires __adaptor_partial_app_viable<_Derived, _Args...>
|
---|
805 | constexpr auto
|
---|
806 | operator()(_Args&&... __args) const
|
---|
807 | {
|
---|
808 | return _Partial<_Derived, decay_t<_Args>...>{std::forward<_Args>(__args)...};
|
---|
809 | }
|
---|
810 | };
|
---|
811 |
|
---|
812 | // True if the range adaptor closure _Adaptor has a simple operator(), i.e.
|
---|
813 | // one that's not overloaded according to constness or value category of the
|
---|
814 | // _Adaptor object.
|
---|
815 | template<typename _Adaptor>
|
---|
816 | concept __closure_has_simple_call_op = _Adaptor::_S_has_simple_call_op;
|
---|
817 |
|
---|
818 | // True if the behavior of the range adaptor non-closure _Adaptor is
|
---|
819 | // independent of the value category of its extra arguments _Args.
|
---|
820 | template<typename _Adaptor, typename... _Args>
|
---|
821 | concept __adaptor_has_simple_extra_args = _Adaptor::_S_has_simple_extra_args
|
---|
822 | || _Adaptor::template _S_has_simple_extra_args<_Args...>;
|
---|
823 |
|
---|
824 | // A range adaptor closure that represents partial application of
|
---|
825 | // the range adaptor _Adaptor with arguments _Args.
|
---|
826 | template<typename _Adaptor, typename... _Args>
|
---|
827 | struct _Partial : _RangeAdaptorClosure
|
---|
828 | {
|
---|
829 | tuple<_Args...> _M_args;
|
---|
830 |
|
---|
831 | constexpr
|
---|
832 | _Partial(_Args... __args)
|
---|
833 | : _M_args(std::move(__args)...)
|
---|
834 | { }
|
---|
835 |
|
---|
836 | // Invoke _Adaptor with arguments __r, _M_args... according to the
|
---|
837 | // value category of this _Partial object.
|
---|
838 | template<typename _Range>
|
---|
839 | requires __adaptor_invocable<_Adaptor, _Range, const _Args&...>
|
---|
840 | constexpr auto
|
---|
841 | operator()(_Range&& __r) const &
|
---|
842 | {
|
---|
843 | auto __forwarder = [&__r] (const auto&... __args) {
|
---|
844 | return _Adaptor{}(std::forward<_Range>(__r), __args...);
|
---|
845 | };
|
---|
846 | return std::apply(__forwarder, _M_args);
|
---|
847 | }
|
---|
848 |
|
---|
849 | template<typename _Range>
|
---|
850 | requires __adaptor_invocable<_Adaptor, _Range, _Args...>
|
---|
851 | constexpr auto
|
---|
852 | operator()(_Range&& __r) &&
|
---|
853 | {
|
---|
854 | auto __forwarder = [&__r] (auto&... __args) {
|
---|
855 | return _Adaptor{}(std::forward<_Range>(__r), std::move(__args)...);
|
---|
856 | };
|
---|
857 | return std::apply(__forwarder, _M_args);
|
---|
858 | }
|
---|
859 |
|
---|
860 | template<typename _Range>
|
---|
861 | constexpr auto
|
---|
862 | operator()(_Range&& __r) const && = delete;
|
---|
863 | };
|
---|
864 |
|
---|
865 | // A lightweight specialization of the above primary template for
|
---|
866 | // the common case where _Adaptor accepts a single extra argument.
|
---|
867 | template<typename _Adaptor, typename _Arg>
|
---|
868 | struct _Partial<_Adaptor, _Arg> : _RangeAdaptorClosure
|
---|
869 | {
|
---|
870 | _Arg _M_arg;
|
---|
871 |
|
---|
872 | constexpr
|
---|
873 | _Partial(_Arg __arg)
|
---|
874 | : _M_arg(std::move(__arg))
|
---|
875 | { }
|
---|
876 |
|
---|
877 | template<typename _Range>
|
---|
878 | requires __adaptor_invocable<_Adaptor, _Range, const _Arg&>
|
---|
879 | constexpr auto
|
---|
880 | operator()(_Range&& __r) const &
|
---|
881 | { return _Adaptor{}(std::forward<_Range>(__r), _M_arg); }
|
---|
882 |
|
---|
883 | template<typename _Range>
|
---|
884 | requires __adaptor_invocable<_Adaptor, _Range, _Arg>
|
---|
885 | constexpr auto
|
---|
886 | operator()(_Range&& __r) &&
|
---|
887 | { return _Adaptor{}(std::forward<_Range>(__r), std::move(_M_arg)); }
|
---|
888 |
|
---|
889 | template<typename _Range>
|
---|
890 | constexpr auto
|
---|
891 | operator()(_Range&& __r) const && = delete;
|
---|
892 | };
|
---|
893 |
|
---|
894 | // Partial specialization of the primary template for the case where the extra
|
---|
895 | // arguments of the adaptor can always be safely and efficiently forwarded by
|
---|
896 | // const reference. This lets us get away with a single operator() overload,
|
---|
897 | // which makes overload resolution failure diagnostics more concise.
|
---|
898 | template<typename _Adaptor, typename... _Args>
|
---|
899 | requires __adaptor_has_simple_extra_args<_Adaptor, _Args...>
|
---|
900 | && (is_trivially_copyable_v<_Args> && ...)
|
---|
901 | struct _Partial<_Adaptor, _Args...> : _RangeAdaptorClosure
|
---|
902 | {
|
---|
903 | tuple<_Args...> _M_args;
|
---|
904 |
|
---|
905 | constexpr
|
---|
906 | _Partial(_Args... __args)
|
---|
907 | : _M_args(std::move(__args)...)
|
---|
908 | { }
|
---|
909 |
|
---|
910 | // Invoke _Adaptor with arguments __r, const _M_args&... regardless
|
---|
911 | // of the value category of this _Partial object.
|
---|
912 | template<typename _Range>
|
---|
913 | requires __adaptor_invocable<_Adaptor, _Range, const _Args&...>
|
---|
914 | constexpr auto
|
---|
915 | operator()(_Range&& __r) const
|
---|
916 | {
|
---|
917 | auto __forwarder = [&__r] (const auto&... __args) {
|
---|
918 | return _Adaptor{}(std::forward<_Range>(__r), __args...);
|
---|
919 | };
|
---|
920 | return std::apply(__forwarder, _M_args);
|
---|
921 | }
|
---|
922 |
|
---|
923 | static constexpr bool _S_has_simple_call_op = true;
|
---|
924 | };
|
---|
925 |
|
---|
926 | // A lightweight specialization of the above template for the common case
|
---|
927 | // where _Adaptor accepts a single extra argument.
|
---|
928 | template<typename _Adaptor, typename _Arg>
|
---|
929 | requires __adaptor_has_simple_extra_args<_Adaptor, _Arg>
|
---|
930 | && is_trivially_copyable_v<_Arg>
|
---|
931 | struct _Partial<_Adaptor, _Arg> : _RangeAdaptorClosure
|
---|
932 | {
|
---|
933 | _Arg _M_arg;
|
---|
934 |
|
---|
935 | constexpr
|
---|
936 | _Partial(_Arg __arg)
|
---|
937 | : _M_arg(std::move(__arg))
|
---|
938 | { }
|
---|
939 |
|
---|
940 | template<typename _Range>
|
---|
941 | requires __adaptor_invocable<_Adaptor, _Range, const _Arg&>
|
---|
942 | constexpr auto
|
---|
943 | operator()(_Range&& __r) const
|
---|
944 | { return _Adaptor{}(std::forward<_Range>(__r), _M_arg); }
|
---|
945 |
|
---|
946 | static constexpr bool _S_has_simple_call_op = true;
|
---|
947 | };
|
---|
948 |
|
---|
949 | template<typename _Lhs, typename _Rhs, typename _Range>
|
---|
950 | concept __pipe_invocable
|
---|
951 | = requires { std::declval<_Rhs>()(std::declval<_Lhs>()(std::declval<_Range>())); };
|
---|
952 |
|
---|
953 | // A range adaptor closure that represents composition of the range
|
---|
954 | // adaptor closures _Lhs and _Rhs.
|
---|
955 | template<typename _Lhs, typename _Rhs>
|
---|
956 | struct _Pipe : _RangeAdaptorClosure
|
---|
957 | {
|
---|
958 | [[no_unique_address]] _Lhs _M_lhs;
|
---|
959 | [[no_unique_address]] _Rhs _M_rhs;
|
---|
960 |
|
---|
961 | constexpr
|
---|
962 | _Pipe(_Lhs __lhs, _Rhs __rhs)
|
---|
963 | : _M_lhs(std::move(__lhs)), _M_rhs(std::move(__rhs))
|
---|
964 | { }
|
---|
965 |
|
---|
966 | // Invoke _M_rhs(_M_lhs(__r)) according to the value category of this
|
---|
967 | // range adaptor closure object.
|
---|
968 | template<typename _Range>
|
---|
969 | requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
|
---|
970 | constexpr auto
|
---|
971 | operator()(_Range&& __r) const &
|
---|
972 | { return _M_rhs(_M_lhs(std::forward<_Range>(__r))); }
|
---|
973 |
|
---|
974 | template<typename _Range>
|
---|
975 | requires __pipe_invocable<_Lhs, _Rhs, _Range>
|
---|
976 | constexpr auto
|
---|
977 | operator()(_Range&& __r) &&
|
---|
978 | { return std::move(_M_rhs)(std::move(_M_lhs)(std::forward<_Range>(__r))); }
|
---|
979 |
|
---|
980 | template<typename _Range>
|
---|
981 | constexpr auto
|
---|
982 | operator()(_Range&& __r) const && = delete;
|
---|
983 | };
|
---|
984 |
|
---|
985 | // A partial specialization of the above primary template for the case where
|
---|
986 | // both adaptor operands have a simple operator(). This in turn lets us
|
---|
987 | // implement composition using a single simple operator(), which makes
|
---|
988 | // overload resolution failure diagnostics more concise.
|
---|
989 | template<typename _Lhs, typename _Rhs>
|
---|
990 | requires __closure_has_simple_call_op<_Lhs>
|
---|
991 | && __closure_has_simple_call_op<_Rhs>
|
---|
992 | struct _Pipe<_Lhs, _Rhs> : _RangeAdaptorClosure
|
---|
993 | {
|
---|
994 | [[no_unique_address]] _Lhs _M_lhs;
|
---|
995 | [[no_unique_address]] _Rhs _M_rhs;
|
---|
996 |
|
---|
997 | constexpr
|
---|
998 | _Pipe(_Lhs __lhs, _Rhs __rhs)
|
---|
999 | : _M_lhs(std::move(__lhs)), _M_rhs(std::move(__rhs))
|
---|
1000 | { }
|
---|
1001 |
|
---|
1002 | template<typename _Range>
|
---|
1003 | requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
|
---|
1004 | constexpr auto
|
---|
1005 | operator()(_Range&& __r) const
|
---|
1006 | { return _M_rhs(_M_lhs(std::forward<_Range>(__r))); }
|
---|
1007 |
|
---|
1008 | static constexpr bool _S_has_simple_call_op = true;
|
---|
1009 | };
|
---|
1010 | } // namespace views::__adaptor
|
---|
1011 |
|
---|
1012 | template<range _Range> requires is_object_v<_Range>
|
---|
1013 | class ref_view : public view_interface<ref_view<_Range>>
|
---|
1014 | {
|
---|
1015 | private:
|
---|
1016 | _Range* _M_r = nullptr;
|
---|
1017 |
|
---|
1018 | static void _S_fun(_Range&); // not defined
|
---|
1019 | static void _S_fun(_Range&&) = delete;
|
---|
1020 |
|
---|
1021 | public:
|
---|
1022 | constexpr
|
---|
1023 | ref_view() noexcept = default;
|
---|
1024 |
|
---|
1025 | template<__detail::__not_same_as<ref_view> _Tp>
|
---|
1026 | requires convertible_to<_Tp, _Range&>
|
---|
1027 | && requires { _S_fun(declval<_Tp>()); }
|
---|
1028 | constexpr
|
---|
1029 | ref_view(_Tp&& __t)
|
---|
1030 | : _M_r(std::__addressof(static_cast<_Range&>(std::forward<_Tp>(__t))))
|
---|
1031 | { }
|
---|
1032 |
|
---|
1033 | constexpr _Range&
|
---|
1034 | base() const
|
---|
1035 | { return *_M_r; }
|
---|
1036 |
|
---|
1037 | constexpr iterator_t<_Range>
|
---|
1038 | begin() const
|
---|
1039 | { return ranges::begin(*_M_r); }
|
---|
1040 |
|
---|
1041 | constexpr sentinel_t<_Range>
|
---|
1042 | end() const
|
---|
1043 | { return ranges::end(*_M_r); }
|
---|
1044 |
|
---|
1045 | constexpr bool
|
---|
1046 | empty() const requires requires { ranges::empty(*_M_r); }
|
---|
1047 | { return ranges::empty(*_M_r); }
|
---|
1048 |
|
---|
1049 | constexpr auto
|
---|
1050 | size() const requires sized_range<_Range>
|
---|
1051 | { return ranges::size(*_M_r); }
|
---|
1052 |
|
---|
1053 | constexpr auto
|
---|
1054 | data() const requires contiguous_range<_Range>
|
---|
1055 | { return ranges::data(*_M_r); }
|
---|
1056 | };
|
---|
1057 |
|
---|
1058 | template<typename _Range>
|
---|
1059 | ref_view(_Range&) -> ref_view<_Range>;
|
---|
1060 |
|
---|
1061 | template<typename _Tp>
|
---|
1062 | inline constexpr bool enable_borrowed_range<ref_view<_Tp>> = true;
|
---|
1063 |
|
---|
1064 | namespace views
|
---|
1065 | {
|
---|
1066 | namespace __detail
|
---|
1067 | {
|
---|
1068 | template<typename _Range>
|
---|
1069 | concept __can_ref_view = requires { ref_view{std::declval<_Range>()}; };
|
---|
1070 |
|
---|
1071 | template<typename _Range>
|
---|
1072 | concept __can_subrange = requires { subrange{std::declval<_Range>()}; };
|
---|
1073 | } // namespace __detail
|
---|
1074 |
|
---|
1075 | struct _All : __adaptor::_RangeAdaptorClosure
|
---|
1076 | {
|
---|
1077 | template<viewable_range _Range>
|
---|
1078 | requires view<decay_t<_Range>>
|
---|
1079 | || __detail::__can_ref_view<_Range>
|
---|
1080 | || __detail::__can_subrange<_Range>
|
---|
1081 | constexpr auto
|
---|
1082 | operator()(_Range&& __r) const
|
---|
1083 | {
|
---|
1084 | if constexpr (view<decay_t<_Range>>)
|
---|
1085 | return std::forward<_Range>(__r);
|
---|
1086 | else if constexpr (__detail::__can_ref_view<_Range>)
|
---|
1087 | return ref_view{std::forward<_Range>(__r)};
|
---|
1088 | else
|
---|
1089 | return subrange{std::forward<_Range>(__r)};
|
---|
1090 | }
|
---|
1091 |
|
---|
1092 | static constexpr bool _S_has_simple_call_op = true;
|
---|
1093 | };
|
---|
1094 |
|
---|
1095 | inline constexpr _All all;
|
---|
1096 |
|
---|
1097 | template<viewable_range _Range>
|
---|
1098 | using all_t = decltype(all(std::declval<_Range>()));
|
---|
1099 | } // namespace views
|
---|
1100 |
|
---|
1101 | // The following simple algos are transcribed from ranges_algo.h to avoid
|
---|
1102 | // having to include that entire header.
|
---|
1103 | namespace __detail
|
---|
1104 | {
|
---|
1105 | template<typename _Iter, typename _Sent, typename _Tp>
|
---|
1106 | constexpr _Iter
|
---|
1107 | find(_Iter __first, _Sent __last, const _Tp& __value)
|
---|
1108 | {
|
---|
1109 | while (__first != __last
|
---|
1110 | && !(bool)(*__first == __value))
|
---|
1111 | ++__first;
|
---|
1112 | return __first;
|
---|
1113 | }
|
---|
1114 |
|
---|
1115 | template<typename _Iter, typename _Sent, typename _Pred>
|
---|
1116 | constexpr _Iter
|
---|
1117 | find_if(_Iter __first, _Sent __last, _Pred __pred)
|
---|
1118 | {
|
---|
1119 | while (__first != __last
|
---|
1120 | && !(bool)std::__invoke(__pred, *__first))
|
---|
1121 | ++__first;
|
---|
1122 | return __first;
|
---|
1123 | }
|
---|
1124 |
|
---|
1125 | template<typename _Iter, typename _Sent, typename _Pred>
|
---|
1126 | constexpr _Iter
|
---|
1127 | find_if_not(_Iter __first, _Sent __last, _Pred __pred)
|
---|
1128 | {
|
---|
1129 | while (__first != __last
|
---|
1130 | && (bool)std::__invoke(__pred, *__first))
|
---|
1131 | ++__first;
|
---|
1132 | return __first;
|
---|
1133 | }
|
---|
1134 |
|
---|
1135 | template<typename _Iter1, typename _Sent1, typename _Iter2, typename _Sent2>
|
---|
1136 | constexpr pair<_Iter1, _Iter2>
|
---|
1137 | mismatch(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2)
|
---|
1138 | {
|
---|
1139 | while (__first1 != __last1 && __first2 != __last2
|
---|
1140 | && (bool)ranges::equal_to{}(*__first1, *__first2))
|
---|
1141 | {
|
---|
1142 | ++__first1;
|
---|
1143 | ++__first2;
|
---|
1144 | }
|
---|
1145 | return { std::move(__first1), std::move(__first2) };
|
---|
1146 | }
|
---|
1147 | } // namespace __detail
|
---|
1148 |
|
---|
1149 | namespace __detail
|
---|
1150 | {
|
---|
1151 | template<typename _Tp>
|
---|
1152 | struct __non_propagating_cache
|
---|
1153 | {
|
---|
1154 | // When _Tp is not an object type (e.g. is a reference type), we make
|
---|
1155 | // __non_propagating_cache<_Tp> empty rather than ill-formed so that
|
---|
1156 | // users can easily conditionally declare data members with this type
|
---|
1157 | // (such as join_view::_M_inner).
|
---|
1158 | };
|
---|
1159 |
|
---|
1160 | template<typename _Tp>
|
---|
1161 | requires is_object_v<_Tp>
|
---|
1162 | struct __non_propagating_cache<_Tp> : protected _Optional_base<_Tp>
|
---|
1163 | {
|
---|
1164 | __non_propagating_cache() = default;
|
---|
1165 |
|
---|
1166 | constexpr
|
---|
1167 | __non_propagating_cache(const __non_propagating_cache&) noexcept
|
---|
1168 | { }
|
---|
1169 |
|
---|
1170 | constexpr
|
---|
1171 | __non_propagating_cache(__non_propagating_cache&& __other) noexcept
|
---|
1172 | { __other._M_reset(); }
|
---|
1173 |
|
---|
1174 | constexpr __non_propagating_cache&
|
---|
1175 | operator=(const __non_propagating_cache& __other) noexcept
|
---|
1176 | {
|
---|
1177 | if (std::__addressof(__other) != this)
|
---|
1178 | this->_M_reset();
|
---|
1179 | return *this;
|
---|
1180 | }
|
---|
1181 |
|
---|
1182 | constexpr __non_propagating_cache&
|
---|
1183 | operator=(__non_propagating_cache&& __other) noexcept
|
---|
1184 | {
|
---|
1185 | this->_M_reset();
|
---|
1186 | __other._M_reset();
|
---|
1187 | return *this;
|
---|
1188 | }
|
---|
1189 |
|
---|
1190 | constexpr _Tp&
|
---|
1191 | operator*() noexcept
|
---|
1192 | { return this->_M_get(); }
|
---|
1193 |
|
---|
1194 | constexpr const _Tp&
|
---|
1195 | operator*() const noexcept
|
---|
1196 | { return this->_M_get(); }
|
---|
1197 |
|
---|
1198 | template<typename _Iter>
|
---|
1199 | _Tp&
|
---|
1200 | _M_emplace_deref(const _Iter& __i)
|
---|
1201 | {
|
---|
1202 | this->_M_reset();
|
---|
1203 | // Using _Optional_base::_M_construct to initialize from '*__i'
|
---|
1204 | // would incur an extra move due to the indirection, so we instead
|
---|
1205 | // use placement new directly.
|
---|
1206 | ::new ((void *) std::__addressof(this->_M_payload._M_payload)) _Tp(*__i);
|
---|
1207 | this->_M_payload._M_engaged = true;
|
---|
1208 | return this->_M_get();
|
---|
1209 | }
|
---|
1210 | };
|
---|
1211 |
|
---|
1212 | template<range _Range>
|
---|
1213 | struct _CachedPosition
|
---|
1214 | {
|
---|
1215 | constexpr bool
|
---|
1216 | _M_has_value() const
|
---|
1217 | { return false; }
|
---|
1218 |
|
---|
1219 | constexpr iterator_t<_Range>
|
---|
1220 | _M_get(const _Range&) const
|
---|
1221 | {
|
---|
1222 | __glibcxx_assert(false);
|
---|
1223 | return {};
|
---|
1224 | }
|
---|
1225 |
|
---|
1226 | constexpr void
|
---|
1227 | _M_set(const _Range&, const iterator_t<_Range>&) const
|
---|
1228 | { }
|
---|
1229 | };
|
---|
1230 |
|
---|
1231 | template<forward_range _Range>
|
---|
1232 | struct _CachedPosition<_Range>
|
---|
1233 | : protected __non_propagating_cache<iterator_t<_Range>>
|
---|
1234 | {
|
---|
1235 | constexpr bool
|
---|
1236 | _M_has_value() const
|
---|
1237 | { return this->_M_is_engaged(); }
|
---|
1238 |
|
---|
1239 | constexpr iterator_t<_Range>
|
---|
1240 | _M_get(const _Range&) const
|
---|
1241 | {
|
---|
1242 | __glibcxx_assert(_M_has_value());
|
---|
1243 | return **this;
|
---|
1244 | }
|
---|
1245 |
|
---|
1246 | constexpr void
|
---|
1247 | _M_set(const _Range&, const iterator_t<_Range>& __it)
|
---|
1248 | {
|
---|
1249 | __glibcxx_assert(!_M_has_value());
|
---|
1250 | std::construct_at(std::__addressof(this->_M_payload._M_payload),
|
---|
1251 | in_place, __it);
|
---|
1252 | this->_M_payload._M_engaged = true;
|
---|
1253 | }
|
---|
1254 | };
|
---|
1255 |
|
---|
1256 | template<random_access_range _Range>
|
---|
1257 | requires (sizeof(range_difference_t<_Range>)
|
---|
1258 | <= sizeof(iterator_t<_Range>))
|
---|
1259 | struct _CachedPosition<_Range>
|
---|
1260 | {
|
---|
1261 | private:
|
---|
1262 | range_difference_t<_Range> _M_offset = -1;
|
---|
1263 |
|
---|
1264 | public:
|
---|
1265 | _CachedPosition() = default;
|
---|
1266 |
|
---|
1267 | constexpr
|
---|
1268 | _CachedPosition(const _CachedPosition&) = default;
|
---|
1269 |
|
---|
1270 | constexpr
|
---|
1271 | _CachedPosition(_CachedPosition&& __other) noexcept
|
---|
1272 | { *this = std::move(__other); }
|
---|
1273 |
|
---|
1274 | constexpr _CachedPosition&
|
---|
1275 | operator=(const _CachedPosition&) = default;
|
---|
1276 |
|
---|
1277 | constexpr _CachedPosition&
|
---|
1278 | operator=(_CachedPosition&& __other) noexcept
|
---|
1279 | {
|
---|
1280 | // Propagate the cached offset, but invalidate the source.
|
---|
1281 | _M_offset = __other._M_offset;
|
---|
1282 | __other._M_offset = -1;
|
---|
1283 | return *this;
|
---|
1284 | }
|
---|
1285 |
|
---|
1286 | constexpr bool
|
---|
1287 | _M_has_value() const
|
---|
1288 | { return _M_offset >= 0; }
|
---|
1289 |
|
---|
1290 | constexpr iterator_t<_Range>
|
---|
1291 | _M_get(_Range& __r) const
|
---|
1292 | {
|
---|
1293 | __glibcxx_assert(_M_has_value());
|
---|
1294 | return ranges::begin(__r) + _M_offset;
|
---|
1295 | }
|
---|
1296 |
|
---|
1297 | constexpr void
|
---|
1298 | _M_set(_Range& __r, const iterator_t<_Range>& __it)
|
---|
1299 | {
|
---|
1300 | __glibcxx_assert(!_M_has_value());
|
---|
1301 | _M_offset = __it - ranges::begin(__r);
|
---|
1302 | }
|
---|
1303 | };
|
---|
1304 | } // namespace __detail
|
---|
1305 |
|
---|
1306 | namespace __detail
|
---|
1307 | {
|
---|
1308 | template<typename _Base>
|
---|
1309 | struct __filter_view_iter_cat
|
---|
1310 | { };
|
---|
1311 |
|
---|
1312 | template<forward_range _Base>
|
---|
1313 | struct __filter_view_iter_cat<_Base>
|
---|
1314 | {
|
---|
1315 | private:
|
---|
1316 | static auto
|
---|
1317 | _S_iter_cat()
|
---|
1318 | {
|
---|
1319 | using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
|
---|
1320 | if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
|
---|
1321 | return bidirectional_iterator_tag{};
|
---|
1322 | else if constexpr (derived_from<_Cat, forward_iterator_tag>)
|
---|
1323 | return forward_iterator_tag{};
|
---|
1324 | else
|
---|
1325 | return _Cat{};
|
---|
1326 | }
|
---|
1327 | public:
|
---|
1328 | using iterator_category = decltype(_S_iter_cat());
|
---|
1329 | };
|
---|
1330 | } // namespace __detail
|
---|
1331 |
|
---|
1332 | template<input_range _Vp,
|
---|
1333 | indirect_unary_predicate<iterator_t<_Vp>> _Pred>
|
---|
1334 | requires view<_Vp> && is_object_v<_Pred>
|
---|
1335 | class filter_view : public view_interface<filter_view<_Vp, _Pred>>
|
---|
1336 | {
|
---|
1337 | private:
|
---|
1338 | struct _Sentinel;
|
---|
1339 |
|
---|
1340 | struct _Iterator : __detail::__filter_view_iter_cat<_Vp>
|
---|
1341 | {
|
---|
1342 | private:
|
---|
1343 | static constexpr auto
|
---|
1344 | _S_iter_concept()
|
---|
1345 | {
|
---|
1346 | if constexpr (bidirectional_range<_Vp>)
|
---|
1347 | return bidirectional_iterator_tag{};
|
---|
1348 | else if constexpr (forward_range<_Vp>)
|
---|
1349 | return forward_iterator_tag{};
|
---|
1350 | else
|
---|
1351 | return input_iterator_tag{};
|
---|
1352 | }
|
---|
1353 |
|
---|
1354 | friend filter_view;
|
---|
1355 |
|
---|
1356 | using _Vp_iter = iterator_t<_Vp>;
|
---|
1357 |
|
---|
1358 | _Vp_iter _M_current = _Vp_iter();
|
---|
1359 | filter_view* _M_parent = nullptr;
|
---|
1360 |
|
---|
1361 | public:
|
---|
1362 | using iterator_concept = decltype(_S_iter_concept());
|
---|
1363 | // iterator_category defined in __filter_view_iter_cat
|
---|
1364 | using value_type = range_value_t<_Vp>;
|
---|
1365 | using difference_type = range_difference_t<_Vp>;
|
---|
1366 |
|
---|
1367 | _Iterator() = default;
|
---|
1368 |
|
---|
1369 | constexpr
|
---|
1370 | _Iterator(filter_view* __parent, _Vp_iter __current)
|
---|
1371 | : _M_current(std::move(__current)),
|
---|
1372 | _M_parent(__parent)
|
---|
1373 | { }
|
---|
1374 |
|
---|
1375 | constexpr const _Vp_iter&
|
---|
1376 | base() const & noexcept
|
---|
1377 | { return _M_current; }
|
---|
1378 |
|
---|
1379 | constexpr _Vp_iter
|
---|
1380 | base() &&
|
---|
1381 | { return std::move(_M_current); }
|
---|
1382 |
|
---|
1383 | constexpr range_reference_t<_Vp>
|
---|
1384 | operator*() const
|
---|
1385 | { return *_M_current; }
|
---|
1386 |
|
---|
1387 | constexpr _Vp_iter
|
---|
1388 | operator->() const
|
---|
1389 | requires __detail::__has_arrow<_Vp_iter>
|
---|
1390 | && copyable<_Vp_iter>
|
---|
1391 | { return _M_current; }
|
---|
1392 |
|
---|
1393 | constexpr _Iterator&
|
---|
1394 | operator++()
|
---|
1395 | {
|
---|
1396 | _M_current = __detail::find_if(std::move(++_M_current),
|
---|
1397 | ranges::end(_M_parent->_M_base),
|
---|
1398 | std::ref(*_M_parent->_M_pred));
|
---|
1399 | return *this;
|
---|
1400 | }
|
---|
1401 |
|
---|
1402 | constexpr void
|
---|
1403 | operator++(int)
|
---|
1404 | { ++*this; }
|
---|
1405 |
|
---|
1406 | constexpr _Iterator
|
---|
1407 | operator++(int) requires forward_range<_Vp>
|
---|
1408 | {
|
---|
1409 | auto __tmp = *this;
|
---|
1410 | ++*this;
|
---|
1411 | return __tmp;
|
---|
1412 | }
|
---|
1413 |
|
---|
1414 | constexpr _Iterator&
|
---|
1415 | operator--() requires bidirectional_range<_Vp>
|
---|
1416 | {
|
---|
1417 | do
|
---|
1418 | --_M_current;
|
---|
1419 | while (!std::__invoke(*_M_parent->_M_pred, *_M_current));
|
---|
1420 | return *this;
|
---|
1421 | }
|
---|
1422 |
|
---|
1423 | constexpr _Iterator
|
---|
1424 | operator--(int) requires bidirectional_range<_Vp>
|
---|
1425 | {
|
---|
1426 | auto __tmp = *this;
|
---|
1427 | --*this;
|
---|
1428 | return __tmp;
|
---|
1429 | }
|
---|
1430 |
|
---|
1431 | friend constexpr bool
|
---|
1432 | operator==(const _Iterator& __x, const _Iterator& __y)
|
---|
1433 | requires equality_comparable<_Vp_iter>
|
---|
1434 | { return __x._M_current == __y._M_current; }
|
---|
1435 |
|
---|
1436 | friend constexpr range_rvalue_reference_t<_Vp>
|
---|
1437 | iter_move(const _Iterator& __i)
|
---|
1438 | noexcept(noexcept(ranges::iter_move(__i._M_current)))
|
---|
1439 | { return ranges::iter_move(__i._M_current); }
|
---|
1440 |
|
---|
1441 | friend constexpr void
|
---|
1442 | iter_swap(const _Iterator& __x, const _Iterator& __y)
|
---|
1443 | noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
|
---|
1444 | requires indirectly_swappable<_Vp_iter>
|
---|
1445 | { ranges::iter_swap(__x._M_current, __y._M_current); }
|
---|
1446 | };
|
---|
1447 |
|
---|
1448 | struct _Sentinel
|
---|
1449 | {
|
---|
1450 | private:
|
---|
1451 | sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
|
---|
1452 |
|
---|
1453 | constexpr bool
|
---|
1454 | __equal(const _Iterator& __i) const
|
---|
1455 | { return __i._M_current == _M_end; }
|
---|
1456 |
|
---|
1457 | public:
|
---|
1458 | _Sentinel() = default;
|
---|
1459 |
|
---|
1460 | constexpr explicit
|
---|
1461 | _Sentinel(filter_view* __parent)
|
---|
1462 | : _M_end(ranges::end(__parent->_M_base))
|
---|
1463 | { }
|
---|
1464 |
|
---|
1465 | constexpr sentinel_t<_Vp>
|
---|
1466 | base() const
|
---|
1467 | { return _M_end; }
|
---|
1468 |
|
---|
1469 | friend constexpr bool
|
---|
1470 | operator==(const _Iterator& __x, const _Sentinel& __y)
|
---|
1471 | { return __y.__equal(__x); }
|
---|
1472 | };
|
---|
1473 |
|
---|
1474 | [[no_unique_address]] __detail::__box<_Pred> _M_pred;
|
---|
1475 | [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
|
---|
1476 | _Vp _M_base = _Vp();
|
---|
1477 |
|
---|
1478 | public:
|
---|
1479 | filter_view() = default;
|
---|
1480 |
|
---|
1481 | constexpr
|
---|
1482 | filter_view(_Vp __base, _Pred __pred)
|
---|
1483 | : _M_pred(std::move(__pred)), _M_base(std::move(__base))
|
---|
1484 | { }
|
---|
1485 |
|
---|
1486 | constexpr _Vp
|
---|
1487 | base() const& requires copy_constructible<_Vp>
|
---|
1488 | { return _M_base; }
|
---|
1489 |
|
---|
1490 | constexpr _Vp
|
---|
1491 | base() &&
|
---|
1492 | { return std::move(_M_base); }
|
---|
1493 |
|
---|
1494 | constexpr const _Pred&
|
---|
1495 | pred() const
|
---|
1496 | { return *_M_pred; }
|
---|
1497 |
|
---|
1498 | constexpr _Iterator
|
---|
1499 | begin()
|
---|
1500 | {
|
---|
1501 | if (_M_cached_begin._M_has_value())
|
---|
1502 | return {this, _M_cached_begin._M_get(_M_base)};
|
---|
1503 |
|
---|
1504 | __glibcxx_assert(_M_pred.has_value());
|
---|
1505 | auto __it = __detail::find_if(ranges::begin(_M_base),
|
---|
1506 | ranges::end(_M_base),
|
---|
1507 | std::ref(*_M_pred));
|
---|
1508 | _M_cached_begin._M_set(_M_base, __it);
|
---|
1509 | return {this, std::move(__it)};
|
---|
1510 | }
|
---|
1511 |
|
---|
1512 | constexpr auto
|
---|
1513 | end()
|
---|
1514 | {
|
---|
1515 | if constexpr (common_range<_Vp>)
|
---|
1516 | return _Iterator{this, ranges::end(_M_base)};
|
---|
1517 | else
|
---|
1518 | return _Sentinel{this};
|
---|
1519 | }
|
---|
1520 | };
|
---|
1521 |
|
---|
1522 | template<typename _Range, typename _Pred>
|
---|
1523 | filter_view(_Range&&, _Pred) -> filter_view<views::all_t<_Range>, _Pred>;
|
---|
1524 |
|
---|
1525 | namespace views
|
---|
1526 | {
|
---|
1527 | namespace __detail
|
---|
1528 | {
|
---|
1529 | template<typename _Range, typename _Pred>
|
---|
1530 | concept __can_filter_view
|
---|
1531 | = requires { filter_view(std::declval<_Range>(), std::declval<_Pred>()); };
|
---|
1532 | } // namespace __detail
|
---|
1533 |
|
---|
1534 | struct _Filter : __adaptor::_RangeAdaptor<_Filter>
|
---|
1535 | {
|
---|
1536 | template<viewable_range _Range, typename _Pred>
|
---|
1537 | requires __detail::__can_filter_view<_Range, _Pred>
|
---|
1538 | constexpr auto
|
---|
1539 | operator()(_Range&& __r, _Pred&& __p) const
|
---|
1540 | {
|
---|
1541 | return filter_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
|
---|
1542 | }
|
---|
1543 |
|
---|
1544 | using _RangeAdaptor<_Filter>::operator();
|
---|
1545 | static constexpr int _S_arity = 2;
|
---|
1546 | static constexpr bool _S_has_simple_extra_args = true;
|
---|
1547 | };
|
---|
1548 |
|
---|
1549 | inline constexpr _Filter filter;
|
---|
1550 | } // namespace views
|
---|
1551 |
|
---|
1552 | template<input_range _Vp, copy_constructible _Fp>
|
---|
1553 | requires view<_Vp> && is_object_v<_Fp>
|
---|
1554 | && regular_invocable<_Fp&, range_reference_t<_Vp>>
|
---|
1555 | && std::__detail::__can_reference<invoke_result_t<_Fp&,
|
---|
1556 | range_reference_t<_Vp>>>
|
---|
1557 | class transform_view : public view_interface<transform_view<_Vp, _Fp>>
|
---|
1558 | {
|
---|
1559 | private:
|
---|
1560 | template<bool _Const>
|
---|
1561 | using _Base = __detail::__maybe_const_t<_Const, _Vp>;
|
---|
1562 |
|
---|
1563 | template<bool _Const>
|
---|
1564 | struct __iter_cat
|
---|
1565 | { };
|
---|
1566 |
|
---|
1567 | template<bool _Const>
|
---|
1568 | requires forward_range<_Base<_Const>>
|
---|
1569 | struct __iter_cat<_Const>
|
---|
1570 | {
|
---|
1571 | private:
|
---|
1572 | static auto
|
---|
1573 | _S_iter_cat()
|
---|
1574 | {
|
---|
1575 | using _Base = transform_view::_Base<_Const>;
|
---|
1576 | using _Res = invoke_result_t<_Fp&, range_reference_t<_Base>>;
|
---|
1577 | if constexpr (is_lvalue_reference_v<_Res>)
|
---|
1578 | {
|
---|
1579 | using _Cat
|
---|
1580 | = typename iterator_traits<iterator_t<_Base>>::iterator_category;
|
---|
1581 | if constexpr (derived_from<_Cat, contiguous_iterator_tag>)
|
---|
1582 | return random_access_iterator_tag{};
|
---|
1583 | else
|
---|
1584 | return _Cat{};
|
---|
1585 | }
|
---|
1586 | else
|
---|
1587 | return input_iterator_tag{};
|
---|
1588 | }
|
---|
1589 | public:
|
---|
1590 | using iterator_category = decltype(_S_iter_cat());
|
---|
1591 | };
|
---|
1592 |
|
---|
1593 | template<bool _Const>
|
---|
1594 | struct _Sentinel;
|
---|
1595 |
|
---|
1596 | template<bool _Const>
|
---|
1597 | struct _Iterator : __iter_cat<_Const>
|
---|
1598 | {
|
---|
1599 | private:
|
---|
1600 | using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
|
---|
1601 | using _Base = transform_view::_Base<_Const>;
|
---|
1602 |
|
---|
1603 | static auto
|
---|
1604 | _S_iter_concept()
|
---|
1605 | {
|
---|
1606 | if constexpr (random_access_range<_Vp>)
|
---|
1607 | return random_access_iterator_tag{};
|
---|
1608 | else if constexpr (bidirectional_range<_Vp>)
|
---|
1609 | return bidirectional_iterator_tag{};
|
---|
1610 | else if constexpr (forward_range<_Vp>)
|
---|
1611 | return forward_iterator_tag{};
|
---|
1612 | else
|
---|
1613 | return input_iterator_tag{};
|
---|
1614 | }
|
---|
1615 |
|
---|
1616 | using _Base_iter = iterator_t<_Base>;
|
---|
1617 |
|
---|
1618 | _Base_iter _M_current = _Base_iter();
|
---|
1619 | _Parent* _M_parent = nullptr;
|
---|
1620 |
|
---|
1621 | public:
|
---|
1622 | using iterator_concept = decltype(_S_iter_concept());
|
---|
1623 | // iterator_category defined in __transform_view_iter_cat
|
---|
1624 | using value_type
|
---|
1625 | = remove_cvref_t<invoke_result_t<_Fp&, range_reference_t<_Base>>>;
|
---|
1626 | using difference_type = range_difference_t<_Base>;
|
---|
1627 |
|
---|
1628 | _Iterator() = default;
|
---|
1629 |
|
---|
1630 | constexpr
|
---|
1631 | _Iterator(_Parent* __parent, _Base_iter __current)
|
---|
1632 | : _M_current(std::move(__current)),
|
---|
1633 | _M_parent(__parent)
|
---|
1634 | { }
|
---|
1635 |
|
---|
1636 | constexpr
|
---|
1637 | _Iterator(_Iterator<!_Const> __i)
|
---|
1638 | requires _Const
|
---|
1639 | && convertible_to<iterator_t<_Vp>, _Base_iter>
|
---|
1640 | : _M_current(std::move(__i._M_current)), _M_parent(__i._M_parent)
|
---|
1641 | { }
|
---|
1642 |
|
---|
1643 | constexpr const _Base_iter&
|
---|
1644 | base() const & noexcept
|
---|
1645 | { return _M_current; }
|
---|
1646 |
|
---|
1647 | constexpr _Base_iter
|
---|
1648 | base() &&
|
---|
1649 | { return std::move(_M_current); }
|
---|
1650 |
|
---|
1651 | constexpr decltype(auto)
|
---|
1652 | operator*() const
|
---|
1653 | noexcept(noexcept(std::__invoke(*_M_parent->_M_fun, *_M_current)))
|
---|
1654 | { return std::__invoke(*_M_parent->_M_fun, *_M_current); }
|
---|
1655 |
|
---|
1656 | constexpr _Iterator&
|
---|
1657 | operator++()
|
---|
1658 | {
|
---|
1659 | ++_M_current;
|
---|
1660 | return *this;
|
---|
1661 | }
|
---|
1662 |
|
---|
1663 | constexpr void
|
---|
1664 | operator++(int)
|
---|
1665 | { ++_M_current; }
|
---|
1666 |
|
---|
1667 | constexpr _Iterator
|
---|
1668 | operator++(int) requires forward_range<_Base>
|
---|
1669 | {
|
---|
1670 | auto __tmp = *this;
|
---|
1671 | ++*this;
|
---|
1672 | return __tmp;
|
---|
1673 | }
|
---|
1674 |
|
---|
1675 | constexpr _Iterator&
|
---|
1676 | operator--() requires bidirectional_range<_Base>
|
---|
1677 | {
|
---|
1678 | --_M_current;
|
---|
1679 | return *this;
|
---|
1680 | }
|
---|
1681 |
|
---|
1682 | constexpr _Iterator
|
---|
1683 | operator--(int) requires bidirectional_range<_Base>
|
---|
1684 | {
|
---|
1685 | auto __tmp = *this;
|
---|
1686 | --*this;
|
---|
1687 | return __tmp;
|
---|
1688 | }
|
---|
1689 |
|
---|
1690 | constexpr _Iterator&
|
---|
1691 | operator+=(difference_type __n) requires random_access_range<_Base>
|
---|
1692 | {
|
---|
1693 | _M_current += __n;
|
---|
1694 | return *this;
|
---|
1695 | }
|
---|
1696 |
|
---|
1697 | constexpr _Iterator&
|
---|
1698 | operator-=(difference_type __n) requires random_access_range<_Base>
|
---|
1699 | {
|
---|
1700 | _M_current -= __n;
|
---|
1701 | return *this;
|
---|
1702 | }
|
---|
1703 |
|
---|
1704 | constexpr decltype(auto)
|
---|
1705 | operator[](difference_type __n) const
|
---|
1706 | requires random_access_range<_Base>
|
---|
1707 | { return std::__invoke(*_M_parent->_M_fun, _M_current[__n]); }
|
---|
1708 |
|
---|
1709 | friend constexpr bool
|
---|
1710 | operator==(const _Iterator& __x, const _Iterator& __y)
|
---|
1711 | requires equality_comparable<_Base_iter>
|
---|
1712 | { return __x._M_current == __y._M_current; }
|
---|
1713 |
|
---|
1714 | friend constexpr bool
|
---|
1715 | operator<(const _Iterator& __x, const _Iterator& __y)
|
---|
1716 | requires random_access_range<_Base>
|
---|
1717 | { return __x._M_current < __y._M_current; }
|
---|
1718 |
|
---|
1719 | friend constexpr bool
|
---|
1720 | operator>(const _Iterator& __x, const _Iterator& __y)
|
---|
1721 | requires random_access_range<_Base>
|
---|
1722 | { return __y < __x; }
|
---|
1723 |
|
---|
1724 | friend constexpr bool
|
---|
1725 | operator<=(const _Iterator& __x, const _Iterator& __y)
|
---|
1726 | requires random_access_range<_Base>
|
---|
1727 | { return !(__y < __x); }
|
---|
1728 |
|
---|
1729 | friend constexpr bool
|
---|
1730 | operator>=(const _Iterator& __x, const _Iterator& __y)
|
---|
1731 | requires random_access_range<_Base>
|
---|
1732 | { return !(__x < __y); }
|
---|
1733 |
|
---|
1734 | #ifdef __cpp_lib_three_way_comparison
|
---|
1735 | friend constexpr auto
|
---|
1736 | operator<=>(const _Iterator& __x, const _Iterator& __y)
|
---|
1737 | requires random_access_range<_Base>
|
---|
1738 | && three_way_comparable<_Base_iter>
|
---|
1739 | { return __x._M_current <=> __y._M_current; }
|
---|
1740 | #endif
|
---|
1741 |
|
---|
1742 | friend constexpr _Iterator
|
---|
1743 | operator+(_Iterator __i, difference_type __n)
|
---|
1744 | requires random_access_range<_Base>
|
---|
1745 | { return {__i._M_parent, __i._M_current + __n}; }
|
---|
1746 |
|
---|
1747 | friend constexpr _Iterator
|
---|
1748 | operator+(difference_type __n, _Iterator __i)
|
---|
1749 | requires random_access_range<_Base>
|
---|
1750 | { return {__i._M_parent, __i._M_current + __n}; }
|
---|
1751 |
|
---|
1752 | friend constexpr _Iterator
|
---|
1753 | operator-(_Iterator __i, difference_type __n)
|
---|
1754 | requires random_access_range<_Base>
|
---|
1755 | { return {__i._M_parent, __i._M_current - __n}; }
|
---|
1756 |
|
---|
1757 | // _GLIBCXX_RESOLVE_LIB_DEFECTS
|
---|
1758 | // 3483. transform_view::iterator's difference is overconstrained
|
---|
1759 | friend constexpr difference_type
|
---|
1760 | operator-(const _Iterator& __x, const _Iterator& __y)
|
---|
1761 | requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
|
---|
1762 | { return __x._M_current - __y._M_current; }
|
---|
1763 |
|
---|
1764 | friend constexpr decltype(auto)
|
---|
1765 | iter_move(const _Iterator& __i) noexcept(noexcept(*__i))
|
---|
1766 | {
|
---|
1767 | if constexpr (is_lvalue_reference_v<decltype(*__i)>)
|
---|
1768 | return std::move(*__i);
|
---|
1769 | else
|
---|
1770 | return *__i;
|
---|
1771 | }
|
---|
1772 |
|
---|
1773 | friend _Iterator<!_Const>;
|
---|
1774 | template<bool> friend struct _Sentinel;
|
---|
1775 | };
|
---|
1776 |
|
---|
1777 | template<bool _Const>
|
---|
1778 | struct _Sentinel
|
---|
1779 | {
|
---|
1780 | private:
|
---|
1781 | using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
|
---|
1782 | using _Base = transform_view::_Base<_Const>;
|
---|
1783 |
|
---|
1784 | template<bool _Const2>
|
---|
1785 | constexpr auto
|
---|
1786 | __distance_from(const _Iterator<_Const2>& __i) const
|
---|
1787 | { return _M_end - __i._M_current; }
|
---|
1788 |
|
---|
1789 | template<bool _Const2>
|
---|
1790 | constexpr bool
|
---|
1791 | __equal(const _Iterator<_Const2>& __i) const
|
---|
1792 | { return __i._M_current == _M_end; }
|
---|
1793 |
|
---|
1794 | sentinel_t<_Base> _M_end = sentinel_t<_Base>();
|
---|
1795 |
|
---|
1796 | public:
|
---|
1797 | _Sentinel() = default;
|
---|
1798 |
|
---|
1799 | constexpr explicit
|
---|
1800 | _Sentinel(sentinel_t<_Base> __end)
|
---|
1801 | : _M_end(__end)
|
---|
1802 | { }
|
---|
1803 |
|
---|
1804 | constexpr
|
---|
1805 | _Sentinel(_Sentinel<!_Const> __i)
|
---|
1806 | requires _Const
|
---|
1807 | && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
|
---|
1808 | : _M_end(std::move(__i._M_end))
|
---|
1809 | { }
|
---|
1810 |
|
---|
1811 | constexpr sentinel_t<_Base>
|
---|
1812 | base() const
|
---|
1813 | { return _M_end; }
|
---|
1814 |
|
---|
1815 | template<bool _Const2>
|
---|
1816 | requires sentinel_for<sentinel_t<_Base>,
|
---|
1817 | iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
|
---|
1818 | friend constexpr bool
|
---|
1819 | operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
|
---|
1820 | { return __y.__equal(__x); }
|
---|
1821 |
|
---|
1822 | template<bool _Const2,
|
---|
1823 | typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
|
---|
1824 | requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
|
---|
1825 | friend constexpr range_difference_t<_Base2>
|
---|
1826 | operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
|
---|
1827 | { return -__y.__distance_from(__x); }
|
---|
1828 |
|
---|
1829 | template<bool _Const2,
|
---|
1830 | typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
|
---|
1831 | requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
|
---|
1832 | friend constexpr range_difference_t<_Base2>
|
---|
1833 | operator-(const _Sentinel& __y, const _Iterator<_Const2>& __x)
|
---|
1834 | { return __y.__distance_from(__x); }
|
---|
1835 |
|
---|
1836 | friend _Sentinel<!_Const>;
|
---|
1837 | };
|
---|
1838 |
|
---|
1839 | [[no_unique_address]] __detail::__box<_Fp> _M_fun;
|
---|
1840 | _Vp _M_base = _Vp();
|
---|
1841 |
|
---|
1842 | public:
|
---|
1843 | transform_view() = default;
|
---|
1844 |
|
---|
1845 | constexpr
|
---|
1846 | transform_view(_Vp __base, _Fp __fun)
|
---|
1847 | : _M_fun(std::move(__fun)), _M_base(std::move(__base))
|
---|
1848 | { }
|
---|
1849 |
|
---|
1850 | constexpr _Vp
|
---|
1851 | base() const& requires copy_constructible<_Vp>
|
---|
1852 | { return _M_base ; }
|
---|
1853 |
|
---|
1854 | constexpr _Vp
|
---|
1855 | base() &&
|
---|
1856 | { return std::move(_M_base); }
|
---|
1857 |
|
---|
1858 | constexpr _Iterator<false>
|
---|
1859 | begin()
|
---|
1860 | { return _Iterator<false>{this, ranges::begin(_M_base)}; }
|
---|
1861 |
|
---|
1862 | constexpr _Iterator<true>
|
---|
1863 | begin() const
|
---|
1864 | requires range<const _Vp>
|
---|
1865 | && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
|
---|
1866 | { return _Iterator<true>{this, ranges::begin(_M_base)}; }
|
---|
1867 |
|
---|
1868 | constexpr _Sentinel<false>
|
---|
1869 | end()
|
---|
1870 | { return _Sentinel<false>{ranges::end(_M_base)}; }
|
---|
1871 |
|
---|
1872 | constexpr _Iterator<false>
|
---|
1873 | end() requires common_range<_Vp>
|
---|
1874 | { return _Iterator<false>{this, ranges::end(_M_base)}; }
|
---|
1875 |
|
---|
1876 | constexpr _Sentinel<true>
|
---|
1877 | end() const
|
---|
1878 | requires range<const _Vp>
|
---|
1879 | && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
|
---|
1880 | { return _Sentinel<true>{ranges::end(_M_base)}; }
|
---|
1881 |
|
---|
1882 | constexpr _Iterator<true>
|
---|
1883 | end() const
|
---|
1884 | requires common_range<const _Vp>
|
---|
1885 | && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
|
---|
1886 | { return _Iterator<true>{this, ranges::end(_M_base)}; }
|
---|
1887 |
|
---|
1888 | constexpr auto
|
---|
1889 | size() requires sized_range<_Vp>
|
---|
1890 | { return ranges::size(_M_base); }
|
---|
1891 |
|
---|
1892 | constexpr auto
|
---|
1893 | size() const requires sized_range<const _Vp>
|
---|
1894 | { return ranges::size(_M_base); }
|
---|
1895 | };
|
---|
1896 |
|
---|
1897 | template<typename _Range, typename _Fp>
|
---|
1898 | transform_view(_Range&&, _Fp) -> transform_view<views::all_t<_Range>, _Fp>;
|
---|
1899 |
|
---|
1900 | namespace views
|
---|
1901 | {
|
---|
1902 | namespace __detail
|
---|
1903 | {
|
---|
1904 | template<typename _Range, typename _Fp>
|
---|
1905 | concept __can_transform_view
|
---|
1906 | = requires { transform_view(std::declval<_Range>(), std::declval<_Fp>()); };
|
---|
1907 | } // namespace __detail
|
---|
1908 |
|
---|
1909 | struct _Transform : __adaptor::_RangeAdaptor<_Transform>
|
---|
1910 | {
|
---|
1911 | template<viewable_range _Range, typename _Fp>
|
---|
1912 | requires __detail::__can_transform_view<_Range, _Fp>
|
---|
1913 | constexpr auto
|
---|
1914 | operator()(_Range&& __r, _Fp&& __f) const
|
---|
1915 | {
|
---|
1916 | return transform_view(std::forward<_Range>(__r), std::forward<_Fp>(__f));
|
---|
1917 | }
|
---|
1918 |
|
---|
1919 | using _RangeAdaptor<_Transform>::operator();
|
---|
1920 | static constexpr int _S_arity = 2;
|
---|
1921 | static constexpr bool _S_has_simple_extra_args = true;
|
---|
1922 | };
|
---|
1923 |
|
---|
1924 | inline constexpr _Transform transform;
|
---|
1925 | } // namespace views
|
---|
1926 |
|
---|
1927 | template<view _Vp>
|
---|
1928 | class take_view : public view_interface<take_view<_Vp>>
|
---|
1929 | {
|
---|
1930 | private:
|
---|
1931 | template<bool _Const>
|
---|
1932 | using _CI = counted_iterator<
|
---|
1933 | iterator_t<__detail::__maybe_const_t<_Const, _Vp>>>;
|
---|
1934 |
|
---|
1935 | template<bool _Const>
|
---|
1936 | struct _Sentinel
|
---|
1937 | {
|
---|
1938 | private:
|
---|
1939 | using _Base = __detail::__maybe_const_t<_Const, _Vp>;
|
---|
1940 | sentinel_t<_Base> _M_end = sentinel_t<_Base>();
|
---|
1941 |
|
---|
1942 | public:
|
---|
1943 | _Sentinel() = default;
|
---|
1944 |
|
---|
1945 | constexpr explicit
|
---|
1946 | _Sentinel(sentinel_t<_Base> __end)
|
---|
1947 | : _M_end(__end)
|
---|
1948 | { }
|
---|
1949 |
|
---|
1950 | constexpr
|
---|
1951 | _Sentinel(_Sentinel<!_Const> __s)
|
---|
1952 | requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
|
---|
1953 | : _M_end(std::move(__s._M_end))
|
---|
1954 | { }
|
---|
1955 |
|
---|
1956 | constexpr sentinel_t<_Base>
|
---|
1957 | base() const
|
---|
1958 | { return _M_end; }
|
---|
1959 |
|
---|
1960 | friend constexpr bool
|
---|
1961 | operator==(const _CI<_Const>& __y, const _Sentinel& __x)
|
---|
1962 | { return __y.count() == 0 || __y.base() == __x._M_end; }
|
---|
1963 |
|
---|
1964 | template<bool _OtherConst = !_Const,
|
---|
1965 | typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
|
---|
1966 | requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
|
---|
1967 | friend constexpr bool
|
---|
1968 | operator==(const _CI<_OtherConst>& __y, const _Sentinel& __x)
|
---|
1969 | { return __y.count() == 0 || __y.base() == __x._M_end; }
|
---|
1970 |
|
---|
1971 | friend _Sentinel<!_Const>;
|
---|
1972 | };
|
---|
1973 |
|
---|
1974 | range_difference_t<_Vp> _M_count = 0;
|
---|
1975 | _Vp _M_base = _Vp();
|
---|
1976 |
|
---|
1977 | public:
|
---|
1978 | take_view() = default;
|
---|
1979 |
|
---|
1980 | constexpr
|
---|
1981 | take_view(_Vp base, range_difference_t<_Vp> __count)
|
---|
1982 | : _M_count(std::move(__count)), _M_base(std::move(base))
|
---|
1983 | { }
|
---|
1984 |
|
---|
1985 | constexpr _Vp
|
---|
1986 | base() const& requires copy_constructible<_Vp>
|
---|
1987 | { return _M_base; }
|
---|
1988 |
|
---|
1989 | constexpr _Vp
|
---|
1990 | base() &&
|
---|
1991 | { return std::move(_M_base); }
|
---|
1992 |
|
---|
1993 | constexpr auto
|
---|
1994 | begin() requires (!__detail::__simple_view<_Vp>)
|
---|
1995 | {
|
---|
1996 | if constexpr (sized_range<_Vp>)
|
---|
1997 | {
|
---|
1998 | if constexpr (random_access_range<_Vp>)
|
---|
1999 | return ranges::begin(_M_base);
|
---|
2000 | else
|
---|
2001 | {
|
---|
2002 | auto __sz = size();
|
---|
2003 | return counted_iterator(ranges::begin(_M_base), __sz);
|
---|
2004 | }
|
---|
2005 | }
|
---|
2006 | else
|
---|
2007 | return counted_iterator(ranges::begin(_M_base), _M_count);
|
---|
2008 | }
|
---|
2009 |
|
---|
2010 | constexpr auto
|
---|
2011 | begin() const requires range<const _Vp>
|
---|
2012 | {
|
---|
2013 | if constexpr (sized_range<const _Vp>)
|
---|
2014 | {
|
---|
2015 | if constexpr (random_access_range<const _Vp>)
|
---|
2016 | return ranges::begin(_M_base);
|
---|
2017 | else
|
---|
2018 | {
|
---|
2019 | auto __sz = size();
|
---|
2020 | return counted_iterator(ranges::begin(_M_base), __sz);
|
---|
2021 | }
|
---|
2022 | }
|
---|
2023 | else
|
---|
2024 | return counted_iterator(ranges::begin(_M_base), _M_count);
|
---|
2025 | }
|
---|
2026 |
|
---|
2027 | constexpr auto
|
---|
2028 | end() requires (!__detail::__simple_view<_Vp>)
|
---|
2029 | {
|
---|
2030 | if constexpr (sized_range<_Vp>)
|
---|
2031 | {
|
---|
2032 | if constexpr (random_access_range<_Vp>)
|
---|
2033 | return ranges::begin(_M_base) + size();
|
---|
2034 | else
|
---|
2035 | return default_sentinel;
|
---|
2036 | }
|
---|
2037 | else
|
---|
2038 | return _Sentinel<false>{ranges::end(_M_base)};
|
---|
2039 | }
|
---|
2040 |
|
---|
2041 | constexpr auto
|
---|
2042 | end() const requires range<const _Vp>
|
---|
2043 | {
|
---|
2044 | if constexpr (sized_range<const _Vp>)
|
---|
2045 | {
|
---|
2046 | if constexpr (random_access_range<const _Vp>)
|
---|
2047 | return ranges::begin(_M_base) + size();
|
---|
2048 | else
|
---|
2049 | return default_sentinel;
|
---|
2050 | }
|
---|
2051 | else
|
---|
2052 | return _Sentinel<true>{ranges::end(_M_base)};
|
---|
2053 | }
|
---|
2054 |
|
---|
2055 | constexpr auto
|
---|
2056 | size() requires sized_range<_Vp>
|
---|
2057 | {
|
---|
2058 | auto __n = ranges::size(_M_base);
|
---|
2059 | return std::min(__n, static_cast<decltype(__n)>(_M_count));
|
---|
2060 | }
|
---|
2061 |
|
---|
2062 | constexpr auto
|
---|
2063 | size() const requires sized_range<const _Vp>
|
---|
2064 | {
|
---|
2065 | auto __n = ranges::size(_M_base);
|
---|
2066 | return std::min(__n, static_cast<decltype(__n)>(_M_count));
|
---|
2067 | }
|
---|
2068 | };
|
---|
2069 |
|
---|
2070 | // _GLIBCXX_RESOLVE_LIB_DEFECTS
|
---|
2071 | // 3447. Deduction guides for take_view and drop_view have different
|
---|
2072 | // constraints
|
---|
2073 | template<typename _Range>
|
---|
2074 | take_view(_Range&&, range_difference_t<_Range>)
|
---|
2075 | -> take_view<views::all_t<_Range>>;
|
---|
2076 |
|
---|
2077 | template<typename _Tp>
|
---|
2078 | inline constexpr bool enable_borrowed_range<take_view<_Tp>>
|
---|
2079 | = enable_borrowed_range<_Tp>;
|
---|
2080 |
|
---|
2081 | namespace views
|
---|
2082 | {
|
---|
2083 | namespace __detail
|
---|
2084 | {
|
---|
2085 | template<typename _Range, typename _Tp>
|
---|
2086 | concept __can_take_view
|
---|
2087 | = requires { take_view(std::declval<_Range>(), std::declval<_Tp>()); };
|
---|
2088 | } // namespace __detail
|
---|
2089 |
|
---|
2090 | struct _Take : __adaptor::_RangeAdaptor<_Take>
|
---|
2091 | {
|
---|
2092 | template<viewable_range _Range, typename _Tp>
|
---|
2093 | requires __detail::__can_take_view<_Range, _Tp>
|
---|
2094 | constexpr auto
|
---|
2095 | operator()(_Range&& __r, _Tp&& __n) const
|
---|
2096 | {
|
---|
2097 | return take_view(std::forward<_Range>(__r), std::forward<_Tp>(__n));
|
---|
2098 | }
|
---|
2099 |
|
---|
2100 | using _RangeAdaptor<_Take>::operator();
|
---|
2101 | static constexpr int _S_arity = 2;
|
---|
2102 | // The count argument of views::take is not always simple -- it can be
|
---|
2103 | // e.g. a move-only class that's implicitly convertible to the difference
|
---|
2104 | // type. But an integer-like count argument is surely simple.
|
---|
2105 | template<typename _Tp>
|
---|
2106 | static constexpr bool _S_has_simple_extra_args
|
---|
2107 | = ranges::__detail::__is_integer_like<_Tp>;
|
---|
2108 | };
|
---|
2109 |
|
---|
2110 | inline constexpr _Take take;
|
---|
2111 | } // namespace views
|
---|
2112 |
|
---|
2113 | template<view _Vp, typename _Pred>
|
---|
2114 | requires input_range<_Vp> && is_object_v<_Pred>
|
---|
2115 | && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
|
---|
2116 | class take_while_view : public view_interface<take_while_view<_Vp, _Pred>>
|
---|
2117 | {
|
---|
2118 | template<bool _Const>
|
---|
2119 | struct _Sentinel
|
---|
2120 | {
|
---|
2121 | private:
|
---|
2122 | using _Base = __detail::__maybe_const_t<_Const, _Vp>;
|
---|
2123 |
|
---|
2124 | sentinel_t<_Base> _M_end = sentinel_t<_Base>();
|
---|
2125 | const _Pred* _M_pred = nullptr;
|
---|
2126 |
|
---|
2127 | public:
|
---|
2128 | _Sentinel() = default;
|
---|
2129 |
|
---|
2130 | constexpr explicit
|
---|
2131 | _Sentinel(sentinel_t<_Base> __end, const _Pred* __pred)
|
---|
2132 | : _M_end(__end), _M_pred(__pred)
|
---|
2133 | { }
|
---|
2134 |
|
---|
2135 | constexpr
|
---|
2136 | _Sentinel(_Sentinel<!_Const> __s)
|
---|
2137 | requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
|
---|
2138 | : _M_end(__s._M_end), _M_pred(__s._M_pred)
|
---|
2139 | { }
|
---|
2140 |
|
---|
2141 | constexpr sentinel_t<_Base>
|
---|
2142 | base() const { return _M_end; }
|
---|
2143 |
|
---|
2144 | friend constexpr bool
|
---|
2145 | operator==(const iterator_t<_Base>& __x, const _Sentinel& __y)
|
---|
2146 | { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }
|
---|
2147 |
|
---|
2148 | template<bool _OtherConst = !_Const,
|
---|
2149 | typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
|
---|
2150 | requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
|
---|
2151 | friend constexpr bool
|
---|
2152 | operator==(const iterator_t<_Base2>& __x, const _Sentinel& __y)
|
---|
2153 | { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }
|
---|
2154 |
|
---|
2155 | friend _Sentinel<!_Const>;
|
---|
2156 | };
|
---|
2157 |
|
---|
2158 | [[no_unique_address]] __detail::__box<_Pred> _M_pred;
|
---|
2159 | _Vp _M_base = _Vp();
|
---|
2160 |
|
---|
2161 | public:
|
---|
2162 | take_while_view() = default;
|
---|
2163 |
|
---|
2164 | constexpr
|
---|
2165 | take_while_view(_Vp base, _Pred __pred)
|
---|
2166 | : _M_pred(std::move(__pred)), _M_base(std::move(base))
|
---|
2167 | { }
|
---|
2168 |
|
---|
2169 | constexpr _Vp
|
---|
2170 | base() const& requires copy_constructible<_Vp>
|
---|
2171 | { return _M_base; }
|
---|
2172 |
|
---|
2173 | constexpr _Vp
|
---|
2174 | base() &&
|
---|
2175 | { return std::move(_M_base); }
|
---|
2176 |
|
---|
2177 | constexpr const _Pred&
|
---|
2178 | pred() const
|
---|
2179 | { return *_M_pred; }
|
---|
2180 |
|
---|
2181 | constexpr auto
|
---|
2182 | begin() requires (!__detail::__simple_view<_Vp>)
|
---|
2183 | { return ranges::begin(_M_base); }
|
---|
2184 |
|
---|
2185 | constexpr auto
|
---|
2186 | begin() const requires range<const _Vp>
|
---|
2187 | && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
|
---|
2188 | { return ranges::begin(_M_base); }
|
---|
2189 |
|
---|
2190 | constexpr auto
|
---|
2191 | end() requires (!__detail::__simple_view<_Vp>)
|
---|
2192 | { return _Sentinel<false>(ranges::end(_M_base),
|
---|
2193 | std::__addressof(*_M_pred)); }
|
---|
2194 |
|
---|
2195 | constexpr auto
|
---|
2196 | end() const requires range<const _Vp>
|
---|
2197 | && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
|
---|
2198 | { return _Sentinel<true>(ranges::end(_M_base),
|
---|
2199 | std::__addressof(*_M_pred)); }
|
---|
2200 | };
|
---|
2201 |
|
---|
2202 | template<typename _Range, typename _Pred>
|
---|
2203 | take_while_view(_Range&&, _Pred)
|
---|
2204 | -> take_while_view<views::all_t<_Range>, _Pred>;
|
---|
2205 |
|
---|
2206 | namespace views
|
---|
2207 | {
|
---|
2208 | namespace __detail
|
---|
2209 | {
|
---|
2210 | template<typename _Range, typename _Pred>
|
---|
2211 | concept __can_take_while_view
|
---|
2212 | = requires { take_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
|
---|
2213 | } // namespace __detail
|
---|
2214 |
|
---|
2215 | struct _TakeWhile : __adaptor::_RangeAdaptor<_TakeWhile>
|
---|
2216 | {
|
---|
2217 | template<viewable_range _Range, typename _Pred>
|
---|
2218 | requires __detail::__can_take_while_view<_Range, _Pred>
|
---|
2219 | constexpr auto
|
---|
2220 | operator()(_Range&& __r, _Pred&& __p) const
|
---|
2221 | {
|
---|
2222 | return take_while_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
|
---|
2223 | }
|
---|
2224 |
|
---|
2225 | using _RangeAdaptor<_TakeWhile>::operator();
|
---|
2226 | static constexpr int _S_arity = 2;
|
---|
2227 | static constexpr bool _S_has_simple_extra_args = true;
|
---|
2228 | };
|
---|
2229 |
|
---|
2230 | inline constexpr _TakeWhile take_while;
|
---|
2231 | } // namespace views
|
---|
2232 |
|
---|
2233 | template<view _Vp>
|
---|
2234 | class drop_view : public view_interface<drop_view<_Vp>>
|
---|
2235 | {
|
---|
2236 | private:
|
---|
2237 | range_difference_t<_Vp> _M_count = 0;
|
---|
2238 | _Vp _M_base = _Vp();
|
---|
2239 |
|
---|
2240 | // ranges::next(begin(base), count, end(base)) is O(1) if _Vp satisfies
|
---|
2241 | // both random_access_range and sized_range. Otherwise, cache its result.
|
---|
2242 | static constexpr bool _S_needs_cached_begin
|
---|
2243 | = !(random_access_range<const _Vp> && sized_range<const _Vp>);
|
---|
2244 | [[no_unique_address]]
|
---|
2245 | __detail::__maybe_present_t<_S_needs_cached_begin,
|
---|
2246 | __detail::_CachedPosition<_Vp>>
|
---|
2247 | _M_cached_begin;
|
---|
2248 |
|
---|
2249 | public:
|
---|
2250 | drop_view() = default;
|
---|
2251 |
|
---|
2252 | constexpr
|
---|
2253 | drop_view(_Vp __base, range_difference_t<_Vp> __count)
|
---|
2254 | : _M_count(__count), _M_base(std::move(__base))
|
---|
2255 | { __glibcxx_assert(__count >= 0); }
|
---|
2256 |
|
---|
2257 | constexpr _Vp
|
---|
2258 | base() const& requires copy_constructible<_Vp>
|
---|
2259 | { return _M_base; }
|
---|
2260 |
|
---|
2261 | constexpr _Vp
|
---|
2262 | base() &&
|
---|
2263 | { return std::move(_M_base); }
|
---|
2264 |
|
---|
2265 | // This overload is disabled for simple views with constant-time begin().
|
---|
2266 | constexpr auto
|
---|
2267 | begin()
|
---|
2268 | requires (!(__detail::__simple_view<_Vp>
|
---|
2269 | && random_access_range<const _Vp>
|
---|
2270 | && sized_range<const _Vp>))
|
---|
2271 | {
|
---|
2272 | if constexpr (_S_needs_cached_begin)
|
---|
2273 | if (_M_cached_begin._M_has_value())
|
---|
2274 | return _M_cached_begin._M_get(_M_base);
|
---|
2275 |
|
---|
2276 | auto __it = ranges::next(ranges::begin(_M_base),
|
---|
2277 | _M_count, ranges::end(_M_base));
|
---|
2278 | if constexpr (_S_needs_cached_begin)
|
---|
2279 | _M_cached_begin._M_set(_M_base, __it);
|
---|
2280 | return __it;
|
---|
2281 | }
|
---|
2282 |
|
---|
2283 | // _GLIBCXX_RESOLVE_LIB_DEFECTS
|
---|
2284 | // 3482. drop_view's const begin should additionally require sized_range
|
---|
2285 | constexpr auto
|
---|
2286 | begin() const
|
---|
2287 | requires random_access_range<const _Vp> && sized_range<const _Vp>
|
---|
2288 | {
|
---|
2289 | return ranges::next(ranges::begin(_M_base), _M_count,
|
---|
2290 | ranges::end(_M_base));
|
---|
2291 | }
|
---|
2292 |
|
---|
2293 | constexpr auto
|
---|
2294 | end() requires (!__detail::__simple_view<_Vp>)
|
---|
2295 | { return ranges::end(_M_base); }
|
---|
2296 |
|
---|
2297 | constexpr auto
|
---|
2298 | end() const requires range<const _Vp>
|
---|
2299 | { return ranges::end(_M_base); }
|
---|
2300 |
|
---|
2301 | constexpr auto
|
---|
2302 | size() requires sized_range<_Vp>
|
---|
2303 | {
|
---|
2304 | const auto __s = ranges::size(_M_base);
|
---|
2305 | const auto __c = static_cast<decltype(__s)>(_M_count);
|
---|
2306 | return __s < __c ? 0 : __s - __c;
|
---|
2307 | }
|
---|
2308 |
|
---|
2309 | constexpr auto
|
---|
2310 | size() const requires sized_range<const _Vp>
|
---|
2311 | {
|
---|
2312 | const auto __s = ranges::size(_M_base);
|
---|
2313 | const auto __c = static_cast<decltype(__s)>(_M_count);
|
---|
2314 | return __s < __c ? 0 : __s - __c;
|
---|
2315 | }
|
---|
2316 | };
|
---|
2317 |
|
---|
2318 | template<typename _Range>
|
---|
2319 | drop_view(_Range&&, range_difference_t<_Range>)
|
---|
2320 | -> drop_view<views::all_t<_Range>>;
|
---|
2321 |
|
---|
2322 | template<typename _Tp>
|
---|
2323 | inline constexpr bool enable_borrowed_range<drop_view<_Tp>>
|
---|
2324 | = enable_borrowed_range<_Tp>;
|
---|
2325 |
|
---|
2326 | namespace views
|
---|
2327 | {
|
---|
2328 | namespace __detail
|
---|
2329 | {
|
---|
2330 | template<typename _Range, typename _Tp>
|
---|
2331 | concept __can_drop_view
|
---|
2332 | = requires { drop_view(std::declval<_Range>(), std::declval<_Tp>()); };
|
---|
2333 | } // namespace __detail
|
---|
2334 |
|
---|
2335 | struct _Drop : __adaptor::_RangeAdaptor<_Drop>
|
---|
2336 | {
|
---|
2337 | template<viewable_range _Range, typename _Tp>
|
---|
2338 | requires __detail::__can_drop_view<_Range, _Tp>
|
---|
2339 | constexpr auto
|
---|
2340 | operator()(_Range&& __r, _Tp&& __n) const
|
---|
2341 | {
|
---|
2342 | return drop_view(std::forward<_Range>(__r), std::forward<_Tp>(__n));
|
---|
2343 | }
|
---|
2344 |
|
---|
2345 | using _RangeAdaptor<_Drop>::operator();
|
---|
2346 | static constexpr int _S_arity = 2;
|
---|
2347 | template<typename _Tp>
|
---|
2348 | static constexpr bool _S_has_simple_extra_args
|
---|
2349 | = _Take::_S_has_simple_extra_args<_Tp>;
|
---|
2350 | };
|
---|
2351 |
|
---|
2352 | inline constexpr _Drop drop;
|
---|
2353 | } // namespace views
|
---|
2354 |
|
---|
2355 | template<view _Vp, typename _Pred>
|
---|
2356 | requires input_range<_Vp> && is_object_v<_Pred>
|
---|
2357 | && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
|
---|
2358 | class drop_while_view : public view_interface<drop_while_view<_Vp, _Pred>>
|
---|
2359 | {
|
---|
2360 | private:
|
---|
2361 | [[no_unique_address]] __detail::__box<_Pred> _M_pred;
|
---|
2362 | [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
|
---|
2363 | _Vp _M_base = _Vp();
|
---|
2364 |
|
---|
2365 | public:
|
---|
2366 | drop_while_view() = default;
|
---|
2367 |
|
---|
2368 | constexpr
|
---|
2369 | drop_while_view(_Vp __base, _Pred __pred)
|
---|
2370 | : _M_pred(std::move(__pred)), _M_base(std::move(__base))
|
---|
2371 | { }
|
---|
2372 |
|
---|
2373 | constexpr _Vp
|
---|
2374 | base() const& requires copy_constructible<_Vp>
|
---|
2375 | { return _M_base; }
|
---|
2376 |
|
---|
2377 | constexpr _Vp
|
---|
2378 | base() &&
|
---|
2379 | { return std::move(_M_base); }
|
---|
2380 |
|
---|
2381 | constexpr const _Pred&
|
---|
2382 | pred() const
|
---|
2383 | { return *_M_pred; }
|
---|
2384 |
|
---|
2385 | constexpr auto
|
---|
2386 | begin()
|
---|
2387 | {
|
---|
2388 | if (_M_cached_begin._M_has_value())
|
---|
2389 | return _M_cached_begin._M_get(_M_base);
|
---|
2390 |
|
---|
2391 | auto __it = __detail::find_if_not(ranges::begin(_M_base),
|
---|
2392 | ranges::end(_M_base),
|
---|
2393 | std::cref(*_M_pred));
|
---|
2394 | _M_cached_begin._M_set(_M_base, __it);
|
---|
2395 | return __it;
|
---|
2396 | }
|
---|
2397 |
|
---|
2398 | constexpr auto
|
---|
2399 | end()
|
---|
2400 | { return ranges::end(_M_base); }
|
---|
2401 | };
|
---|
2402 |
|
---|
2403 | template<typename _Range, typename _Pred>
|
---|
2404 | drop_while_view(_Range&&, _Pred)
|
---|
2405 | -> drop_while_view<views::all_t<_Range>, _Pred>;
|
---|
2406 |
|
---|
2407 | template<typename _Tp, typename _Pred>
|
---|
2408 | inline constexpr bool enable_borrowed_range<drop_while_view<_Tp, _Pred>>
|
---|
2409 | = enable_borrowed_range<_Tp>;
|
---|
2410 |
|
---|
2411 | namespace views
|
---|
2412 | {
|
---|
2413 | namespace __detail
|
---|
2414 | {
|
---|
2415 | template<typename _Range, typename _Pred>
|
---|
2416 | concept __can_drop_while_view
|
---|
2417 | = requires { drop_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
|
---|
2418 | } // namespace __detail
|
---|
2419 |
|
---|
2420 | struct _DropWhile : __adaptor::_RangeAdaptor<_DropWhile>
|
---|
2421 | {
|
---|
2422 | template<viewable_range _Range, typename _Pred>
|
---|
2423 | requires __detail::__can_drop_while_view<_Range, _Pred>
|
---|
2424 | constexpr auto
|
---|
2425 | operator()(_Range&& __r, _Pred&& __p) const
|
---|
2426 | {
|
---|
2427 | return drop_while_view(std::forward<_Range>(__r),
|
---|
2428 | std::forward<_Pred>(__p));
|
---|
2429 | }
|
---|
2430 |
|
---|
2431 | using _RangeAdaptor<_DropWhile>::operator();
|
---|
2432 | static constexpr int _S_arity = 2;
|
---|
2433 | static constexpr bool _S_has_simple_extra_args = true;
|
---|
2434 | };
|
---|
2435 |
|
---|
2436 | inline constexpr _DropWhile drop_while;
|
---|
2437 | } // namespace views
|
---|
2438 |
|
---|
2439 | template<input_range _Vp>
|
---|
2440 | requires view<_Vp> && input_range<range_reference_t<_Vp>>
|
---|
2441 | class join_view : public view_interface<join_view<_Vp>>
|
---|
2442 | {
|
---|
2443 | private:
|
---|
2444 | using _InnerRange = range_reference_t<_Vp>;
|
---|
2445 |
|
---|
2446 | template<bool _Const>
|
---|
2447 | using _Base = __detail::__maybe_const_t<_Const, _Vp>;
|
---|
2448 |
|
---|
2449 | template<bool _Const>
|
---|
2450 | using _Outer_iter = iterator_t<_Base<_Const>>;
|
---|
2451 |
|
---|
2452 | template<bool _Const>
|
---|
2453 | using _Inner_iter = iterator_t<range_reference_t<_Base<_Const>>>;
|
---|
2454 |
|
---|
2455 | template<bool _Const>
|
---|
2456 | static constexpr bool _S_ref_is_glvalue
|
---|
2457 | = is_reference_v<range_reference_t<_Base<_Const>>>;
|
---|
2458 |
|
---|
2459 | template<bool _Const>
|
---|
2460 | struct __iter_cat
|
---|
2461 | { };
|
---|
2462 |
|
---|
2463 | template<bool _Const>
|
---|
2464 | requires _S_ref_is_glvalue<_Const>
|
---|
2465 | && forward_range<_Base<_Const>>
|
---|
2466 | && forward_range<range_reference_t<_Base<_Const>>>
|
---|
2467 | struct __iter_cat<_Const>
|
---|
2468 | {
|
---|
2469 | private:
|
---|
2470 | static constexpr auto
|
---|
2471 | _S_iter_cat()
|
---|
2472 | {
|
---|
2473 | using _Outer_iter = join_view::_Outer_iter<_Const>;
|
---|
2474 | using _Inner_iter = join_view::_Inner_iter<_Const>;
|
---|
2475 | using _OuterCat = typename iterator_traits<_Outer_iter>::iterator_category;
|
---|
2476 | using _InnerCat = typename iterator_traits<_Inner_iter>::iterator_category;
|
---|
2477 | if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
|
---|
2478 | && derived_from<_InnerCat, bidirectional_iterator_tag>)
|
---|
2479 | return bidirectional_iterator_tag{};
|
---|
2480 | else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
|
---|
2481 | && derived_from<_InnerCat, forward_iterator_tag>)
|
---|
2482 | return forward_iterator_tag{};
|
---|
2483 | else
|
---|
2484 | return input_iterator_tag{};
|
---|
2485 | }
|
---|
2486 | public:
|
---|
2487 | using iterator_category = decltype(_S_iter_cat());
|
---|
2488 | };
|
---|
2489 |
|
---|
2490 | template<bool _Const>
|
---|
2491 | struct _Sentinel;
|
---|
2492 |
|
---|
2493 | template<bool _Const>
|
---|
2494 | struct _Iterator : __iter_cat<_Const>
|
---|
2495 | {
|
---|
2496 | private:
|
---|
2497 | using _Parent = __detail::__maybe_const_t<_Const, join_view>;
|
---|
2498 | using _Base = join_view::_Base<_Const>;
|
---|
2499 |
|
---|
2500 | static constexpr bool _S_ref_is_glvalue
|
---|
2501 | = join_view::_S_ref_is_glvalue<_Const>;
|
---|
2502 |
|
---|
2503 | constexpr void
|
---|
2504 | _M_satisfy()
|
---|
2505 | {
|
---|
2506 | auto __update_inner = [this] (const iterator_t<_Base>& __x) -> auto&& {
|
---|
2507 | if constexpr (_S_ref_is_glvalue)
|
---|
2508 | return *__x;
|
---|
2509 | else
|
---|
2510 | return _M_parent->_M_inner._M_emplace_deref(__x);
|
---|
2511 | };
|
---|
2512 |
|
---|
2513 | for (; _M_outer != ranges::end(_M_parent->_M_base); ++_M_outer)
|
---|
2514 | {
|
---|
2515 | auto&& __inner = __update_inner(_M_outer);
|
---|
2516 | _M_inner = ranges::begin(__inner);
|
---|
2517 | if (_M_inner != ranges::end(__inner))
|
---|
2518 | return;
|
---|
2519 | }
|
---|
2520 |
|
---|
2521 | if constexpr (_S_ref_is_glvalue)
|
---|
2522 | _M_inner = _Inner_iter();
|
---|
2523 | }
|
---|
2524 |
|
---|
2525 | static constexpr auto
|
---|
2526 | _S_iter_concept()
|
---|
2527 | {
|
---|
2528 | if constexpr (_S_ref_is_glvalue
|
---|
2529 | && bidirectional_range<_Base>
|
---|
2530 | && bidirectional_range<range_reference_t<_Base>>)
|
---|
2531 | return bidirectional_iterator_tag{};
|
---|
2532 | else if constexpr (_S_ref_is_glvalue
|
---|
2533 | && forward_range<_Base>
|
---|
2534 | && forward_range<range_reference_t<_Base>>)
|
---|
2535 | return forward_iterator_tag{};
|
---|
2536 | else
|
---|
2537 | return input_iterator_tag{};
|
---|
2538 | }
|
---|
2539 |
|
---|
2540 | using _Outer_iter = join_view::_Outer_iter<_Const>;
|
---|
2541 | using _Inner_iter = join_view::_Inner_iter<_Const>;
|
---|
2542 |
|
---|
2543 | _Outer_iter _M_outer = _Outer_iter();
|
---|
2544 | _Inner_iter _M_inner = _Inner_iter();
|
---|
2545 | _Parent* _M_parent = nullptr;
|
---|
2546 |
|
---|
2547 | public:
|
---|
2548 | using iterator_concept = decltype(_S_iter_concept());
|
---|
2549 | // iterator_category defined in __join_view_iter_cat
|
---|
2550 | using value_type = range_value_t<range_reference_t<_Base>>;
|
---|
2551 | using difference_type
|
---|
2552 | = common_type_t<range_difference_t<_Base>,
|
---|
2553 | range_difference_t<range_reference_t<_Base>>>;
|
---|
2554 |
|
---|
2555 | _Iterator() = default;
|
---|
2556 |
|
---|
2557 | constexpr
|
---|
2558 | _Iterator(_Parent* __parent, _Outer_iter __outer)
|
---|
2559 | : _M_outer(std::move(__outer)),
|
---|
2560 | _M_parent(__parent)
|
---|
2561 | { _M_satisfy(); }
|
---|
2562 |
|
---|
2563 | constexpr
|
---|
2564 | _Iterator(_Iterator<!_Const> __i)
|
---|
2565 | requires _Const
|
---|
2566 | && convertible_to<iterator_t<_Vp>, _Outer_iter>
|
---|
2567 | && convertible_to<iterator_t<_InnerRange>, _Inner_iter>
|
---|
2568 | : _M_outer(std::move(__i._M_outer)), _M_inner(__i._M_inner),
|
---|
2569 | _M_parent(__i._M_parent)
|
---|
2570 | { }
|
---|
2571 |
|
---|
2572 | constexpr decltype(auto)
|
---|
2573 | operator*() const
|
---|
2574 | { return *_M_inner; }
|
---|
2575 |
|
---|
2576 | // _GLIBCXX_RESOLVE_LIB_DEFECTS
|
---|
2577 | // 3500. join_view::iterator::operator->() is bogus
|
---|
2578 | constexpr _Inner_iter
|
---|
2579 | operator->() const
|
---|
2580 | requires __detail::__has_arrow<_Inner_iter>
|
---|
2581 | && copyable<_Inner_iter>
|
---|
2582 | { return _M_inner; }
|
---|
2583 |
|
---|
2584 | constexpr _Iterator&
|
---|
2585 | operator++()
|
---|
2586 | {
|
---|
2587 | auto&& __inner_range = [this] () -> auto&& {
|
---|
2588 | if constexpr (_S_ref_is_glvalue)
|
---|
2589 | return *_M_outer;
|
---|
2590 | else
|
---|
2591 | return *_M_parent->_M_inner;
|
---|
2592 | }();
|
---|
2593 | if (++_M_inner == ranges::end(__inner_range))
|
---|
2594 | {
|
---|
2595 | ++_M_outer;
|
---|
2596 | _M_satisfy();
|
---|
2597 | }
|
---|
2598 | return *this;
|
---|
2599 | }
|
---|
2600 |
|
---|
2601 | constexpr void
|
---|
2602 | operator++(int)
|
---|
2603 | { ++*this; }
|
---|
2604 |
|
---|
2605 | constexpr _Iterator
|
---|
2606 | operator++(int)
|
---|
2607 | requires _S_ref_is_glvalue && forward_range<_Base>
|
---|
2608 | && forward_range<range_reference_t<_Base>>
|
---|
2609 | {
|
---|
2610 | auto __tmp = *this;
|
---|
2611 | ++*this;
|
---|
2612 | return __tmp;
|
---|
2613 | }
|
---|
2614 |
|
---|
2615 | constexpr _Iterator&
|
---|
2616 | operator--()
|
---|
2617 | requires _S_ref_is_glvalue && bidirectional_range<_Base>
|
---|
2618 | && bidirectional_range<range_reference_t<_Base>>
|
---|
2619 | && common_range<range_reference_t<_Base>>
|
---|
2620 | {
|
---|
2621 | if (_M_outer == ranges::end(_M_parent->_M_base))
|
---|
2622 | _M_inner = ranges::end(*--_M_outer);
|
---|
2623 | while (_M_inner == ranges::begin(*_M_outer))
|
---|
2624 | _M_inner = ranges::end(*--_M_outer);
|
---|
2625 | --_M_inner;
|
---|
2626 | return *this;
|
---|
2627 | }
|
---|
2628 |
|
---|
2629 | constexpr _Iterator
|
---|
2630 | operator--(int)
|
---|
2631 | requires _S_ref_is_glvalue && bidirectional_range<_Base>
|
---|
2632 | && bidirectional_range<range_reference_t<_Base>>
|
---|
2633 | && common_range<range_reference_t<_Base>>
|
---|
2634 | {
|
---|
2635 | auto __tmp = *this;
|
---|
2636 | --*this;
|
---|
2637 | return __tmp;
|
---|
2638 | }
|
---|
2639 |
|
---|
2640 | friend constexpr bool
|
---|
2641 | operator==(const _Iterator& __x, const _Iterator& __y)
|
---|
2642 | requires _S_ref_is_glvalue
|
---|
2643 | && equality_comparable<_Outer_iter>
|
---|
2644 | && equality_comparable<_Inner_iter>
|
---|
2645 | {
|
---|
2646 | return (__x._M_outer == __y._M_outer
|
---|
2647 | && __x._M_inner == __y._M_inner);
|
---|
2648 | }
|
---|
2649 |
|
---|
2650 | friend constexpr decltype(auto)
|
---|
2651 | iter_move(const _Iterator& __i)
|
---|
2652 | noexcept(noexcept(ranges::iter_move(__i._M_inner)))
|
---|
2653 | { return ranges::iter_move(__i._M_inner); }
|
---|
2654 |
|
---|
2655 | friend constexpr void
|
---|
2656 | iter_swap(const _Iterator& __x, const _Iterator& __y)
|
---|
2657 | noexcept(noexcept(ranges::iter_swap(__x._M_inner, __y._M_inner)))
|
---|
2658 | requires indirectly_swappable<_Inner_iter>
|
---|
2659 | { return ranges::iter_swap(__x._M_inner, __y._M_inner); }
|
---|
2660 |
|
---|
2661 | friend _Iterator<!_Const>;
|
---|
2662 | template<bool> friend struct _Sentinel;
|
---|
2663 | };
|
---|
2664 |
|
---|
2665 | template<bool _Const>
|
---|
2666 | struct _Sentinel
|
---|
2667 | {
|
---|
2668 | private:
|
---|
2669 | using _Parent = __detail::__maybe_const_t<_Const, join_view>;
|
---|
2670 | using _Base = join_view::_Base<_Const>;
|
---|
2671 |
|
---|
2672 | template<bool _Const2>
|
---|
2673 | constexpr bool
|
---|
2674 | __equal(const _Iterator<_Const2>& __i) const
|
---|
2675 | { return __i._M_outer == _M_end; }
|
---|
2676 |
|
---|
2677 | sentinel_t<_Base> _M_end = sentinel_t<_Base>();
|
---|
2678 |
|
---|
2679 | public:
|
---|
2680 | _Sentinel() = default;
|
---|
2681 |
|
---|
2682 | constexpr explicit
|
---|
2683 | _Sentinel(_Parent* __parent)
|
---|
2684 | : _M_end(ranges::end(__parent->_M_base))
|
---|
2685 | { }
|
---|
2686 |
|
---|
2687 | constexpr
|
---|
2688 | _Sentinel(_Sentinel<!_Const> __s)
|
---|
2689 | requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
|
---|
2690 | : _M_end(std::move(__s._M_end))
|
---|
2691 | { }
|
---|
2692 |
|
---|
2693 | template<bool _Const2>
|
---|
2694 | requires sentinel_for<sentinel_t<_Base>,
|
---|
2695 | iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
|
---|
2696 | friend constexpr bool
|
---|
2697 | operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
|
---|
2698 | { return __y.__equal(__x); }
|
---|
2699 |
|
---|
2700 | friend _Sentinel<!_Const>;
|
---|
2701 | };
|
---|
2702 |
|
---|
2703 | [[no_unique_address]]
|
---|
2704 | __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
|
---|
2705 | _Vp _M_base = _Vp();
|
---|
2706 |
|
---|
2707 | public:
|
---|
2708 | join_view() = default;
|
---|
2709 |
|
---|
2710 | constexpr explicit
|
---|
2711 | join_view(_Vp __base)
|
---|
2712 | : _M_base(std::move(__base))
|
---|
2713 | { }
|
---|
2714 |
|
---|
2715 | constexpr _Vp
|
---|
2716 | base() const& requires copy_constructible<_Vp>
|
---|
2717 | { return _M_base; }
|
---|
2718 |
|
---|
2719 | constexpr _Vp
|
---|
2720 | base() &&
|
---|
2721 | { return std::move(_M_base); }
|
---|
2722 |
|
---|
2723 | constexpr auto
|
---|
2724 | begin()
|
---|
2725 | {
|
---|
2726 | constexpr bool __use_const
|
---|
2727 | = (__detail::__simple_view<_Vp>
|
---|
2728 | && is_reference_v<range_reference_t<_Vp>>);
|
---|
2729 | return _Iterator<__use_const>{this, ranges::begin(_M_base)};
|
---|
2730 | }
|
---|
2731 |
|
---|
2732 | constexpr auto
|
---|
2733 | begin() const
|
---|
2734 | requires input_range<const _Vp>
|
---|
2735 | && is_reference_v<range_reference_t<const _Vp>>
|
---|
2736 | {
|
---|
2737 | return _Iterator<true>{this, ranges::begin(_M_base)};
|
---|
2738 | }
|
---|
2739 |
|
---|
2740 | constexpr auto
|
---|
2741 | end()
|
---|
2742 | {
|
---|
2743 | if constexpr (forward_range<_Vp> && is_reference_v<_InnerRange>
|
---|
2744 | && forward_range<_InnerRange>
|
---|
2745 | && common_range<_Vp> && common_range<_InnerRange>)
|
---|
2746 | return _Iterator<__detail::__simple_view<_Vp>>{this,
|
---|
2747 | ranges::end(_M_base)};
|
---|
2748 | else
|
---|
2749 | return _Sentinel<__detail::__simple_view<_Vp>>{this};
|
---|
2750 | }
|
---|
2751 |
|
---|
2752 | constexpr auto
|
---|
2753 | end() const
|
---|
2754 | requires input_range<const _Vp>
|
---|
2755 | && is_reference_v<range_reference_t<const _Vp>>
|
---|
2756 | {
|
---|
2757 | if constexpr (forward_range<const _Vp>
|
---|
2758 | && is_reference_v<range_reference_t<const _Vp>>
|
---|
2759 | && forward_range<range_reference_t<const _Vp>>
|
---|
2760 | && common_range<const _Vp>
|
---|
2761 | && common_range<range_reference_t<const _Vp>>)
|
---|
2762 | return _Iterator<true>{this, ranges::end(_M_base)};
|
---|
2763 | else
|
---|
2764 | return _Sentinel<true>{this};
|
---|
2765 | }
|
---|
2766 | };
|
---|
2767 |
|
---|
2768 | template<typename _Range>
|
---|
2769 | explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>;
|
---|
2770 |
|
---|
2771 | namespace views
|
---|
2772 | {
|
---|
2773 | namespace __detail
|
---|
2774 | {
|
---|
2775 | template<typename _Range>
|
---|
2776 | concept __can_join_view
|
---|
2777 | = requires { join_view<all_t<_Range>>{std::declval<_Range>()}; };
|
---|
2778 | } // namespace __detail
|
---|
2779 |
|
---|
2780 | struct _Join : __adaptor::_RangeAdaptorClosure
|
---|
2781 | {
|
---|
2782 | template<viewable_range _Range>
|
---|
2783 | requires __detail::__can_join_view<_Range>
|
---|
2784 | constexpr auto
|
---|
2785 | operator()(_Range&& __r) const
|
---|
2786 | {
|
---|
2787 | // _GLIBCXX_RESOLVE_LIB_DEFECTS
|
---|
2788 | // 3474. Nesting join_views is broken because of CTAD
|
---|
2789 | return join_view<all_t<_Range>>{std::forward<_Range>(__r)};
|
---|
2790 | }
|
---|
2791 |
|
---|
2792 | static constexpr bool _S_has_simple_call_op = true;
|
---|
2793 | };
|
---|
2794 |
|
---|
2795 | inline constexpr _Join join;
|
---|
2796 | } // namespace views
|
---|
2797 |
|
---|
2798 | namespace __detail
|
---|
2799 | {
|
---|
2800 | template<auto>
|
---|
2801 | struct __require_constant;
|
---|
2802 |
|
---|
2803 | template<typename _Range>
|
---|
2804 | concept __tiny_range = sized_range<_Range>
|
---|
2805 | && requires
|
---|
2806 | { typename __require_constant<remove_reference_t<_Range>::size()>; }
|
---|
2807 | && (remove_reference_t<_Range>::size() <= 1);
|
---|
2808 |
|
---|
2809 | template<typename _Base>
|
---|
2810 | struct __split_view_outer_iter_cat
|
---|
2811 | { };
|
---|
2812 |
|
---|
2813 | template<forward_range _Base>
|
---|
2814 | struct __split_view_outer_iter_cat<_Base>
|
---|
2815 | { using iterator_category = input_iterator_tag; };
|
---|
2816 |
|
---|
2817 | template<typename _Base>
|
---|
2818 | struct __split_view_inner_iter_cat
|
---|
2819 | { };
|
---|
2820 |
|
---|
2821 | template<forward_range _Base>
|
---|
2822 | struct __split_view_inner_iter_cat<_Base>
|
---|
2823 | {
|
---|
2824 | private:
|
---|
2825 | static constexpr auto
|
---|
2826 | _S_iter_cat()
|
---|
2827 | {
|
---|
2828 | using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
|
---|
2829 | if constexpr (derived_from<_Cat, forward_iterator_tag>)
|
---|
2830 | return forward_iterator_tag{};
|
---|
2831 | else
|
---|
2832 | return _Cat{};
|
---|
2833 | }
|
---|
2834 | public:
|
---|
2835 | using iterator_category = decltype(_S_iter_cat());
|
---|
2836 | };
|
---|
2837 | }
|
---|
2838 |
|
---|
2839 | template<input_range _Vp, forward_range _Pattern>
|
---|
2840 | requires view<_Vp> && view<_Pattern>
|
---|
2841 | && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
|
---|
2842 | ranges::equal_to>
|
---|
2843 | && (forward_range<_Vp> || __detail::__tiny_range<_Pattern>)
|
---|
2844 | class split_view : public view_interface<split_view<_Vp, _Pattern>>
|
---|
2845 | {
|
---|
2846 | private:
|
---|
2847 | template<bool _Const>
|
---|
2848 | using _Base = __detail::__maybe_const_t<_Const, _Vp>;
|
---|
2849 |
|
---|
2850 | template<bool _Const>
|
---|
2851 | struct _InnerIter;
|
---|
2852 |
|
---|
2853 | template<bool _Const>
|
---|
2854 | struct _OuterIter
|
---|
2855 | : __detail::__split_view_outer_iter_cat<_Base<_Const>>
|
---|
2856 | {
|
---|
2857 | private:
|
---|
2858 | using _Parent = __detail::__maybe_const_t<_Const, split_view>;
|
---|
2859 | using _Base = split_view::_Base<_Const>;
|
---|
2860 |
|
---|
2861 | constexpr bool
|
---|
2862 | __at_end() const
|
---|
2863 | { return __current() == ranges::end(_M_parent->_M_base); }
|
---|
2864 |
|
---|
2865 | // [range.split.outer] p1
|
---|
2866 | // Many of the following specifications refer to the notional member
|
---|
2867 | // current of outer-iterator. current is equivalent to current_ if
|
---|
2868 | // V models forward_range, and parent_->current_ otherwise.
|
---|
2869 | constexpr auto&
|
---|
2870 | __current() noexcept
|
---|
2871 | {
|
---|
2872 | if constexpr (forward_range<_Vp>)
|
---|
2873 | return _M_current;
|
---|
2874 | else
|
---|
2875 | return _M_parent->_M_current;
|
---|
2876 | }
|
---|
2877 |
|
---|
2878 | constexpr auto&
|
---|
2879 | __current() const noexcept
|
---|
2880 | {
|
---|
2881 | if constexpr (forward_range<_Vp>)
|
---|
2882 | return _M_current;
|
---|
2883 | else
|
---|
2884 | return _M_parent->_M_current;
|
---|
2885 | }
|
---|
2886 |
|
---|
2887 | _Parent* _M_parent = nullptr;
|
---|
2888 |
|
---|
2889 | // XXX: _M_current is present only if "V models forward_range"
|
---|
2890 | [[no_unique_address]]
|
---|
2891 | __detail::__maybe_present_t<forward_range<_Vp>,
|
---|
2892 | iterator_t<_Base>> _M_current;
|
---|
2893 |
|
---|
2894 | public:
|
---|
2895 | using iterator_concept = conditional_t<forward_range<_Base>,
|
---|
2896 | forward_iterator_tag,
|
---|
2897 | input_iterator_tag>;
|
---|
2898 | // iterator_category defined in __split_view_outer_iter_cat
|
---|
2899 | using difference_type = range_difference_t<_Base>;
|
---|
2900 |
|
---|
2901 | struct value_type : view_interface<value_type>
|
---|
2902 | {
|
---|
2903 | private:
|
---|
2904 | _OuterIter _M_i = _OuterIter();
|
---|
2905 |
|
---|
2906 | public:
|
---|
2907 | value_type() = default;
|
---|
2908 |
|
---|
2909 | constexpr explicit
|
---|
2910 | value_type(_OuterIter __i)
|
---|
2911 | : _M_i(std::move(__i))
|
---|
2912 | { }
|
---|
2913 |
|
---|
2914 | constexpr _InnerIter<_Const>
|
---|
2915 | begin() const
|
---|
2916 | requires copyable<_OuterIter>
|
---|
2917 | { return _InnerIter<_Const>{_M_i}; }
|
---|
2918 |
|
---|
2919 | constexpr _InnerIter<_Const>
|
---|
2920 | begin()
|
---|
2921 | requires (!copyable<_OuterIter>)
|
---|
2922 | { return _InnerIter<_Const>{std::move(_M_i)}; }
|
---|
2923 |
|
---|
2924 | constexpr default_sentinel_t
|
---|
2925 | end() const
|
---|
2926 | { return default_sentinel; }
|
---|
2927 | };
|
---|
2928 |
|
---|
2929 | _OuterIter() = default;
|
---|
2930 |
|
---|
2931 | constexpr explicit
|
---|
2932 | _OuterIter(_Parent* __parent) requires (!forward_range<_Base>)
|
---|
2933 | : _M_parent(__parent)
|
---|
2934 | { }
|
---|
2935 |
|
---|
2936 | constexpr
|
---|
2937 | _OuterIter(_Parent* __parent, iterator_t<_Base> __current)
|
---|
2938 | requires forward_range<_Base>
|
---|
2939 | : _M_parent(__parent),
|
---|
2940 | _M_current(std::move(__current))
|
---|
2941 | { }
|
---|
2942 |
|
---|
2943 | constexpr
|
---|
2944 | _OuterIter(_OuterIter<!_Const> __i)
|
---|
2945 | requires _Const
|
---|
2946 | && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
|
---|
2947 | : _M_parent(__i._M_parent), _M_current(std::move(__i._M_current))
|
---|
2948 | { }
|
---|
2949 |
|
---|
2950 | constexpr value_type
|
---|
2951 | operator*() const
|
---|
2952 | { return value_type{*this}; }
|
---|
2953 |
|
---|
2954 | constexpr _OuterIter&
|
---|
2955 | operator++()
|
---|
2956 | {
|
---|
2957 | // _GLIBCXX_RESOLVE_LIB_DEFECTS
|
---|
2958 | // 3505. split_view::outer-iterator::operator++ misspecified
|
---|
2959 | const auto __end = ranges::end(_M_parent->_M_base);
|
---|
2960 | if (__current() == __end)
|
---|
2961 | return *this;
|
---|
2962 | const auto [__pbegin, __pend] = subrange{_M_parent->_M_pattern};
|
---|
2963 | if (__pbegin == __pend)
|
---|
2964 | ++__current();
|
---|
2965 | else if constexpr (__detail::__tiny_range<_Pattern>)
|
---|
2966 | {
|
---|
2967 | __current() = __detail::find(std::move(__current()), __end,
|
---|
2968 | *__pbegin);
|
---|
2969 | if (__current() != __end)
|
---|
2970 | ++__current();
|
---|
2971 | }
|
---|
2972 | else
|
---|
2973 | do
|
---|
2974 | {
|
---|
2975 | auto [__b, __p]
|
---|
2976 | = __detail::mismatch(__current(), __end, __pbegin, __pend);
|
---|
2977 | if (__p == __pend)
|
---|
2978 | {
|
---|
2979 | __current() = __b;
|
---|
2980 | break;
|
---|
2981 | }
|
---|
2982 | } while (++__current() != __end);
|
---|
2983 | return *this;
|
---|
2984 | }
|
---|
2985 |
|
---|
2986 | constexpr decltype(auto)
|
---|
2987 | operator++(int)
|
---|
2988 | {
|
---|
2989 | if constexpr (forward_range<_Base>)
|
---|
2990 | {
|
---|
2991 | auto __tmp = *this;
|
---|
2992 | ++*this;
|
---|
2993 | return __tmp;
|
---|
2994 | }
|
---|
2995 | else
|
---|
2996 | ++*this;
|
---|
2997 | }
|
---|
2998 |
|
---|
2999 | friend constexpr bool
|
---|
3000 | operator==(const _OuterIter& __x, const _OuterIter& __y)
|
---|
3001 | requires forward_range<_Base>
|
---|
3002 | { return __x._M_current == __y._M_current; }
|
---|
3003 |
|
---|
3004 | friend constexpr bool
|
---|
3005 | operator==(const _OuterIter& __x, default_sentinel_t)
|
---|
3006 | { return __x.__at_end(); };
|
---|
3007 |
|
---|
3008 | friend _OuterIter<!_Const>;
|
---|
3009 | friend _InnerIter<_Const>;
|
---|
3010 | };
|
---|
3011 |
|
---|
3012 | template<bool _Const>
|
---|
3013 | struct _InnerIter
|
---|
3014 | : __detail::__split_view_inner_iter_cat<_Base<_Const>>
|
---|
3015 | {
|
---|
3016 | private:
|
---|
3017 | using _Base = split_view::_Base<_Const>;
|
---|
3018 |
|
---|
3019 | constexpr bool
|
---|
3020 | __at_end() const
|
---|
3021 | {
|
---|
3022 | auto [__pcur, __pend] = subrange{_M_i._M_parent->_M_pattern};
|
---|
3023 | auto __end = ranges::end(_M_i._M_parent->_M_base);
|
---|
3024 | if constexpr (__detail::__tiny_range<_Pattern>)
|
---|
3025 | {
|
---|
3026 | const auto& __cur = _M_i_current();
|
---|
3027 | if (__cur == __end)
|
---|
3028 | return true;
|
---|
3029 | if (__pcur == __pend)
|
---|
3030 | return _M_incremented;
|
---|
3031 | return *__cur == *__pcur;
|
---|
3032 | }
|
---|
3033 | else
|
---|
3034 | {
|
---|
3035 | auto __cur = _M_i_current();
|
---|
3036 | if (__cur == __end)
|
---|
3037 | return true;
|
---|
3038 | if (__pcur == __pend)
|
---|
3039 | return _M_incremented;
|
---|
3040 | do
|
---|
3041 | {
|
---|
3042 | if (*__cur != *__pcur)
|
---|
3043 | return false;
|
---|
3044 | if (++__pcur == __pend)
|
---|
3045 | return true;
|
---|
3046 | } while (++__cur != __end);
|
---|
3047 | return false;
|
---|
3048 | }
|
---|
3049 | }
|
---|
3050 |
|
---|
3051 | constexpr auto&
|
---|
3052 | _M_i_current() noexcept
|
---|
3053 | { return _M_i.__current(); }
|
---|
3054 |
|
---|
3055 | constexpr auto&
|
---|
3056 | _M_i_current() const noexcept
|
---|
3057 | { return _M_i.__current(); }
|
---|
3058 |
|
---|
3059 | _OuterIter<_Const> _M_i = _OuterIter<_Const>();
|
---|
3060 | bool _M_incremented = false;
|
---|
3061 |
|
---|
3062 | public:
|
---|
3063 | using iterator_concept
|
---|
3064 | = typename _OuterIter<_Const>::iterator_concept;
|
---|
3065 | // iterator_category defined in __split_view_inner_iter_cat
|
---|
3066 | using value_type = range_value_t<_Base>;
|
---|
3067 | using difference_type = range_difference_t<_Base>;
|
---|
3068 |
|
---|
3069 | _InnerIter() = default;
|
---|
3070 |
|
---|
3071 | constexpr explicit
|
---|
3072 | _InnerIter(_OuterIter<_Const> __i)
|
---|
3073 | : _M_i(std::move(__i))
|
---|
3074 | { }
|
---|
3075 |
|
---|
3076 | constexpr decltype(auto)
|
---|
3077 | operator*() const
|
---|
3078 | { return *_M_i_current(); }
|
---|
3079 |
|
---|
3080 | constexpr _InnerIter&
|
---|
3081 | operator++()
|
---|
3082 | {
|
---|
3083 | _M_incremented = true;
|
---|
3084 | if constexpr (!forward_range<_Base>)
|
---|
3085 | if constexpr (_Pattern::size() == 0)
|
---|
3086 | return *this;
|
---|
3087 | ++_M_i_current();
|
---|
3088 | return *this;
|
---|
3089 | }
|
---|
3090 |
|
---|
3091 | constexpr decltype(auto)
|
---|
3092 | operator++(int)
|
---|
3093 | {
|
---|
3094 | if constexpr (forward_range<_Base>)
|
---|
3095 | {
|
---|
3096 | auto __tmp = *this;
|
---|
3097 | ++*this;
|
---|
3098 | return __tmp;
|
---|
3099 | }
|
---|
3100 | else
|
---|
3101 | ++*this;
|
---|
3102 | }
|
---|
3103 |
|
---|
3104 | friend constexpr bool
|
---|
3105 | operator==(const _InnerIter& __x, const _InnerIter& __y)
|
---|
3106 | requires forward_range<_Base>
|
---|
3107 | { return __x._M_i == __y._M_i; }
|
---|
3108 |
|
---|
3109 | friend constexpr bool
|
---|
3110 | operator==(const _InnerIter& __x, default_sentinel_t)
|
---|
3111 | { return __x.__at_end(); }
|
---|
3112 |
|
---|
3113 | friend constexpr decltype(auto)
|
---|
3114 | iter_move(const _InnerIter& __i)
|
---|
3115 | noexcept(noexcept(ranges::iter_move(__i._M_i_current())))
|
---|
3116 | { return ranges::iter_move(__i._M_i_current()); }
|
---|
3117 |
|
---|
3118 | friend constexpr void
|
---|
3119 | iter_swap(const _InnerIter& __x, const _InnerIter& __y)
|
---|
3120 | noexcept(noexcept(ranges::iter_swap(__x._M_i_current(),
|
---|
3121 | __y._M_i_current())))
|
---|
3122 | requires indirectly_swappable<iterator_t<_Base>>
|
---|
3123 | { ranges::iter_swap(__x._M_i_current(), __y._M_i_current()); }
|
---|
3124 | };
|
---|
3125 |
|
---|
3126 | _Pattern _M_pattern = _Pattern();
|
---|
3127 | // XXX: _M_current is "present only if !forward_range<V>"
|
---|
3128 | [[no_unique_address]]
|
---|
3129 | __detail::__maybe_present_t<!forward_range<_Vp>,
|
---|
3130 | iterator_t<_Vp>> _M_current;
|
---|
3131 | _Vp _M_base = _Vp();
|
---|
3132 |
|
---|
3133 |
|
---|
3134 | public:
|
---|
3135 | split_view() = default;
|
---|
3136 |
|
---|
3137 | constexpr
|
---|
3138 | split_view(_Vp __base, _Pattern __pattern)
|
---|
3139 | : _M_pattern(std::move(__pattern)), _M_base(std::move(__base))
|
---|
3140 | { }
|
---|
3141 |
|
---|
3142 | template<input_range _Range>
|
---|
3143 | requires constructible_from<_Vp, views::all_t<_Range>>
|
---|
3144 | && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
|
---|
3145 | constexpr
|
---|
3146 | split_view(_Range&& __r, range_value_t<_Range> __e)
|
---|
3147 | : _M_pattern(views::single(std::move(__e))),
|
---|
3148 | _M_base(views::all(std::forward<_Range>(__r)))
|
---|
3149 | { }
|
---|
3150 |
|
---|
3151 | constexpr _Vp
|
---|
3152 | base() const& requires copy_constructible<_Vp>
|
---|
3153 | { return _M_base; }
|
---|
3154 |
|
---|
3155 | constexpr _Vp
|
---|
3156 | base() &&
|
---|
3157 | { return std::move(_M_base); }
|
---|
3158 |
|
---|
3159 | constexpr auto
|
---|
3160 | begin()
|
---|
3161 | {
|
---|
3162 | if constexpr (forward_range<_Vp>)
|
---|
3163 | return _OuterIter<__detail::__simple_view<_Vp>>{
|
---|
3164 | this, ranges::begin(_M_base)};
|
---|
3165 | else
|
---|
3166 | {
|
---|
3167 | _M_current = ranges::begin(_M_base);
|
---|
3168 | return _OuterIter<false>{this};
|
---|
3169 | }
|
---|
3170 | }
|
---|
3171 |
|
---|
3172 | constexpr auto
|
---|
3173 | begin() const requires forward_range<_Vp> && forward_range<const _Vp>
|
---|
3174 | {
|
---|
3175 | return _OuterIter<true>{this, ranges::begin(_M_base)};
|
---|
3176 | }
|
---|
3177 |
|
---|
3178 | constexpr auto
|
---|
3179 | end() requires forward_range<_Vp> && common_range<_Vp>
|
---|
3180 | {
|
---|
3181 | return _OuterIter<__detail::__simple_view<_Vp>>{
|
---|
3182 | this, ranges::end(_M_base)};
|
---|
3183 | }
|
---|
3184 |
|
---|
3185 | constexpr auto
|
---|
3186 | end() const
|
---|
3187 | {
|
---|
3188 | if constexpr (forward_range<_Vp>
|
---|
3189 | && forward_range<const _Vp>
|
---|
3190 | && common_range<const _Vp>)
|
---|
3191 | return _OuterIter<true>{this, ranges::end(_M_base)};
|
---|
3192 | else
|
---|
3193 | return default_sentinel;
|
---|
3194 | }
|
---|
3195 | };
|
---|
3196 |
|
---|
3197 | template<typename _Range, typename _Pattern>
|
---|
3198 | split_view(_Range&&, _Pattern&&)
|
---|
3199 | -> split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
|
---|
3200 |
|
---|
3201 | template<input_range _Range>
|
---|
3202 | split_view(_Range&&, range_value_t<_Range>)
|
---|
3203 | -> split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
|
---|
3204 |
|
---|
3205 | namespace views
|
---|
3206 | {
|
---|
3207 | namespace __detail
|
---|
3208 | {
|
---|
3209 | template<typename _Range, typename _Pattern>
|
---|
3210 | concept __can_split_view
|
---|
3211 | = requires { split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
|
---|
3212 | } // namespace __detail
|
---|
3213 |
|
---|
3214 | struct _Split : __adaptor::_RangeAdaptor<_Split>
|
---|
3215 | {
|
---|
3216 | template<viewable_range _Range, typename _Pattern>
|
---|
3217 | requires __detail::__can_split_view<_Range, _Pattern>
|
---|
3218 | constexpr auto
|
---|
3219 | operator()(_Range&& __r, _Pattern&& __f) const
|
---|
3220 | {
|
---|
3221 | return split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
|
---|
3222 | }
|
---|
3223 |
|
---|
3224 | using _RangeAdaptor<_Split>::operator();
|
---|
3225 | static constexpr int _S_arity = 2;
|
---|
3226 | // The pattern argument of views::split is not always simple -- it can be
|
---|
3227 | // a non-view range, the value category of which affects whether the call
|
---|
3228 | // is well-formed. But a scalar or a view pattern argument is surely
|
---|
3229 | // simple.
|
---|
3230 | template<typename _Pattern>
|
---|
3231 | static constexpr bool _S_has_simple_extra_args
|
---|
3232 | = is_scalar_v<_Pattern> || (view<_Pattern>
|
---|
3233 | && copy_constructible<_Pattern>);
|
---|
3234 | };
|
---|
3235 |
|
---|
3236 | inline constexpr _Split split;
|
---|
3237 | } // namespace views
|
---|
3238 |
|
---|
3239 | namespace views
|
---|
3240 | {
|
---|
3241 | struct _Counted
|
---|
3242 | {
|
---|
3243 | template<input_or_output_iterator _Iter>
|
---|
3244 | constexpr auto
|
---|
3245 | operator()(_Iter __i, iter_difference_t<_Iter> __n) const
|
---|
3246 | {
|
---|
3247 | if constexpr (random_access_iterator<_Iter>)
|
---|
3248 | return subrange(__i, __i + __n);
|
---|
3249 | else
|
---|
3250 | return subrange(counted_iterator(std::move(__i), __n),
|
---|
3251 | default_sentinel);
|
---|
3252 | }
|
---|
3253 | };
|
---|
3254 |
|
---|
3255 | inline constexpr _Counted counted{};
|
---|
3256 | } // namespace views
|
---|
3257 |
|
---|
3258 | template<view _Vp>
|
---|
3259 | requires (!common_range<_Vp>) && copyable<iterator_t<_Vp>>
|
---|
3260 | class common_view : public view_interface<common_view<_Vp>>
|
---|
3261 | {
|
---|
3262 | private:
|
---|
3263 | _Vp _M_base = _Vp();
|
---|
3264 |
|
---|
3265 | public:
|
---|
3266 | common_view() = default;
|
---|
3267 |
|
---|
3268 | constexpr explicit
|
---|
3269 | common_view(_Vp __r)
|
---|
3270 | : _M_base(std::move(__r))
|
---|
3271 | { }
|
---|
3272 |
|
---|
3273 | /* XXX: LWG 3280 didn't remove this constructor, but I think it should?
|
---|
3274 | template<viewable_range _Range>
|
---|
3275 | requires (!common_range<_Range>)
|
---|
3276 | && constructible_from<_Vp, views::all_t<_Range>>
|
---|
3277 | constexpr explicit
|
---|
3278 | common_view(_Range&& __r)
|
---|
3279 | : _M_base(views::all(std::forward<_Range>(__r)))
|
---|
3280 | { }
|
---|
3281 | */
|
---|
3282 |
|
---|
3283 | constexpr _Vp
|
---|
3284 | base() const& requires copy_constructible<_Vp>
|
---|
3285 | { return _M_base; }
|
---|
3286 |
|
---|
3287 | constexpr _Vp
|
---|
3288 | base() &&
|
---|
3289 | { return std::move(_M_base); }
|
---|
3290 |
|
---|
3291 | constexpr auto
|
---|
3292 | begin()
|
---|
3293 | {
|
---|
3294 | if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
|
---|
3295 | return ranges::begin(_M_base);
|
---|
3296 | else
|
---|
3297 | return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
|
---|
3298 | (ranges::begin(_M_base));
|
---|
3299 | }
|
---|
3300 |
|
---|
3301 | constexpr auto
|
---|
3302 | begin() const requires range<const _Vp>
|
---|
3303 | {
|
---|
3304 | if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
|
---|
3305 | return ranges::begin(_M_base);
|
---|
3306 | else
|
---|
3307 | return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
|
---|
3308 | (ranges::begin(_M_base));
|
---|
3309 | }
|
---|
3310 |
|
---|
3311 | constexpr auto
|
---|
3312 | end()
|
---|
3313 | {
|
---|
3314 | if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
|
---|
3315 | return ranges::begin(_M_base) + ranges::size(_M_base);
|
---|
3316 | else
|
---|
3317 | return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
|
---|
3318 | (ranges::end(_M_base));
|
---|
3319 | }
|
---|
3320 |
|
---|
3321 | constexpr auto
|
---|
3322 | end() const requires range<const _Vp>
|
---|
3323 | {
|
---|
3324 | if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
|
---|
3325 | return ranges::begin(_M_base) + ranges::size(_M_base);
|
---|
3326 | else
|
---|
3327 | return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
|
---|
3328 | (ranges::end(_M_base));
|
---|
3329 | }
|
---|
3330 |
|
---|
3331 | constexpr auto
|
---|
3332 | size() requires sized_range<_Vp>
|
---|
3333 | { return ranges::size(_M_base); }
|
---|
3334 |
|
---|
3335 | constexpr auto
|
---|
3336 | size() const requires sized_range<const _Vp>
|
---|
3337 | { return ranges::size(_M_base); }
|
---|
3338 | };
|
---|
3339 |
|
---|
3340 | template<typename _Range>
|
---|
3341 | common_view(_Range&&) -> common_view<views::all_t<_Range>>;
|
---|
3342 |
|
---|
3343 | template<typename _Tp>
|
---|
3344 | inline constexpr bool enable_borrowed_range<common_view<_Tp>>
|
---|
3345 | = enable_borrowed_range<_Tp>;
|
---|
3346 |
|
---|
3347 | namespace views
|
---|
3348 | {
|
---|
3349 | namespace __detail
|
---|
3350 | {
|
---|
3351 | template<typename _Range>
|
---|
3352 | concept __already_common = common_range<_Range>
|
---|
3353 | && requires { views::all(std::declval<_Range>()); };
|
---|
3354 |
|
---|
3355 | template<typename _Range>
|
---|
3356 | concept __can_common_view
|
---|
3357 | = requires { common_view{std::declval<_Range>()}; };
|
---|
3358 | } // namespace __detail
|
---|
3359 |
|
---|
3360 | struct _Common : __adaptor::_RangeAdaptorClosure
|
---|
3361 | {
|
---|
3362 | template<viewable_range _Range>
|
---|
3363 | requires __detail::__already_common<_Range>
|
---|
3364 | || __detail::__can_common_view<_Range>
|
---|
3365 | constexpr auto
|
---|
3366 | operator()(_Range&& __r) const
|
---|
3367 | {
|
---|
3368 | if constexpr (__detail::__already_common<_Range>)
|
---|
3369 | return views::all(std::forward<_Range>(__r));
|
---|
3370 | else
|
---|
3371 | return common_view{std::forward<_Range>(__r)};
|
---|
3372 | }
|
---|
3373 |
|
---|
3374 | static constexpr bool _S_has_simple_call_op = true;
|
---|
3375 | };
|
---|
3376 |
|
---|
3377 | inline constexpr _Common common;
|
---|
3378 | } // namespace views
|
---|
3379 |
|
---|
3380 | template<view _Vp>
|
---|
3381 | requires bidirectional_range<_Vp>
|
---|
3382 | class reverse_view : public view_interface<reverse_view<_Vp>>
|
---|
3383 | {
|
---|
3384 | private:
|
---|
3385 | static constexpr bool _S_needs_cached_begin
|
---|
3386 | = !common_range<_Vp> && !random_access_range<_Vp>;
|
---|
3387 |
|
---|
3388 | [[no_unique_address]]
|
---|
3389 | __detail::__maybe_present_t<_S_needs_cached_begin,
|
---|
3390 | __detail::_CachedPosition<_Vp>>
|
---|
3391 | _M_cached_begin;
|
---|
3392 | _Vp _M_base = _Vp();
|
---|
3393 |
|
---|
3394 | public:
|
---|
3395 | reverse_view() = default;
|
---|
3396 |
|
---|
3397 | constexpr explicit
|
---|
3398 | reverse_view(_Vp __r)
|
---|
3399 | : _M_base(std::move(__r))
|
---|
3400 | { }
|
---|
3401 |
|
---|
3402 | constexpr _Vp
|
---|
3403 | base() const& requires copy_constructible<_Vp>
|
---|
3404 | { return _M_base; }
|
---|
3405 |
|
---|
3406 | constexpr _Vp
|
---|
3407 | base() &&
|
---|
3408 | { return std::move(_M_base); }
|
---|
3409 |
|
---|
3410 | constexpr reverse_iterator<iterator_t<_Vp>>
|
---|
3411 | begin()
|
---|
3412 | {
|
---|
3413 | if constexpr (_S_needs_cached_begin)
|
---|
3414 | if (_M_cached_begin._M_has_value())
|
---|
3415 | return std::make_reverse_iterator(_M_cached_begin._M_get(_M_base));
|
---|
3416 |
|
---|
3417 | auto __it = ranges::next(ranges::begin(_M_base), ranges::end(_M_base));
|
---|
3418 | if constexpr (_S_needs_cached_begin)
|
---|
3419 | _M_cached_begin._M_set(_M_base, __it);
|
---|
3420 | return std::make_reverse_iterator(std::move(__it));
|
---|
3421 | }
|
---|
3422 |
|
---|
3423 | constexpr auto
|
---|
3424 | begin() requires common_range<_Vp>
|
---|
3425 | { return std::make_reverse_iterator(ranges::end(_M_base)); }
|
---|
3426 |
|
---|
3427 | constexpr auto
|
---|
3428 | begin() const requires common_range<const _Vp>
|
---|
3429 | { return std::make_reverse_iterator(ranges::end(_M_base)); }
|
---|
3430 |
|
---|
3431 | constexpr reverse_iterator<iterator_t<_Vp>>
|
---|
3432 | end()
|
---|
3433 | { return std::make_reverse_iterator(ranges::begin(_M_base)); }
|
---|
3434 |
|
---|
3435 | constexpr auto
|
---|
3436 | end() const requires common_range<const _Vp>
|
---|
3437 | { return std::make_reverse_iterator(ranges::begin(_M_base)); }
|
---|
3438 |
|
---|
3439 | constexpr auto
|
---|
3440 | size() requires sized_range<_Vp>
|
---|
3441 | { return ranges::size(_M_base); }
|
---|
3442 |
|
---|
3443 | constexpr auto
|
---|
3444 | size() const requires sized_range<const _Vp>
|
---|
3445 | { return ranges::size(_M_base); }
|
---|
3446 | };
|
---|
3447 |
|
---|
3448 | template<typename _Range>
|
---|
3449 | reverse_view(_Range&&) -> reverse_view<views::all_t<_Range>>;
|
---|
3450 |
|
---|
3451 | template<typename _Tp>
|
---|
3452 | inline constexpr bool enable_borrowed_range<reverse_view<_Tp>>
|
---|
3453 | = enable_borrowed_range<_Tp>;
|
---|
3454 |
|
---|
3455 | namespace views
|
---|
3456 | {
|
---|
3457 | namespace __detail
|
---|
3458 | {
|
---|
3459 | template<typename>
|
---|
3460 | inline constexpr bool __is_reversible_subrange = false;
|
---|
3461 |
|
---|
3462 | template<typename _Iter, subrange_kind _Kind>
|
---|
3463 | inline constexpr bool
|
---|
3464 | __is_reversible_subrange<subrange<reverse_iterator<_Iter>,
|
---|
3465 | reverse_iterator<_Iter>,
|
---|
3466 | _Kind>> = true;
|
---|
3467 |
|
---|
3468 | template<typename>
|
---|
3469 | inline constexpr bool __is_reverse_view = false;
|
---|
3470 |
|
---|
3471 | template<typename _Vp>
|
---|
3472 | inline constexpr bool __is_reverse_view<reverse_view<_Vp>> = true;
|
---|
3473 |
|
---|
3474 | template<typename _Range>
|
---|
3475 | concept __can_reverse_view
|
---|
3476 | = requires { reverse_view{std::declval<_Range>()}; };
|
---|
3477 | } // namespace __detail
|
---|
3478 |
|
---|
3479 | struct _Reverse : __adaptor::_RangeAdaptorClosure
|
---|
3480 | {
|
---|
3481 | template<viewable_range _Range>
|
---|
3482 | requires __detail::__is_reverse_view<remove_cvref_t<_Range>>
|
---|
3483 | || __detail::__is_reversible_subrange<remove_cvref_t<_Range>>
|
---|
3484 | || __detail::__can_reverse_view<_Range>
|
---|
3485 | constexpr auto
|
---|
3486 | operator()(_Range&& __r) const
|
---|
3487 | {
|
---|
3488 | using _Tp = remove_cvref_t<_Range>;
|
---|
3489 | if constexpr (__detail::__is_reverse_view<_Tp>)
|
---|
3490 | return std::forward<_Range>(__r).base();
|
---|
3491 | else if constexpr (__detail::__is_reversible_subrange<_Tp>)
|
---|
3492 | {
|
---|
3493 | using _Iter = decltype(ranges::begin(__r).base());
|
---|
3494 | if constexpr (sized_range<_Tp>)
|
---|
3495 | return subrange<_Iter, _Iter, subrange_kind::sized>
|
---|
3496 | {__r.end().base(), __r.begin().base(), __r.size()};
|
---|
3497 | else
|
---|
3498 | return subrange<_Iter, _Iter, subrange_kind::unsized>
|
---|
3499 | {__r.end().base(), __r.begin().base()};
|
---|
3500 | }
|
---|
3501 | else
|
---|
3502 | return reverse_view{std::forward<_Range>(__r)};
|
---|
3503 | }
|
---|
3504 |
|
---|
3505 | static constexpr bool _S_has_simple_call_op = true;
|
---|
3506 | };
|
---|
3507 |
|
---|
3508 | inline constexpr _Reverse reverse;
|
---|
3509 | } // namespace views
|
---|
3510 |
|
---|
3511 | namespace __detail
|
---|
3512 | {
|
---|
3513 | template<typename _Tp, size_t _Nm>
|
---|
3514 | concept __has_tuple_element = requires(_Tp __t)
|
---|
3515 | {
|
---|
3516 | typename tuple_size<_Tp>::type;
|
---|
3517 | requires _Nm < tuple_size_v<_Tp>;
|
---|
3518 | typename tuple_element_t<_Nm, _Tp>;
|
---|
3519 | { std::get<_Nm>(__t) }
|
---|
3520 | -> convertible_to<const tuple_element_t<_Nm, _Tp>&>;
|
---|
3521 | };
|
---|
3522 |
|
---|
3523 | template<typename _Tp, size_t _Nm>
|
---|
3524 | concept __returnable_element
|
---|
3525 | = is_reference_v<_Tp> || move_constructible<tuple_element_t<_Nm, _Tp>>;
|
---|
3526 | }
|
---|
3527 |
|
---|
3528 | template<input_range _Vp, size_t _Nm>
|
---|
3529 | requires view<_Vp>
|
---|
3530 | && __detail::__has_tuple_element<range_value_t<_Vp>, _Nm>
|
---|
3531 | && __detail::__has_tuple_element<remove_reference_t<range_reference_t<_Vp>>,
|
---|
3532 | _Nm>
|
---|
3533 | && __detail::__returnable_element<range_reference_t<_Vp>, _Nm>
|
---|
3534 | class elements_view : public view_interface<elements_view<_Vp, _Nm>>
|
---|
3535 | {
|
---|
3536 | public:
|
---|
3537 | elements_view() = default;
|
---|
3538 |
|
---|
3539 | constexpr explicit
|
---|
3540 | elements_view(_Vp base)
|
---|
3541 | : _M_base(std::move(base))
|
---|
3542 | { }
|
---|
3543 |
|
---|
3544 | constexpr const _Vp&
|
---|
3545 | base() const & noexcept
|
---|
3546 | { return _M_base; }
|
---|
3547 |
|
---|
3548 | constexpr _Vp
|
---|
3549 | base() &&
|
---|
3550 | { return std::move(_M_base); }
|
---|
3551 |
|
---|
3552 | constexpr auto
|
---|
3553 | begin() requires (!__detail::__simple_view<_Vp>)
|
---|
3554 | { return _Iterator<false>(ranges::begin(_M_base)); }
|
---|
3555 |
|
---|
3556 | constexpr auto
|
---|
3557 | begin() const requires range<const _Vp>
|
---|
3558 | { return _Iterator<true>(ranges::begin(_M_base)); }
|
---|
3559 |
|
---|
3560 | constexpr auto
|
---|
3561 | end() requires (!__detail::__simple_view<_Vp> && !common_range<_Vp>)
|
---|
3562 | { return _Sentinel<false>{ranges::end(_M_base)}; }
|
---|
3563 |
|
---|
3564 | constexpr auto
|
---|
3565 | end() requires (!__detail::__simple_view<_Vp> && common_range<_Vp>)
|
---|
3566 | { return _Iterator<false>{ranges::end(_M_base)}; }
|
---|
3567 |
|
---|
3568 | constexpr auto
|
---|
3569 | end() const requires range<const _Vp>
|
---|
3570 | { return _Sentinel<true>{ranges::end(_M_base)}; }
|
---|
3571 |
|
---|
3572 | constexpr auto
|
---|
3573 | end() const requires common_range<const _Vp>
|
---|
3574 | { return _Iterator<true>{ranges::end(_M_base)}; }
|
---|
3575 |
|
---|
3576 | constexpr auto
|
---|
3577 | size() requires sized_range<_Vp>
|
---|
3578 | { return ranges::size(_M_base); }
|
---|
3579 |
|
---|
3580 | constexpr auto
|
---|
3581 | size() const requires sized_range<const _Vp>
|
---|
3582 | { return ranges::size(_M_base); }
|
---|
3583 |
|
---|
3584 | private:
|
---|
3585 | template<bool _Const>
|
---|
3586 | using _Base = __detail::__maybe_const_t<_Const, _Vp>;
|
---|
3587 |
|
---|
3588 | template<bool _Const>
|
---|
3589 | struct __iter_cat
|
---|
3590 | { };
|
---|
3591 |
|
---|
3592 | template<bool _Const>
|
---|
3593 | requires forward_range<_Base<_Const>>
|
---|
3594 | struct __iter_cat<_Const>
|
---|
3595 | {
|
---|
3596 | private:
|
---|
3597 | static auto _S_iter_cat()
|
---|
3598 | {
|
---|
3599 | using _Base = elements_view::_Base<_Const>;
|
---|
3600 | using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
|
---|
3601 | using _Res = decltype((std::get<_Nm>(*std::declval<iterator_t<_Base>>())));
|
---|
3602 | if constexpr (!is_lvalue_reference_v<_Res>)
|
---|
3603 | return input_iterator_tag{};
|
---|
3604 | else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
|
---|
3605 | return random_access_iterator_tag{};
|
---|
3606 | else
|
---|
3607 | return _Cat{};
|
---|
3608 | }
|
---|
3609 | public:
|
---|
3610 | using iterator_category = decltype(_S_iter_cat());
|
---|
3611 | };
|
---|
3612 |
|
---|
3613 | template<bool _Const>
|
---|
3614 | struct _Sentinel;
|
---|
3615 |
|
---|
3616 | template<bool _Const>
|
---|
3617 | struct _Iterator : __iter_cat<_Const>
|
---|
3618 | {
|
---|
3619 | private:
|
---|
3620 | using _Base = elements_view::_Base<_Const>;
|
---|
3621 |
|
---|
3622 | iterator_t<_Base> _M_current = iterator_t<_Base>();
|
---|
3623 |
|
---|
3624 | static constexpr decltype(auto)
|
---|
3625 | _S_get_element(const iterator_t<_Base>& __i)
|
---|
3626 | {
|
---|
3627 | if constexpr (is_reference_v<range_reference_t<_Base>>)
|
---|
3628 | return std::get<_Nm>(*__i);
|
---|
3629 | else
|
---|
3630 | {
|
---|
3631 | using _Et = remove_cv_t<tuple_element_t<_Nm, range_reference_t<_Base>>>;
|
---|
3632 | return static_cast<_Et>(std::get<_Nm>(*__i));
|
---|
3633 | }
|
---|
3634 | }
|
---|
3635 |
|
---|
3636 | static auto
|
---|
3637 | _S_iter_concept()
|
---|
3638 | {
|
---|
3639 | if constexpr (random_access_range<_Vp>)
|
---|
3640 | return random_access_iterator_tag{};
|
---|
3641 | else if constexpr (bidirectional_range<_Vp>)
|
---|
3642 | return bidirectional_iterator_tag{};
|
---|
3643 | else if constexpr (forward_range<_Vp>)
|
---|
3644 | return forward_iterator_tag{};
|
---|
3645 | else
|
---|
3646 | return input_iterator_tag{};
|
---|
3647 | }
|
---|
3648 |
|
---|
3649 | friend _Iterator<!_Const>;
|
---|
3650 |
|
---|
3651 | public:
|
---|
3652 | using iterator_concept = decltype(_S_iter_concept());
|
---|
3653 | // iterator_category defined in elements_view::__iter_cat
|
---|
3654 | using value_type
|
---|
3655 | = remove_cvref_t<tuple_element_t<_Nm, range_value_t<_Base>>>;
|
---|
3656 | using difference_type = range_difference_t<_Base>;
|
---|
3657 |
|
---|
3658 | _Iterator() = default;
|
---|
3659 |
|
---|
3660 | constexpr explicit
|
---|
3661 | _Iterator(iterator_t<_Base> current)
|
---|
3662 | : _M_current(std::move(current))
|
---|
3663 | { }
|
---|
3664 |
|
---|
3665 | constexpr
|
---|
3666 | _Iterator(_Iterator<!_Const> i)
|
---|
3667 | requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
|
---|
3668 | : _M_current(std::move(i._M_current))
|
---|
3669 | { }
|
---|
3670 |
|
---|
3671 | constexpr iterator_t<_Base>
|
---|
3672 | base() const&
|
---|
3673 | requires copyable<iterator_t<_Base>>
|
---|
3674 | { return _M_current; }
|
---|
3675 |
|
---|
3676 | constexpr iterator_t<_Base>
|
---|
3677 | base() &&
|
---|
3678 | { return std::move(_M_current); }
|
---|
3679 |
|
---|
3680 | constexpr decltype(auto)
|
---|
3681 | operator*() const
|
---|
3682 | { return _S_get_element(_M_current); }
|
---|
3683 |
|
---|
3684 | constexpr _Iterator&
|
---|
3685 | operator++()
|
---|
3686 | {
|
---|
3687 | ++_M_current;
|
---|
3688 | return *this;
|
---|
3689 | }
|
---|
3690 |
|
---|
3691 | constexpr void
|
---|
3692 | operator++(int)
|
---|
3693 | { ++_M_current; }
|
---|
3694 |
|
---|
3695 | constexpr _Iterator
|
---|
3696 | operator++(int) requires forward_range<_Base>
|
---|
3697 | {
|
---|
3698 | auto __tmp = *this;
|
---|
3699 | ++_M_current;
|
---|
3700 | return __tmp;
|
---|
3701 | }
|
---|
3702 |
|
---|
3703 | constexpr _Iterator&
|
---|
3704 | operator--() requires bidirectional_range<_Base>
|
---|
3705 | {
|
---|
3706 | --_M_current;
|
---|
3707 | return *this;
|
---|
3708 | }
|
---|
3709 |
|
---|
3710 | constexpr _Iterator
|
---|
3711 | operator--(int) requires bidirectional_range<_Base>
|
---|
3712 | {
|
---|
3713 | auto __tmp = *this;
|
---|
3714 | --_M_current;
|
---|
3715 | return __tmp;
|
---|
3716 | }
|
---|
3717 |
|
---|
3718 | constexpr _Iterator&
|
---|
3719 | operator+=(difference_type __n)
|
---|
3720 | requires random_access_range<_Base>
|
---|
3721 | {
|
---|
3722 | _M_current += __n;
|
---|
3723 | return *this;
|
---|
3724 | }
|
---|
3725 |
|
---|
3726 | constexpr _Iterator&
|
---|
3727 | operator-=(difference_type __n)
|
---|
3728 | requires random_access_range<_Base>
|
---|
3729 | {
|
---|
3730 | _M_current -= __n;
|
---|
3731 | return *this;
|
---|
3732 | }
|
---|
3733 |
|
---|
3734 | constexpr decltype(auto)
|
---|
3735 | operator[](difference_type __n) const
|
---|
3736 | requires random_access_range<_Base>
|
---|
3737 | { return _S_get_element(_M_current + __n); }
|
---|
3738 |
|
---|
3739 | friend constexpr bool
|
---|
3740 | operator==(const _Iterator& __x, const _Iterator& __y)
|
---|
3741 | requires equality_comparable<iterator_t<_Base>>
|
---|
3742 | { return __x._M_current == __y._M_current; }
|
---|
3743 |
|
---|
3744 | friend constexpr bool
|
---|
3745 | operator<(const _Iterator& __x, const _Iterator& __y)
|
---|
3746 | requires random_access_range<_Base>
|
---|
3747 | { return __x._M_current < __y._M_current; }
|
---|
3748 |
|
---|
3749 | friend constexpr bool
|
---|
3750 | operator>(const _Iterator& __x, const _Iterator& __y)
|
---|
3751 | requires random_access_range<_Base>
|
---|
3752 | { return __y._M_current < __x._M_current; }
|
---|
3753 |
|
---|
3754 | friend constexpr bool
|
---|
3755 | operator<=(const _Iterator& __x, const _Iterator& __y)
|
---|
3756 | requires random_access_range<_Base>
|
---|
3757 | { return !(__y._M_current > __x._M_current); }
|
---|
3758 |
|
---|
3759 | friend constexpr bool
|
---|
3760 | operator>=(const _Iterator& __x, const _Iterator& __y)
|
---|
3761 | requires random_access_range<_Base>
|
---|
3762 | { return !(__x._M_current > __y._M_current); }
|
---|
3763 |
|
---|
3764 | #ifdef __cpp_lib_three_way_comparison
|
---|
3765 | friend constexpr auto
|
---|
3766 | operator<=>(const _Iterator& __x, const _Iterator& __y)
|
---|
3767 | requires random_access_range<_Base>
|
---|
3768 | && three_way_comparable<iterator_t<_Base>>
|
---|
3769 | { return __x._M_current <=> __y._M_current; }
|
---|
3770 | #endif
|
---|
3771 |
|
---|
3772 | friend constexpr _Iterator
|
---|
3773 | operator+(const _Iterator& __x, difference_type __y)
|
---|
3774 | requires random_access_range<_Base>
|
---|
3775 | { return _Iterator{__x} += __y; }
|
---|
3776 |
|
---|
3777 | friend constexpr _Iterator
|
---|
3778 | operator+(difference_type __x, const _Iterator& __y)
|
---|
3779 | requires random_access_range<_Base>
|
---|
3780 | { return __y + __x; }
|
---|
3781 |
|
---|
3782 | friend constexpr _Iterator
|
---|
3783 | operator-(const _Iterator& __x, difference_type __y)
|
---|
3784 | requires random_access_range<_Base>
|
---|
3785 | { return _Iterator{__x} -= __y; }
|
---|
3786 |
|
---|
3787 | // _GLIBCXX_RESOLVE_LIB_DEFECTS
|
---|
3788 | // 3483. transform_view::iterator's difference is overconstrained
|
---|
3789 | friend constexpr difference_type
|
---|
3790 | operator-(const _Iterator& __x, const _Iterator& __y)
|
---|
3791 | requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
|
---|
3792 | { return __x._M_current - __y._M_current; }
|
---|
3793 |
|
---|
3794 | template <bool> friend struct _Sentinel;
|
---|
3795 | };
|
---|
3796 |
|
---|
3797 | template<bool _Const>
|
---|
3798 | struct _Sentinel
|
---|
3799 | {
|
---|
3800 | private:
|
---|
3801 | template<bool _Const2>
|
---|
3802 | constexpr bool
|
---|
3803 | _M_equal(const _Iterator<_Const2>& __x) const
|
---|
3804 | { return __x._M_current == _M_end; }
|
---|
3805 |
|
---|
3806 | template<bool _Const2>
|
---|
3807 | constexpr auto
|
---|
3808 | _M_distance_from(const _Iterator<_Const2>& __i) const
|
---|
3809 | { return _M_end - __i._M_current; }
|
---|
3810 |
|
---|
3811 | using _Base = elements_view::_Base<_Const>;
|
---|
3812 | sentinel_t<_Base> _M_end = sentinel_t<_Base>();
|
---|
3813 |
|
---|
3814 | public:
|
---|
3815 | _Sentinel() = default;
|
---|
3816 |
|
---|
3817 | constexpr explicit
|
---|
3818 | _Sentinel(sentinel_t<_Base> __end)
|
---|
3819 | : _M_end(std::move(__end))
|
---|
3820 | { }
|
---|
3821 |
|
---|
3822 | constexpr
|
---|
3823 | _Sentinel(_Sentinel<!_Const> __other)
|
---|
3824 | requires _Const
|
---|
3825 | && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
|
---|
3826 | : _M_end(std::move(__other._M_end))
|
---|
3827 | { }
|
---|
3828 |
|
---|
3829 | constexpr sentinel_t<_Base>
|
---|
3830 | base() const
|
---|
3831 | { return _M_end; }
|
---|
3832 |
|
---|
3833 | template<bool _Const2>
|
---|
3834 | requires sentinel_for<sentinel_t<_Base>,
|
---|
3835 | iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
|
---|
3836 | friend constexpr bool
|
---|
3837 | operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
|
---|
3838 | { return __y._M_equal(__x); }
|
---|
3839 |
|
---|
3840 | template<bool _Const2,
|
---|
3841 | typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
|
---|
3842 | requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
|
---|
3843 | friend constexpr range_difference_t<_Base2>
|
---|
3844 | operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
|
---|
3845 | { return -__y._M_distance_from(__x); }
|
---|
3846 |
|
---|
3847 | template<bool _Const2,
|
---|
3848 | typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
|
---|
3849 | requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
|
---|
3850 | friend constexpr range_difference_t<_Base2>
|
---|
3851 | operator-(const _Sentinel& __x, const _Iterator<_Const2>& __y)
|
---|
3852 | { return __x._M_distance_from(__y); }
|
---|
3853 |
|
---|
3854 | friend _Sentinel<!_Const>;
|
---|
3855 | };
|
---|
3856 |
|
---|
3857 | _Vp _M_base = _Vp();
|
---|
3858 | };
|
---|
3859 |
|
---|
3860 | template<typename _Tp, size_t _Nm>
|
---|
3861 | inline constexpr bool enable_borrowed_range<elements_view<_Tp, _Nm>>
|
---|
3862 | = enable_borrowed_range<_Tp>;
|
---|
3863 |
|
---|
3864 | template<typename _Range>
|
---|
3865 | using keys_view = elements_view<views::all_t<_Range>, 0>;
|
---|
3866 |
|
---|
3867 | template<typename _Range>
|
---|
3868 | using values_view = elements_view<views::all_t<_Range>, 1>;
|
---|
3869 |
|
---|
3870 | namespace views
|
---|
3871 | {
|
---|
3872 | namespace __detail
|
---|
3873 | {
|
---|
3874 | template<size_t _Nm, typename _Range>
|
---|
3875 | concept __can_elements_view
|
---|
3876 | = requires { elements_view<all_t<_Range>, _Nm>{std::declval<_Range>()}; };
|
---|
3877 | } // namespace __detail
|
---|
3878 |
|
---|
3879 | template<size_t _Nm>
|
---|
3880 | struct _Elements : __adaptor::_RangeAdaptorClosure
|
---|
3881 | {
|
---|
3882 | template<viewable_range _Range>
|
---|
3883 | requires __detail::__can_elements_view<_Nm, _Range>
|
---|
3884 | constexpr auto
|
---|
3885 | operator()(_Range&& __r) const
|
---|
3886 | {
|
---|
3887 | return elements_view<all_t<_Range>, _Nm>{std::forward<_Range>(__r)};
|
---|
3888 | }
|
---|
3889 |
|
---|
3890 | static constexpr bool _S_has_simple_call_op = true;
|
---|
3891 | };
|
---|
3892 |
|
---|
3893 | template<size_t _Nm>
|
---|
3894 | inline constexpr _Elements<_Nm> elements;
|
---|
3895 | inline constexpr auto keys = elements<0>;
|
---|
3896 | inline constexpr auto values = elements<1>;
|
---|
3897 | } // namespace views
|
---|
3898 |
|
---|
3899 | } // namespace ranges
|
---|
3900 |
|
---|
3901 | namespace views = ranges::views;
|
---|
3902 |
|
---|
3903 | _GLIBCXX_END_NAMESPACE_VERSION
|
---|
3904 | } // namespace
|
---|
3905 | #endif // library concepts
|
---|
3906 | #endif // C++2a
|
---|
3907 | #endif /* _GLIBCXX_RANGES */
|
---|