libstdc++
iterator_concepts.h
Go to the documentation of this file.
1// Concepts and traits for use with iterators -*- C++ -*-
2
3// Copyright (C) 2019-2022 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file bits/iterator_concepts.h
26 * This is an internal header file, included by other library headers.
27 * Do not attempt to use it directly. @headername{iterator}
28 */
29
30#ifndef _ITERATOR_CONCEPTS_H
31#define _ITERATOR_CONCEPTS_H 1
32
33#pragma GCC system_header
34
35#include <concepts>
36#include <bits/ptr_traits.h> // to_address
37#include <bits/ranges_cmp.h> // identity, ranges::less
38
39#if __cpp_lib_concepts
40namespace std _GLIBCXX_VISIBILITY(default)
41{
42_GLIBCXX_BEGIN_NAMESPACE_VERSION
43
44 struct input_iterator_tag;
45 struct output_iterator_tag;
46 struct forward_iterator_tag;
47 struct bidirectional_iterator_tag;
48 struct random_access_iterator_tag;
49 struct contiguous_iterator_tag;
50
51 template<typename _Iterator>
52 struct iterator_traits;
53
54 template<typename _Tp> requires is_object_v<_Tp>
55 struct iterator_traits<_Tp*>;
56
57 template<typename _Iterator, typename>
58 struct __iterator_traits;
59
60 namespace __detail
61 {
62 template<typename _Tp>
63 using __with_ref = _Tp&;
64
65 template<typename _Tp>
66 concept __can_reference = requires { typename __with_ref<_Tp>; };
67
68 template<typename _Tp>
69 concept __dereferenceable = requires(_Tp& __t)
70 {
71 { *__t } -> __can_reference;
72 };
73 } // namespace __detail
74
75 template<__detail::__dereferenceable _Tp>
76 using iter_reference_t = decltype(*std::declval<_Tp&>());
77
78 namespace ranges
79 {
80 namespace __cust_imove
81 {
82 void iter_move();
83
84 template<typename _Tp>
85 concept __adl_imove
86 = (std::__detail::__class_or_enum<remove_reference_t<_Tp>>)
87 && requires(_Tp&& __t) { iter_move(static_cast<_Tp&&>(__t)); };
88
89 struct _IMove
90 {
91 private:
92 template<typename _Tp>
93 struct __result
94 { using type = iter_reference_t<_Tp>; };
95
96 template<typename _Tp>
97 requires __adl_imove<_Tp>
98 struct __result<_Tp>
99 { using type = decltype(iter_move(std::declval<_Tp>())); };
100
101 template<typename _Tp>
102 requires (!__adl_imove<_Tp>)
103 && is_lvalue_reference_v<iter_reference_t<_Tp>>
104 struct __result<_Tp>
105 { using type = remove_reference_t<iter_reference_t<_Tp>>&&; };
106
107 template<typename _Tp>
108 static constexpr bool
109 _S_noexcept()
110 {
111 if constexpr (__adl_imove<_Tp>)
112 return noexcept(iter_move(std::declval<_Tp>()));
113 else
114 return noexcept(*std::declval<_Tp>());
115 }
116
117 public:
118 // The result type of iter_move(std::declval<_Tp>())
119 template<std::__detail::__dereferenceable _Tp>
120 using __type = typename __result<_Tp>::type;
121
122 template<std::__detail::__dereferenceable _Tp>
123 [[nodiscard]]
124 constexpr __type<_Tp>
125 operator()(_Tp&& __e) const
126 noexcept(_S_noexcept<_Tp>())
127 {
128 if constexpr (__adl_imove<_Tp>)
129 return iter_move(static_cast<_Tp&&>(__e));
130 else if constexpr (is_lvalue_reference_v<iter_reference_t<_Tp>>)
131 return static_cast<__type<_Tp>>(*__e);
132 else
133 return *__e;
134 }
135 };
136 } // namespace __cust_imove
137
138 inline namespace __cust
139 {
140 inline constexpr __cust_imove::_IMove iter_move{};
141 } // inline namespace __cust
142 } // namespace ranges
143
144 template<__detail::__dereferenceable _Tp>
145 requires __detail::
146 __can_reference<ranges::__cust_imove::_IMove::__type<_Tp&>>
147 using iter_rvalue_reference_t
148 = ranges::__cust_imove::_IMove::__type<_Tp&>;
149
150 template<typename> struct incrementable_traits { };
151
152 template<typename _Tp> requires is_object_v<_Tp>
153 struct incrementable_traits<_Tp*>
154 { using difference_type = ptrdiff_t; };
155
156 template<typename _Iter>
157 struct incrementable_traits<const _Iter>
158 : incrementable_traits<_Iter> { };
159
160 template<typename _Tp> requires requires { typename _Tp::difference_type; }
161 struct incrementable_traits<_Tp>
162 { using difference_type = typename _Tp::difference_type; };
163
164 template<typename _Tp>
165 requires (!requires { typename _Tp::difference_type; }
166 && requires(const _Tp& __a, const _Tp& __b)
167 { { __a - __b } -> integral; })
168 struct incrementable_traits<_Tp>
169 {
170 using difference_type
171 = make_signed_t<decltype(std::declval<_Tp>() - std::declval<_Tp>())>;
172 };
173
174#if defined __STRICT_ANSI__ && defined __SIZEOF_INT128__
175 // __int128 is incrementable even if !integral<__int128>
176 template<>
177 struct incrementable_traits<__int128>
178 { using difference_type = __int128; };
179
180 template<>
181 struct incrementable_traits<unsigned __int128>
182 { using difference_type = __int128; };
183#endif
184
185 namespace __detail
186 {
187 // An iterator such that iterator_traits<_Iter> names a specialization
188 // generated from the primary template.
189 template<typename _Iter>
190 concept __primary_traits_iter
191 = __is_base_of(__iterator_traits<_Iter, void>, iterator_traits<_Iter>);
192
193 template<typename _Iter, typename _Tp>
194 struct __iter_traits_impl
195 { using type = iterator_traits<_Iter>; };
196
197 template<typename _Iter, typename _Tp>
198 requires __primary_traits_iter<_Iter>
199 struct __iter_traits_impl<_Iter, _Tp>
200 { using type = _Tp; };
201
202 // ITER_TRAITS
203 template<typename _Iter, typename _Tp = _Iter>
204 using __iter_traits = typename __iter_traits_impl<_Iter, _Tp>::type;
205
206 template<typename _Tp>
207 using __iter_diff_t = typename
208 __iter_traits<_Tp, incrementable_traits<_Tp>>::difference_type;
209 } // namespace __detail
210
211 template<typename _Tp>
212 using iter_difference_t = __detail::__iter_diff_t<remove_cvref_t<_Tp>>;
213
214 namespace __detail
215 {
216 template<typename> struct __cond_value_type { };
217
218 template<typename _Tp> requires is_object_v<_Tp>
219 struct __cond_value_type<_Tp>
220 { using value_type = remove_cv_t<_Tp>; };
221
222 template<typename _Tp>
223 concept __has_member_value_type
224 = requires { typename _Tp::value_type; };
225
226 template<typename _Tp>
227 concept __has_member_element_type
228 = requires { typename _Tp::element_type; };
229
230 } // namespace __detail
231
232 template<typename> struct indirectly_readable_traits { };
233
234 template<typename _Tp>
235 struct indirectly_readable_traits<_Tp*>
236 : __detail::__cond_value_type<_Tp>
237 { };
238
239 template<typename _Iter> requires is_array_v<_Iter>
240 struct indirectly_readable_traits<_Iter>
241 { using value_type = remove_cv_t<remove_extent_t<_Iter>>; };
242
243 template<typename _Iter>
244 struct indirectly_readable_traits<const _Iter>
245 : indirectly_readable_traits<_Iter>
246 { };
247
248 template<__detail::__has_member_value_type _Tp>
249 struct indirectly_readable_traits<_Tp>
250 : __detail::__cond_value_type<typename _Tp::value_type>
251 { };
252
253 template<__detail::__has_member_element_type _Tp>
254 struct indirectly_readable_traits<_Tp>
255 : __detail::__cond_value_type<typename _Tp::element_type>
256 { };
257
258 // _GLIBCXX_RESOLVE_LIB_DEFECTS
259 // 3446. indirectly_readable_traits ambiguity for types with both [...]
260 template<__detail::__has_member_value_type _Tp>
261 requires __detail::__has_member_element_type<_Tp>
262 && same_as<remove_cv_t<typename _Tp::element_type>,
263 remove_cv_t<typename _Tp::value_type>>
264 struct indirectly_readable_traits<_Tp>
265 : __detail::__cond_value_type<typename _Tp::value_type>
266 { };
267
268 // _GLIBCXX_RESOLVE_LIB_DEFECTS
269 // 3541. indirectly_readable_traits should be SFINAE-friendly for all types
270 template<__detail::__has_member_value_type _Tp>
271 requires __detail::__has_member_element_type<_Tp>
272 struct indirectly_readable_traits<_Tp>
273 { };
274
275 namespace __detail
276 {
277 template<typename _Tp>
278 using __iter_value_t = typename
279 __iter_traits<_Tp, indirectly_readable_traits<_Tp>>::value_type;
280 } // namespace __detail
281
282 template<typename _Tp>
283 using iter_value_t = __detail::__iter_value_t<remove_cvref_t<_Tp>>;
284
285 namespace __detail
286 {
287 // _GLIBCXX_RESOLVE_LIB_DEFECTS
288 // 3420. cpp17-iterator should check [type] looks like an iterator first
289 template<typename _Iter>
290 concept __cpp17_iterator = requires(_Iter __it)
291 {
292 { *__it } -> __can_reference;
293 { ++__it } -> same_as<_Iter&>;
294 { *__it++ } -> __can_reference;
295 } && copyable<_Iter>;
296
297 template<typename _Iter>
298 concept __cpp17_input_iterator = __cpp17_iterator<_Iter>
299 && equality_comparable<_Iter>
300 && requires(_Iter __it)
301 {
302 typename incrementable_traits<_Iter>::difference_type;
303 typename indirectly_readable_traits<_Iter>::value_type;
304 typename common_reference_t<iter_reference_t<_Iter>&&,
305 typename indirectly_readable_traits<_Iter>::value_type&>;
306 typename common_reference_t<decltype(*__it++)&&,
307 typename indirectly_readable_traits<_Iter>::value_type&>;
308 requires signed_integral<
309 typename incrementable_traits<_Iter>::difference_type>;
310 };
311
312 template<typename _Iter>
313 concept __cpp17_fwd_iterator = __cpp17_input_iterator<_Iter>
314 && constructible_from<_Iter>
315 && is_lvalue_reference_v<iter_reference_t<_Iter>>
316 && same_as<remove_cvref_t<iter_reference_t<_Iter>>,
317 typename indirectly_readable_traits<_Iter>::value_type>
318 && requires(_Iter __it)
319 {
320 { __it++ } -> convertible_to<const _Iter&>;
321 { *__it++ } -> same_as<iter_reference_t<_Iter>>;
322 };
323
324 template<typename _Iter>
325 concept __cpp17_bidi_iterator = __cpp17_fwd_iterator<_Iter>
326 && requires(_Iter __it)
327 {
328 { --__it } -> same_as<_Iter&>;
329 { __it-- } -> convertible_to<const _Iter&>;
330 { *__it-- } -> same_as<iter_reference_t<_Iter>>;
331 };
332
333 template<typename _Iter>
334 concept __cpp17_randacc_iterator = __cpp17_bidi_iterator<_Iter>
335 && totally_ordered<_Iter>
336 && requires(_Iter __it,
337 typename incrementable_traits<_Iter>::difference_type __n)
338 {
339 { __it += __n } -> same_as<_Iter&>;
340 { __it -= __n } -> same_as<_Iter&>;
341 { __it + __n } -> same_as<_Iter>;
342 { __n + __it } -> same_as<_Iter>;
343 { __it - __n } -> same_as<_Iter>;
344 { __it - __it } -> same_as<decltype(__n)>;
345 { __it[__n] } -> convertible_to<iter_reference_t<_Iter>>;
346 };
347
348 template<typename _Iter>
349 concept __iter_with_nested_types = requires {
350 typename _Iter::iterator_category;
351 typename _Iter::value_type;
352 typename _Iter::difference_type;
353 typename _Iter::reference;
354 };
355
356 template<typename _Iter>
357 concept __iter_without_nested_types = !__iter_with_nested_types<_Iter>;
358
359 template<typename _Iter>
360 concept __iter_without_category
361 = !requires { typename _Iter::iterator_category; };
362
363 } // namespace __detail
364
365 template<typename _Iterator>
366 requires __detail::__iter_with_nested_types<_Iterator>
367 struct __iterator_traits<_Iterator, void>
368 {
369 private:
370 template<typename _Iter>
371 struct __ptr
372 { using type = void; };
373
374 template<typename _Iter> requires requires { typename _Iter::pointer; }
375 struct __ptr<_Iter>
376 { using type = typename _Iter::pointer; };
377
378 public:
379 using iterator_category = typename _Iterator::iterator_category;
380 using value_type = typename _Iterator::value_type;
381 using difference_type = typename _Iterator::difference_type;
382 using pointer = typename __ptr<_Iterator>::type;
383 using reference = typename _Iterator::reference;
384 };
385
386 template<typename _Iterator>
387 requires __detail::__iter_without_nested_types<_Iterator>
388 && __detail::__cpp17_input_iterator<_Iterator>
389 struct __iterator_traits<_Iterator, void>
390 {
391 private:
392 template<typename _Iter>
393 struct __cat
394 { using type = input_iterator_tag; };
395
396 template<typename _Iter>
397 requires requires { typename _Iter::iterator_category; }
398 struct __cat<_Iter>
399 { using type = typename _Iter::iterator_category; };
400
401 template<typename _Iter>
402 requires __detail::__iter_without_category<_Iter>
403 && __detail::__cpp17_randacc_iterator<_Iter>
404 struct __cat<_Iter>
405 { using type = random_access_iterator_tag; };
406
407 template<typename _Iter>
408 requires __detail::__iter_without_category<_Iter>
409 && __detail::__cpp17_bidi_iterator<_Iter>
410 struct __cat<_Iter>
411 { using type = bidirectional_iterator_tag; };
412
413 template<typename _Iter>
414 requires __detail::__iter_without_category<_Iter>
415 && __detail::__cpp17_fwd_iterator<_Iter>
416 struct __cat<_Iter>
417 { using type = forward_iterator_tag; };
418
419 template<typename _Iter>
420 struct __ptr
421 { using type = void; };
422
423 template<typename _Iter> requires requires { typename _Iter::pointer; }
424 struct __ptr<_Iter>
425 { using type = typename _Iter::pointer; };
426
427 template<typename _Iter>
428 requires (!requires { typename _Iter::pointer; }
429 && requires(_Iter& __it) { __it.operator->(); })
430 struct __ptr<_Iter>
431 { using type = decltype(std::declval<_Iter&>().operator->()); };
432
433 template<typename _Iter>
434 struct __ref
435 { using type = iter_reference_t<_Iter>; };
436
437 template<typename _Iter> requires requires { typename _Iter::reference; }
438 struct __ref<_Iter>
439 { using type = typename _Iter::reference; };
440
441 public:
442 using iterator_category = typename __cat<_Iterator>::type;
443 using value_type
444 = typename indirectly_readable_traits<_Iterator>::value_type;
445 using difference_type
446 = typename incrementable_traits<_Iterator>::difference_type;
447 using pointer = typename __ptr<_Iterator>::type;
448 using reference = typename __ref<_Iterator>::type;
449 };
450
451 template<typename _Iterator>
452 requires __detail::__iter_without_nested_types<_Iterator>
453 && __detail::__cpp17_iterator<_Iterator>
454 struct __iterator_traits<_Iterator, void>
455 {
456 private:
457 template<typename _Iter>
458 struct __diff
459 { using type = void; };
460
461 template<typename _Iter>
462 requires requires
463 { typename incrementable_traits<_Iter>::difference_type; }
464 struct __diff<_Iter>
465 {
466 using type = typename incrementable_traits<_Iter>::difference_type;
467 };
468
469 public:
470 using iterator_category = output_iterator_tag;
471 using value_type = void;
472 using difference_type = typename __diff<_Iterator>::type;
473 using pointer = void;
474 using reference = void;
475 };
476
477 namespace __detail
478 {
479 template<typename _Iter>
480 struct __iter_concept_impl;
481
482 // ITER_CONCEPT(I) is ITER_TRAITS(I)::iterator_concept if that is valid.
483 template<typename _Iter>
484 requires requires { typename __iter_traits<_Iter>::iterator_concept; }
485 struct __iter_concept_impl<_Iter>
486 { using type = typename __iter_traits<_Iter>::iterator_concept; };
487
488 // Otherwise, ITER_TRAITS(I)::iterator_category if that is valid.
489 template<typename _Iter>
490 requires (!requires { typename __iter_traits<_Iter>::iterator_concept; }
491 && requires { typename __iter_traits<_Iter>::iterator_category; })
492 struct __iter_concept_impl<_Iter>
493 { using type = typename __iter_traits<_Iter>::iterator_category; };
494
495 // Otherwise, random_access_tag if iterator_traits<I> is not specialized.
496 template<typename _Iter>
497 requires (!requires { typename __iter_traits<_Iter>::iterator_concept; }
498 && !requires { typename __iter_traits<_Iter>::iterator_category; }
499 && __primary_traits_iter<_Iter>)
500 struct __iter_concept_impl<_Iter>
501 { using type = random_access_iterator_tag; };
502
503 // Otherwise, there is no ITER_CONCEPT(I) type.
504 template<typename _Iter>
505 struct __iter_concept_impl
506 { };
507
508 // ITER_CONCEPT
509 template<typename _Iter>
510 using __iter_concept = typename __iter_concept_impl<_Iter>::type;
511
512 template<typename _In>
513 concept __indirectly_readable_impl = requires
514 {
515 typename iter_value_t<_In>;
516 typename iter_reference_t<_In>;
517 typename iter_rvalue_reference_t<_In>;
518 requires same_as<iter_reference_t<const _In>,
519 iter_reference_t<_In>>;
520 requires same_as<iter_rvalue_reference_t<const _In>,
521 iter_rvalue_reference_t<_In>>;
522 }
523 && common_reference_with<iter_reference_t<_In>&&, iter_value_t<_In>&>
524 && common_reference_with<iter_reference_t<_In>&&,
525 iter_rvalue_reference_t<_In>&&>
526 && common_reference_with<iter_rvalue_reference_t<_In>&&,
527 const iter_value_t<_In>&>;
528
529 } // namespace __detail
530
531 /// Requirements for types that are readable by applying operator*.
532 template<typename _In>
533 concept indirectly_readable
534 = __detail::__indirectly_readable_impl<remove_cvref_t<_In>>;
535
536 template<indirectly_readable _Tp>
537 using iter_common_reference_t
538 = common_reference_t<iter_reference_t<_Tp>, iter_value_t<_Tp>&>;
539
540 /// Requirements for writing a value into an iterator's referenced object.
541 template<typename _Out, typename _Tp>
542 concept indirectly_writable = requires(_Out&& __o, _Tp&& __t)
543 {
544 *__o = std::forward<_Tp>(__t);
545 *std::forward<_Out>(__o) = std::forward<_Tp>(__t);
546 const_cast<const iter_reference_t<_Out>&&>(*__o)
547 = std::forward<_Tp>(__t);
548 const_cast<const iter_reference_t<_Out>&&>(*std::forward<_Out>(__o))
549 = std::forward<_Tp>(__t);
550 };
551
552 namespace ranges::__detail
553 {
554 class __max_diff_type;
555 class __max_size_type;
556
557 __extension__
558 template<typename _Tp>
559 concept __is_signed_int128
560#if __SIZEOF_INT128__
562#else
563 = false;
564#endif
565
566 __extension__
567 template<typename _Tp>
568 concept __is_unsigned_int128
569#if __SIZEOF_INT128__
571#else
572 = false;
573#endif
574
575 template<typename _Tp>
577
578 template<typename _Tp>
579 concept __integral_nonbool = integral<_Tp> && !__cv_bool<_Tp>;
580
581 template<typename _Tp>
582 concept __is_int128 = __is_signed_int128<_Tp> || __is_unsigned_int128<_Tp>;
583
584 template<typename _Tp>
585 concept __is_integer_like = __integral_nonbool<_Tp>
586 || __is_int128<_Tp>
588
589 template<typename _Tp>
590 concept __is_signed_integer_like = signed_integral<_Tp>
591 || __is_signed_int128<_Tp>
593
594 } // namespace ranges::__detail
595
596 namespace __detail { using ranges::__detail::__is_signed_integer_like; }
597
598 /// Requirements on types that can be incremented with ++.
599 template<typename _Iter>
600 concept weakly_incrementable = movable<_Iter>
601 && requires(_Iter __i)
602 {
603 typename iter_difference_t<_Iter>;
604 requires __detail::__is_signed_integer_like<iter_difference_t<_Iter>>;
605 { ++__i } -> same_as<_Iter&>;
606 __i++;
607 };
608
609 template<typename _Iter>
610 concept incrementable = regular<_Iter> && weakly_incrementable<_Iter>
611 && requires(_Iter __i) { { __i++ } -> same_as<_Iter>; };
612
613 template<typename _Iter>
614 concept input_or_output_iterator
615 = requires(_Iter __i) { { *__i } -> __detail::__can_reference; }
616 && weakly_incrementable<_Iter>;
617
618 template<typename _Sent, typename _Iter>
619 concept sentinel_for = semiregular<_Sent>
620 && input_or_output_iterator<_Iter>
621 && __detail::__weakly_eq_cmp_with<_Sent, _Iter>;
622
623 template<typename _Sent, typename _Iter>
624 inline constexpr bool disable_sized_sentinel_for = false;
625
626 template<typename _Sent, typename _Iter>
627 concept sized_sentinel_for = sentinel_for<_Sent, _Iter>
628 && !disable_sized_sentinel_for<remove_cv_t<_Sent>, remove_cv_t<_Iter>>
629 && requires(const _Iter& __i, const _Sent& __s)
630 {
631 { __s - __i } -> same_as<iter_difference_t<_Iter>>;
632 { __i - __s } -> same_as<iter_difference_t<_Iter>>;
633 };
634
635 template<typename _Iter>
636 concept input_iterator = input_or_output_iterator<_Iter>
637 && indirectly_readable<_Iter>
638 && requires { typename __detail::__iter_concept<_Iter>; }
639 && derived_from<__detail::__iter_concept<_Iter>, input_iterator_tag>;
640
641 template<typename _Iter, typename _Tp>
642 concept output_iterator = input_or_output_iterator<_Iter>
643 && indirectly_writable<_Iter, _Tp>
644 && requires(_Iter __i, _Tp&& __t) { *__i++ = std::forward<_Tp>(__t); };
645
646 template<typename _Iter>
647 concept forward_iterator = input_iterator<_Iter>
648 && derived_from<__detail::__iter_concept<_Iter>, forward_iterator_tag>
649 && incrementable<_Iter> && sentinel_for<_Iter, _Iter>;
650
651 template<typename _Iter>
652 concept bidirectional_iterator = forward_iterator<_Iter>
653 && derived_from<__detail::__iter_concept<_Iter>,
654 bidirectional_iterator_tag>
655 && requires(_Iter __i)
656 {
657 { --__i } -> same_as<_Iter&>;
658 { __i-- } -> same_as<_Iter>;
659 };
660
661 template<typename _Iter>
662 concept random_access_iterator = bidirectional_iterator<_Iter>
663 && derived_from<__detail::__iter_concept<_Iter>,
664 random_access_iterator_tag>
665 && totally_ordered<_Iter> && sized_sentinel_for<_Iter, _Iter>
666 && requires(_Iter __i, const _Iter __j,
667 const iter_difference_t<_Iter> __n)
668 {
669 { __i += __n } -> same_as<_Iter&>;
670 { __j + __n } -> same_as<_Iter>;
671 { __n + __j } -> same_as<_Iter>;
672 { __i -= __n } -> same_as<_Iter&>;
673 { __j - __n } -> same_as<_Iter>;
674 { __j[__n] } -> same_as<iter_reference_t<_Iter>>;
675 };
676
677 template<typename _Iter>
678 concept contiguous_iterator = random_access_iterator<_Iter>
679 && derived_from<__detail::__iter_concept<_Iter>, contiguous_iterator_tag>
680 && is_lvalue_reference_v<iter_reference_t<_Iter>>
681 && same_as<iter_value_t<_Iter>, remove_cvref_t<iter_reference_t<_Iter>>>
682 && requires(const _Iter& __i)
683 {
684 { std::to_address(__i) }
685 -> same_as<add_pointer_t<iter_reference_t<_Iter>>>;
686 };
687
688 // [indirectcallable], indirect callable requirements
689
690 // [indirectcallable.indirectinvocable], indirect callables
691
692 template<typename _Fn, typename _Iter>
693 concept indirectly_unary_invocable = indirectly_readable<_Iter>
694 && copy_constructible<_Fn> && invocable<_Fn&, iter_value_t<_Iter>&>
695 && invocable<_Fn&, iter_reference_t<_Iter>>
696 && invocable<_Fn&, iter_common_reference_t<_Iter>>
697 && common_reference_with<invoke_result_t<_Fn&, iter_value_t<_Iter>&>,
698 invoke_result_t<_Fn&, iter_reference_t<_Iter>>>;
699
700 template<typename _Fn, typename _Iter>
701 concept indirectly_regular_unary_invocable = indirectly_readable<_Iter>
702 && copy_constructible<_Fn>
703 && regular_invocable<_Fn&, iter_value_t<_Iter>&>
704 && regular_invocable<_Fn&, iter_reference_t<_Iter>>
705 && regular_invocable<_Fn&, iter_common_reference_t<_Iter>>
706 && common_reference_with<invoke_result_t<_Fn&, iter_value_t<_Iter>&>,
707 invoke_result_t<_Fn&, iter_reference_t<_Iter>>>;
708
709 template<typename _Fn, typename _Iter>
710 concept indirect_unary_predicate = indirectly_readable<_Iter>
711 && copy_constructible<_Fn> && predicate<_Fn&, iter_value_t<_Iter>&>
712 && predicate<_Fn&, iter_reference_t<_Iter>>
713 && predicate<_Fn&, iter_common_reference_t<_Iter>>;
714
715 template<typename _Fn, typename _I1, typename _I2>
716 concept indirect_binary_predicate
717 = indirectly_readable<_I1> && indirectly_readable<_I2>
718 && copy_constructible<_Fn>
719 && predicate<_Fn&, iter_value_t<_I1>&, iter_value_t<_I2>&>
720 && predicate<_Fn&, iter_value_t<_I1>&, iter_reference_t<_I2>>
721 && predicate<_Fn&, iter_reference_t<_I1>, iter_value_t<_I2>&>
722 && predicate<_Fn&, iter_reference_t<_I1>, iter_reference_t<_I2>>
723 && predicate<_Fn&, iter_common_reference_t<_I1>,
724 iter_common_reference_t<_I2>>;
725
726 template<typename _Fn, typename _I1, typename _I2 = _I1>
727 concept indirect_equivalence_relation
728 = indirectly_readable<_I1> && indirectly_readable<_I2>
729 && copy_constructible<_Fn>
730 && equivalence_relation<_Fn&, iter_value_t<_I1>&, iter_value_t<_I2>&>
731 && equivalence_relation<_Fn&, iter_value_t<_I1>&, iter_reference_t<_I2>>
732 && equivalence_relation<_Fn&, iter_reference_t<_I1>, iter_value_t<_I2>&>
733 && equivalence_relation<_Fn&, iter_reference_t<_I1>,
734 iter_reference_t<_I2>>
735 && equivalence_relation<_Fn&, iter_common_reference_t<_I1>,
736 iter_common_reference_t<_I2>>;
737
738 template<typename _Fn, typename _I1, typename _I2 = _I1>
739 concept indirect_strict_weak_order
740 = indirectly_readable<_I1> && indirectly_readable<_I2>
741 && copy_constructible<_Fn>
742 && strict_weak_order<_Fn&, iter_value_t<_I1>&, iter_value_t<_I2>&>
743 && strict_weak_order<_Fn&, iter_value_t<_I1>&, iter_reference_t<_I2>>
744 && strict_weak_order<_Fn&, iter_reference_t<_I1>, iter_value_t<_I2>&>
745 && strict_weak_order<_Fn&, iter_reference_t<_I1>, iter_reference_t<_I2>>
746 && strict_weak_order<_Fn&, iter_common_reference_t<_I1>,
747 iter_common_reference_t<_I2>>;
748
749 template<typename _Fn, typename... _Is>
750 requires (indirectly_readable<_Is> && ...)
751 && invocable<_Fn, iter_reference_t<_Is>...>
752 using indirect_result_t = invoke_result_t<_Fn, iter_reference_t<_Is>...>;
753
754 /// [projected], projected
755 template<indirectly_readable _Iter,
756 indirectly_regular_unary_invocable<_Iter> _Proj>
757 struct projected
758 {
760
761 indirect_result_t<_Proj&, _Iter> operator*() const; // not defined
762 };
763
764 template<weakly_incrementable _Iter, typename _Proj>
765 struct incrementable_traits<projected<_Iter, _Proj>>
766 { using difference_type = iter_difference_t<_Iter>; };
767
768 // [alg.req], common algorithm requirements
769
770 /// [alg.req.ind.move], concept `indirectly_movable`
771
772 template<typename _In, typename _Out>
775
776 template<typename _In, typename _Out>
777 concept indirectly_movable_storable = indirectly_movable<_In, _Out>
779 && movable<iter_value_t<_In>>
780 && constructible_from<iter_value_t<_In>, iter_rvalue_reference_t<_In>>
781 && assignable_from<iter_value_t<_In>&, iter_rvalue_reference_t<_In>>;
782
783 /// [alg.req.ind.copy], concept `indirectly_copyable`
784 template<typename _In, typename _Out>
787
788 template<typename _In, typename _Out>
789 concept indirectly_copyable_storable = indirectly_copyable<_In, _Out>
794 && copyable<iter_value_t<_In>>
795 && constructible_from<iter_value_t<_In>, iter_reference_t<_In>>
796 && assignable_from<iter_value_t<_In>&, iter_reference_t<_In>>;
797
798namespace ranges
799{
800 namespace __cust_iswap
801 {
802 template<typename _It1, typename _It2>
803 void iter_swap(_It1, _It2) = delete;
804
805 template<typename _Tp, typename _Up>
806 concept __adl_iswap
807 = (std::__detail::__class_or_enum<remove_reference_t<_Tp>>
808 || std::__detail::__class_or_enum<remove_reference_t<_Up>>)
809 && requires(_Tp&& __t, _Up&& __u) {
810 iter_swap(static_cast<_Tp&&>(__t), static_cast<_Up&&>(__u));
811 };
812
813 template<typename _Xp, typename _Yp>
814 constexpr iter_value_t<_Xp>
815 __iter_exchange_move(_Xp&& __x, _Yp&& __y)
816 noexcept(noexcept(iter_value_t<_Xp>(iter_move(__x)))
817 && noexcept(*__x = iter_move(__y)))
818 {
819 iter_value_t<_Xp> __old_value(iter_move(__x));
820 *__x = iter_move(__y);
821 return __old_value;
822 }
823
824 struct _IterSwap
825 {
826 private:
827 template<typename _Tp, typename _Up>
828 static constexpr bool
829 _S_noexcept()
830 {
831 if constexpr (__adl_iswap<_Tp, _Up>)
832 return noexcept(iter_swap(std::declval<_Tp>(),
833 std::declval<_Up>()));
834 else if constexpr (indirectly_readable<_Tp>
836 && swappable_with<iter_reference_t<_Tp>, iter_reference_t<_Up>>)
837 return noexcept(ranges::swap(*std::declval<_Tp>(),
838 *std::declval<_Up>()));
839 else
840 return noexcept(*std::declval<_Tp>()
841 = __iter_exchange_move(std::declval<_Up>(),
842 std::declval<_Tp>()));
843 }
844
845 public:
846 template<typename _Tp, typename _Up>
847 requires __adl_iswap<_Tp, _Up>
850 && swappable_with<iter_reference_t<_Tp>, iter_reference_t<_Up>>)
851 || (indirectly_movable_storable<_Tp, _Up>
852 && indirectly_movable_storable<_Up, _Tp>)
853 constexpr void
854 operator()(_Tp&& __e1, _Up&& __e2) const
855 noexcept(_S_noexcept<_Tp, _Up>())
856 {
857 if constexpr (__adl_iswap<_Tp, _Up>)
858 iter_swap(static_cast<_Tp&&>(__e1), static_cast<_Up&&>(__e2));
859 else if constexpr (indirectly_readable<_Tp>
861 && swappable_with<iter_reference_t<_Tp>, iter_reference_t<_Up>>)
862 ranges::swap(*__e1, *__e2);
863 else
864 *__e1 = __iter_exchange_move(__e2, __e1);
865 }
866 };
867 } // namespace __cust_iswap
868
869 inline namespace __cust
870 {
871 inline constexpr __cust_iswap::_IterSwap iter_swap{};
872 } // inline namespace __cust
873
874} // namespace ranges
875
876 /// [alg.req.ind.swap], concept `indirectly_swappable`
877 template<typename _I1, typename _I2 = _I1>
880 && requires(const _I1 __i1, const _I2 __i2)
881 {
882 ranges::iter_swap(__i1, __i1);
883 ranges::iter_swap(__i2, __i2);
884 ranges::iter_swap(__i1, __i2);
885 ranges::iter_swap(__i2, __i1);
886 };
887
888 /// [alg.req.ind.cmp], concept `indirectly_comparable`
889 template<typename _I1, typename _I2, typename _Rel, typename _P1 = identity,
890 typename _P2 = identity>
892 = indirect_binary_predicate<_Rel, projected<_I1, _P1>,
893 projected<_I2, _P2>>;
894
895 /// [alg.req.permutable], concept `permutable`
896 template<typename _Iter>
897 concept permutable = forward_iterator<_Iter>
898 && indirectly_movable_storable<_Iter, _Iter>
900
901 /// [alg.req.mergeable], concept `mergeable`
902 template<typename _I1, typename _I2, typename _Out,
903 typename _Rel = ranges::less, typename _P1 = identity,
904 typename _P2 = identity>
905 concept mergeable = input_iterator<_I1> && input_iterator<_I2>
908 && indirect_strict_weak_order<_Rel, projected<_I1, _P1>,
909 projected<_I2, _P2>>;
910
911 /// [alg.req.sortable], concept `sortable`
912 template<typename _Iter, typename _Rel = ranges::less,
913 typename _Proj = identity>
915 && indirect_strict_weak_order<_Rel, projected<_Iter, _Proj>>;
916
917 struct unreachable_sentinel_t
918 {
919 template<weakly_incrementable _It>
920 friend constexpr bool
921 operator==(unreachable_sentinel_t, const _It&) noexcept
922 { return false; }
923 };
924
925 inline constexpr unreachable_sentinel_t unreachable_sentinel{};
926
927 struct default_sentinel_t { };
928 inline constexpr default_sentinel_t default_sentinel{};
929
930 // This is the namespace for [range.access] CPOs.
931 namespace ranges::__cust_access
932 {
933 using std::__detail::__class_or_enum;
934
935 struct _Decay_copy final
936 {
937 template<typename _Tp>
938 constexpr decay_t<_Tp>
939 operator()(_Tp&& __t) const
940 noexcept(is_nothrow_convertible_v<_Tp, decay_t<_Tp>>)
941 { return std::forward<_Tp>(__t); }
942 } inline constexpr __decay_copy{};
943
944 template<typename _Tp>
945 concept __member_begin = requires(_Tp& __t)
946 {
947 { __decay_copy(__t.begin()) } -> input_or_output_iterator;
948 };
949
950 // Poison pills so that unqualified lookup doesn't find std::begin.
951 void begin(auto&) = delete;
952 void begin(const auto&) = delete;
953
954 template<typename _Tp>
955 concept __adl_begin = __class_or_enum<remove_reference_t<_Tp>>
956 && requires(_Tp& __t)
957 {
958 { __decay_copy(begin(__t)) } -> input_or_output_iterator;
959 };
960
961 // Simplified version of std::ranges::begin that only supports lvalues,
962 // for use by __range_iter_t below.
963 template<typename _Tp>
964 requires is_array_v<_Tp> || __member_begin<_Tp&> || __adl_begin<_Tp&>
965 auto
966 __begin(_Tp& __t)
967 {
968 if constexpr (is_array_v<_Tp>)
969 return __t + 0;
970 else if constexpr (__member_begin<_Tp&>)
971 return __t.begin();
972 else
973 return begin(__t);
974 }
975 } // namespace ranges::__cust_access
976
977 namespace __detail
978 {
979 // Implementation of std::ranges::iterator_t, without using ranges::begin.
980 template<typename _Tp>
981 using __range_iter_t
982 = decltype(ranges::__cust_access::__begin(std::declval<_Tp&>()));
983
984 } // namespace __detail
985
986_GLIBCXX_END_NAMESPACE_VERSION
987} // namespace std
988#endif // C++20 library concepts
989#endif // _ITERATOR_CONCEPTS_H
constexpr _Tp * to_address(_Tp *__ptr) noexcept
Obtain address referenced by a pointer to an object.
Definition: ptr_traits.h:266
typename remove_cvref< _Tp >::type remove_cvref_t
Definition: type_traits:3357
_Tp * begin(valarray< _Tp > &__va) noexcept
Return an iterator pointing to the first element of the valarray.
Definition: valarray:1215
ISO C++ entities toplevel namespace is std.
[projected], projected
[func.identity] The identity function.
Definition: ranges_cmp.h:48
[concept.same], concept same_as
Definition: concepts:63
[concept.assignable], concept assignable_from
Definition: concepts:124
[concept.constructible], concept constructible_from
Definition: concepts:137
Requirements for types that are readable by applying operator*.
Requirements for writing a value into an iterator's referenced object.
Requirements on types that can be incremented with ++.
[alg.req.ind.move], concept indirectly_movable
[alg.req.ind.copy], concept indirectly_copyable
[alg.req.ind.swap], concept indirectly_swappable
[alg.req.ind.cmp], concept indirectly_comparable
[alg.req.permutable], concept permutable
[alg.req.mergeable], concept mergeable
[alg.req.sortable], concept sortable