14#ifndef RANGES_V3_ITERATOR_CONCEPTS_HPP
15#define RANGES_V3_ITERATOR_CONCEPTS_HPP
34#include <debug/safe_iterator.h>
37#include <range/v3/detail/prologue.hpp>
49 std::iterator_traits<I>, I>;
51#if defined(_GLIBCXX_DEBUG)
52 template(
typename I,
typename T,
typename Seq)(
53 requires same_as<I, __gnu_debug::_Safe_iterator<T *, Seq>>)
54 auto iter_concept_(__gnu_debug::_Safe_iterator<T *, Seq>, priority_tag<3>)
57#if defined(__GLIBCXX__)
58 template(
typename I,
typename T,
typename Seq)(
59 requires same_as<I, __gnu_cxx::__normal_iterator<T *, Seq>>)
60 auto iter_concept_(__gnu_cxx::__normal_iterator<T *, Seq>, priority_tag<3>)
63#if defined(_LIBCPP_VERSION)
64 template(
typename I,
typename T)(
65 requires same_as<I, std::__wrap_iter<T *>>)
66 auto iter_concept_(std::__wrap_iter<T *>, priority_tag<3>)
69#if defined(_MSVC_STL_VERSION) || defined(_IS_WRS)
71 requires same_as<I, class I::_Array_iterator>)
72 auto iter_concept_(I, priority_tag<3>)
75 requires same_as<I, class I::_Array_const_iterator>)
76 auto iter_concept_(I, priority_tag<3>)
79 requires same_as<I, class I::_Vector_iterator>)
80 auto iter_concept_(I, priority_tag<3>)
83 requires same_as<I, class I::_Vector_const_iterator>)
84 auto iter_concept_(I, priority_tag<3>)
87 requires same_as<I, class I::_String_iterator>)
88 auto iter_concept_(I, priority_tag<3>)
91 requires same_as<I, class I::_String_const_iterator>)
92 auto iter_concept_(I, priority_tag<3>)
95 requires same_as<I, class I::_String_view_iterator>)
96 auto iter_concept_(I, priority_tag<3>)
99 template(
typename I,
typename T)(
100 requires same_as<I, T *>)
101 auto iter_concept_(T *, priority_tag<3>)
104 auto iter_concept_(I, priority_tag<2>) ->
105 typename iter_traits_t<I>::iterator_concept;
107 auto iter_concept_(I, priority_tag<1>) ->
108 typename iter_traits_t<I>::iterator_category;
110 auto iter_concept_(I, priority_tag<0>)
111 -> enable_if_t<!is_std_iterator_traits_specialized_v<I>,
112 std::random_access_iterator_tag>;
115 using iter_concept_t =
116 decltype(iter_concept_<I>(std::declval<I>(), priority_tag<3>{}));
118 using ::concepts::detail::weakly_equality_comparable_with_;
121 using readable_types_t =
129 template(
typename I)(
130 concept (readable_)(I),
136 same_as<iter_reference_t<I const>, iter_reference_t<I>> AND
137 same_as<iter_rvalue_reference_t<I const>, iter_rvalue_reference_t<I>> AND
138 common_reference_with<iter_reference_t<I> &&, iter_value_t<I> &> AND
139 common_reference_with<iter_reference_t<I> &&,
140 iter_rvalue_reference_t<I> &&> AND
141 common_reference_with<iter_rvalue_reference_t<I> &&, iter_value_t<I>
const &>
147 CPP_concept indirectly_readable =
151 RANGES_DEPRECATED(
"Please use ranges::indirectly_readable instead")
152 RANGES_INLINE_VAR constexpr
bool readable =
153 indirectly_readable<I>;
157 template<typename O, typename T>
158 CPP_requires(writable_,
159 requires(O && o, T && t)
162 *(O &&) o = (T &&) t,
163 const_cast<iter_reference_t<O> const &&>(*o) = (T &&) t,
164 const_cast<iter_reference_t<O> const &&>(*(O &&) o) = (T &&) t
168 template<typename O, typename T>
169 CPP_concept indirectly_writable =
170 CPP_requires_ref(ranges::writable_, O, T);
172 template<typename O, typename T>
173 RANGES_DEPRECATED("Please use ranges::indirectly_writable instead")
174 RANGES_INLINE_VAR constexpr
bool writable =
175 indirectly_writable<O, T>;
181#if RANGES_CXX_INLINE_VARIABLES >= RANGES_CXX_INLINE_VARIABLES_17
183 inline constexpr bool _is_integer_like_ = std::is_integral<D>::value;
185 template<
typename D,
typename =
void>
186 constexpr bool _is_integer_like_ = std::is_integral<D>::value;
192 __extension__
typedef __int128 int128_t;
193#if RANGES_CXX_INLINE_VARIABLES >= RANGES_CXX_INLINE_VARIABLES_17
195 inline constexpr bool _is_integer_like_<int128_t> =
true;
197 template<
typename Enable>
198 constexpr bool _is_integer_like_<int128_t, Enable> =
true;
206 CPP_concept integer_like_ = _is_integer_like_<D>;
209#ifdef RANGES_WORKAROUND_MSVC_792338
210 template<
typename D,
bool Signed = (D(-1) < D(0))>
211 constexpr bool _is_signed_(D *)
215 constexpr bool _is_signed_(
void *)
223 CPP_concept signed_integer_like_ =
224 integer_like_<D> && detail::_is_signed_((D*)
nullptr);
228 template(typename D)(
229 concept (signed_integer_like_impl_)(D),
231 concepts::type<std::integral_constant<bool, (D(-1) < D(0))>> AND
232 std::integral_constant<
bool, (D(-1) < D(0))>::value
238 CPP_concept signed_integer_like_ =
240 CPP_concept_ref(detail::signed_integer_like_impl_, D);
250 CPP_requires(weakly_incrementable_,
255 concepts::requires_<same_as<I&,
decltype(++i)>>
260 template(
typename I)(
261 concept (weakly_incrementable_)(I),
262 concepts::type<iter_difference_t<I>> AND
263 detail::signed_integer_like_<iter_difference_t<I>>);
268 CPP_concept weakly_incrementable =
276 CPP_requires(incrementable_,
279 concepts::requires_<same_as<I,
decltype(i++)>>
284 CPP_concept incrementable =
286 weakly_incrementable<I> &&
291 template(
typename I)(
292 concept (input_or_output_iterator_)(I),
293 detail::dereferenceable_<I&>
299 CPP_concept input_or_output_iterator =
300 weakly_incrementable<I> &&
305 template<
typename S,
typename I>
306 CPP_concept sentinel_for =
308 input_or_output_iterator<I> &&
309 detail::weakly_equality_comparable_with_<S, I>;
313 template<
typename S,
typename I>
314 CPP_requires(sized_sentinel_for_,
315 requires(S
const & s, I
const & i)
319 concepts::requires_<same_as<iter_difference_t<I>,
decltype(s - i)>>,
320 concepts::requires_<same_as<iter_difference_t<I>,
decltype(i - s)>>
324 template(
typename S,
typename I)(
325 concept (sized_sentinel_for_)(S, I),
326 (!disable_sized_sentinel<std::remove_cv_t<S>, std::remove_cv_t<I>>) AND
331 template<
typename S,
typename I>
332 CPP_concept sized_sentinel_for =
333 CPP_concept_ref(sized_sentinel_for_, S, I) &&
338 template<
typename Out,
typename T>
339 CPP_requires(output_iterator_,
340 requires(Out o, T && t)
346 template<
typename Out,
typename T>
347 CPP_concept output_iterator =
348 input_or_output_iterator<Out> &&
349 indirectly_writable<Out, T> &&
354 template(
typename I,
typename Tag)(
355 concept (with_category_)(I, Tag),
356 derived_from<detail::iter_concept_t<I>, Tag>
362 CPP_concept input_iterator =
363 input_or_output_iterator<I> &&
364 indirectly_readable<I> &&
370 CPP_concept forward_iterator =
373 sentinel_for<I, I> &&
379 CPP_requires(bidirectional_iterator_,
384 concepts::requires_<same_as<I&,
decltype(--i)>>,
385 concepts::requires_<same_as<I,
decltype(i--)>>
390 CPP_concept bidirectional_iterator =
391 forward_iterator<I> &&
398 CPP_requires(random_access_iterator_,
399 requires(I i, iter_difference_t<I> n)
406 concepts::requires_<same_as<
decltype(i + n), I>>,
407 concepts::requires_<same_as<
decltype(n + i), I>>,
408 concepts::requires_<same_as<
decltype(i - n), I>>,
409 concepts::requires_<same_as<
decltype(i += n), I&>>,
410 concepts::requires_<same_as<
decltype(i -= n), I&>>,
411 concepts::requires_<same_as<
decltype(i[n]), iter_reference_t<I>>>
416 CPP_concept random_access_iterator =
417 bidirectional_iterator<I> &&
418 totally_ordered<I> &&
419 sized_sentinel_for<I, I> &&
425 template(
typename I)(
426 concept (contiguous_iterator_)(I),
427 std::is_lvalue_reference<iter_reference_t<I>>::value AND
428 same_as<iter_value_t<I>, uncvref_t<iter_reference_t<I>>> AND
435 CPP_concept contiguous_iterator =
436 random_access_iterator<I> &&
442 template<
typename Rng>
443 using iterator_tag_of =
447 contiguous_iterator<Rng>,
450 random_access_iterator<Rng>,
451 std::random_access_iterator_tag,
453 bidirectional_iterator<Rng>,
454 std::bidirectional_iterator_tag,
456 forward_iterator<Rng>,
457 std::forward_iterator_tag,
458 std::input_iterator_tag>>>>>;
463 template<
typename,
bool>
464 struct iterator_category_
468 struct iterator_category_<I, true>
470 using type = iterator_tag_of<I>;
473 template<
typename T,
typename U = meta::_t<std::remove_const<T>>>
474 using iterator_category = iterator_category_<U, (bool)input_iterator<U>>;
484 CPP_concept single_pass_iterator_ =
485 input_or_output_iterator<I> && !forward_iterator<I>;
491 template<
typename Fun,
typename... Is>
492 using indirect_result_t =
493 detail::enable_if_t<(bool)and_v<(
bool)indirectly_readable<Is>...>,
494 invoke_result_t<Fun, iter_reference_t<Is>...>>;
502 template(
typename T1,
typename T2,
typename T3,
typename T4)(
503 concept (common_reference_with_4_impl_)(T1, T2, T3, T4),
504 concepts::type<common_reference_t<T1, T2, T3, T4>> AND
505 convertible_to<T1, common_reference_t<T1, T2, T3, T4>> AND
506 convertible_to<T2, common_reference_t<T1, T2, T3, T4>> AND
507 convertible_to<T3, common_reference_t<T1, T2, T3, T4>> AND
508 convertible_to<T4, common_reference_t<T1, T2, T3, T4>>
513 template<
typename T1,
typename T2,
typename T3,
typename T4>
514 CPP_concept common_reference_with_4_ =
515 CPP_concept_ref(detail::common_reference_with_4_impl_, T1, T2, T3, T4);
521 template(
typename F,
typename I)(
522 concept (indirectly_unary_invocable_impl_)(F, I),
523 invocable<F &, iter_value_t<I> &> AND
524 invocable<F &, iter_reference_t<I>> AND
525 invocable<F &, iter_common_reference_t<I>> AND
526 common_reference_with<
527 invoke_result_t<F &, iter_value_t<I> &>,
528 invoke_result_t<F &, iter_reference_t<I>>>
533 template<
typename F,
typename I>
534 CPP_concept indirectly_unary_invocable_ =
535 indirectly_readable<I> &&
536 CPP_concept_ref(detail::indirectly_unary_invocable_impl_, F, I);
544 template<
typename F,
typename I>
545 CPP_concept indirectly_unary_invocable =
546 detail::indirectly_unary_invocable_<F, I> &&
547 copy_constructible<F>;
551 template(
typename F,
typename I)(
552 concept (indirectly_regular_unary_invocable_)(F, I),
553 regular_invocable<F &, iter_value_t<I> &> AND
554 regular_invocable<F &, iter_reference_t<I>> AND
555 regular_invocable<F &, iter_common_reference_t<I>> AND
556 common_reference_with<
557 invoke_result_t<F &, iter_value_t<I> &>,
558 invoke_result_t<F &, iter_reference_t<I>>>
563 template<
typename F,
typename I>
564 CPP_concept indirectly_regular_unary_invocable =
565 indirectly_readable<I> &&
566 copy_constructible<F> &&
573 template(
typename F,
typename I1,
typename I2)(
574 concept (indirectly_binary_invocable_impl_)(F, I1, I2),
575 invocable<F &, iter_value_t<I1> &, iter_value_t<I2> &> AND
576 invocable<F &, iter_value_t<I1> &, iter_reference_t<I2>> AND
577 invocable<F &, iter_reference_t<I1>, iter_value_t<I2> &> AND
578 invocable<F &, iter_reference_t<I1>, iter_reference_t<I2>> AND
579 invocable<F &, iter_common_reference_t<I1>, iter_common_reference_t<I2>> AND
580 detail::common_reference_with_4_<
581 invoke_result_t<F &, iter_value_t<I1> &, iter_value_t<I2> &>,
582 invoke_result_t<F &, iter_value_t<I1> &, iter_reference_t<I2>>,
583 invoke_result_t<F &, iter_reference_t<I1>, iter_value_t<I2> &>,
584 invoke_result_t<F &, iter_reference_t<I1>, iter_reference_t<I2>>>
589 template<
typename F,
typename I1,
typename I2>
590 CPP_concept indirectly_binary_invocable_ =
591 indirectly_readable<I1> && indirectly_readable<I2> &&
592 copy_constructible<F> &&
593 CPP_concept_ref(ranges::indirectly_binary_invocable_impl_, F, I1, I2);
597 template(
typename F,
typename I1,
typename I2)(
598 concept (indirectly_regular_binary_invocable_impl_)(F, I1, I2),
599 regular_invocable<F &, iter_value_t<I1> &, iter_value_t<I2> &> AND
600 regular_invocable<F &, iter_value_t<I1> &, iter_reference_t<I2>> AND
601 regular_invocable<F &, iter_reference_t<I1>, iter_value_t<I2> &> AND
602 regular_invocable<F &, iter_reference_t<I1>, iter_reference_t<I2>> AND
603 regular_invocable<F &, iter_common_reference_t<I1>, iter_common_reference_t<I2>> AND
604 detail::common_reference_with_4_<
605 invoke_result_t<F &, iter_value_t<I1> &, iter_value_t<I2> &>,
606 invoke_result_t<F &, iter_value_t<I1> &, iter_reference_t<I2>>,
607 invoke_result_t<F &, iter_reference_t<I1>, iter_value_t<I2> &>,
608 invoke_result_t<F &, iter_reference_t<I1>, iter_reference_t<I2>>>
613 template<
typename F,
typename I1,
typename I2>
614 CPP_concept indirectly_regular_binary_invocable_ =
615 indirectly_readable<I1> && indirectly_readable<I2> &&
616 copy_constructible<F> &&
617 CPP_concept_ref(ranges::indirectly_regular_binary_invocable_impl_, F, I1, I2);
622 template(
typename F,
typename I)(
623 concept (indirect_unary_predicate_)(F, I),
624 predicate<F &, iter_value_t<I> &> AND
625 predicate<F &, iter_reference_t<I>> AND
626 predicate<F &, iter_common_reference_t<I>>
631 template<
typename F,
typename I>
632 CPP_concept indirect_unary_predicate =
633 indirectly_readable<I> &&
634 copy_constructible<F> &&
639 template(
typename F,
typename I1,
typename I2)(
640 concept (indirect_binary_predicate_impl_)(F, I1, I2),
641 predicate<F &, iter_value_t<I1> &, iter_value_t<I2> &> AND
642 predicate<F &, iter_value_t<I1> &, iter_reference_t<I2>> AND
643 predicate<F &, iter_reference_t<I1>, iter_value_t<I2> &> AND
644 predicate<F &, iter_reference_t<I1>, iter_reference_t<I2>> AND
645 predicate<F &, iter_common_reference_t<I1>, iter_common_reference_t<I2>>
650 template<
typename F,
typename I1,
typename I2>
651 CPP_concept indirect_binary_predicate_ =
652 indirectly_readable<I1> && indirectly_readable<I2> &&
653 copy_constructible<F> &&
658 template(
typename F,
typename I1,
typename I2)(
659 concept (indirect_relation_)(F, I1, I2),
660 relation<F &, iter_value_t<I1> &, iter_value_t<I2> &> AND
661 relation<F &, iter_value_t<I1> &, iter_reference_t<I2>> AND
662 relation<F &, iter_reference_t<I1>, iter_value_t<I2> &> AND
663 relation<F &, iter_reference_t<I1>, iter_reference_t<I2>> AND
664 relation<F &, iter_common_reference_t<I1>, iter_common_reference_t<I2>>
669 template<
typename F,
typename I1,
typename I2 = I1>
670 CPP_concept indirect_relation =
671 indirectly_readable<I1> && indirectly_readable<I2> &&
672 copy_constructible<F> &&
677 template(
typename F,
typename I1,
typename I2)(
678 concept (indirect_strict_weak_order_)(F, I1, I2),
679 strict_weak_order<F &, iter_value_t<I1> &, iter_value_t<I2> &> AND
680 strict_weak_order<F &, iter_value_t<I1> &, iter_reference_t<I2>> AND
681 strict_weak_order<F &, iter_reference_t<I1>, iter_value_t<I2> &> AND
682 strict_weak_order<F &, iter_reference_t<I1>, iter_reference_t<I2>> AND
683 strict_weak_order<F &, iter_common_reference_t<I1>, iter_common_reference_t<I2>>
688 template<
typename F,
typename I1,
typename I2 = I1>
689 CPP_concept indirect_strict_weak_order =
690 indirectly_readable<I1> && indirectly_readable<I2> &&
691 copy_constructible<F> &&
700 RANGES_DIAGNOSTIC_PUSH
701 RANGES_DIAGNOSTIC_IGNORE_UNDEFINED_INTERNAL
702 template<
typename I,
typename Proj>
707 using reference = indirect_result_t<Proj &, I>;
708 using value_type = uncvref_t<reference>;
712 RANGES_DIAGNOSTIC_POP
714 template<
typename Proj>
715 struct select_projected_
721 (bool)indirectly_regular_unary_invocable<Proj, I>,
722 detail::projected_<I, Proj>>>;
726 struct select_projected_<identity>
729 using apply = detail::enable_if_t<(bool)indirectly_readable<I>, I>;
734 template<
typename I,
typename Proj>
735 using projected =
typename detail::select_projected_<Proj>::template apply<I>;
737 template<
typename I,
typename Proj>
744 template(
typename I,
typename O)(
751 template<
typename I,
typename O>
757 template(
typename I,
typename O)(
760 movable<iter_value_t<I>> AND
761 constructible_from<iter_value_t<I>, iter_rvalue_reference_t<I>> AND
762 assignable_from<iter_value_t<I> &, iter_rvalue_reference_t<I>>
767 template<
typename I,
typename O>
774 template(
typename I,
typename O)(
781 template<
typename I,
typename O>
787 template(
typename I,
typename O)(
790 copyable<iter_value_t<I>> AND
791 constructible_from<iter_value_t<I>, iter_reference_t<I>> AND
792 assignable_from<iter_value_t<I> &, iter_reference_t<I>>
797 template<
typename I,
typename O>
804 template<
typename I1,
typename I2>
806 requires(I1
const i1, I2
const i2)
808 ranges::iter_swap(i1, i2),
809 ranges::iter_swap(i1, i1),
810 ranges::iter_swap(i2, i2),
811 ranges::iter_swap(i2, i1)
815 template<
typename I1,
typename I2 = I1>
823 template(
typename C,
typename I1,
typename P1,
typename I2,
typename P2)(
830 template<
typename I1,
typename I2,
typename C,
typename P1 =
identity,
847 template(
typename C,
typename I1,
typename P1,
typename I2,
typename P2)(
852 template<
typename I1,
typename I2,
typename Out,
typename C =
less,
854 CPP_concept mergeable =
864 template<
typename I,
typename C = less,
typename P =
identity>
875 template<
typename S,
typename I>
876 using sentinel_tag_of =
887 using iterator_category RANGES_DEPRECATED(
888 "iterator_category is deprecated. Use the iterator concepts instead") =
889 detail::iterator_category<I>;
892 using iterator_category_t RANGES_DEPRECATED(
893 "iterator_category_t is deprecated. Use the iterator concepts instead") =
896 template<
typename Fun,
typename... Is>
897 using indirect_invoke_result_t RANGES_DEPRECATED(
898 "Please switch to indirect_result_t") = indirect_result_t<Fun, Is...>;
900 template<
typename Fun,
typename... Is>
901 struct RANGES_DEPRECATED(
"Please switch to indirect_result_t") indirect_invoke_result
905 template<
typename Sig>
906 struct indirect_result_of
909 template<
typename Fun,
typename... Is>
910 struct RANGES_DEPRECATED(
"Please switch to indirect_result_t")
911 indirect_result_of<Fun(Is...)> :
meta::defer<indirect_result_t, Fun, Is...>
914 template<
typename Sig>
915 using indirect_result_of_t RANGES_DEPRECATED(
"Please switch to indirect_result_t") =
926 using ranges::indirect_result_t;
941 using ranges::mergeable;
944 using ranges::projected;
960 template(
typename I1,
typename I2,
typename Seq)(
961 requires (!::ranges::sized_sentinel_for<I1, I2>))
962 void operator-(_Safe_iterator<I1, Seq>
const &, _Safe_iterator<I2, Seq>
const &) =
965 template(
typename I1,
typename Seq)(
966 requires (!::ranges::sized_sentinel_for<I1, I1>))
967 void operator-(_Safe_iterator<I1, Seq>
const &, _Safe_iterator<I1, Seq>
const &) =
972#if defined(__GLIBCXX__) || (defined(_LIBCPP_VERSION) && _LIBCPP_VERSION <= 3900)
980 template<
typename S,
typename I>
982 disable_sized_sentinel<std::reverse_iterator<S>, std::reverse_iterator<I>> =
983 !
static_cast<bool>(sized_sentinel_for<I, S>);
988#include <range/v3/detail/epilogue.hpp>
The bidirectional_iterator_ concept.
The bidirectional_iterator concept.
The contiguous_iterator_ concept.
The contiguous_iterator concept.
The forward_iterator concept.
The incrementable_ concept.
The incrementable concept.
The indirect_binary_predicate_impl_ concept.
The indirect_relation_ concept.
The indirect_relation concept.
The indirect_strict_weak_order_ concept.
The indirect_strict_weak_order concept.
The indirect_unary_predicate_ concept.
The indirect_unary_predicate concept.
The indirectly_comparable concept.
The indirectly_copyable_ concept.
The indirectly_copyable_storable_ concept.
The indirectly_copyable_storable concept.
The indirectly_copyable concept.
The indirectly_movable_ concept.
The indirectly_movable_storable_ concept.
The indirectly_movable_storable concept.
The indirectly_movable concept.
The indirectly_readable concept.
The indirectly_regular_unary_invocable_ concept.
The indirectly_regular_unary_invocable concept.
The indirectly_swappable_ concept.
The indirectly_swappable concept.
The indirectly_unary_invocable concept.
The indirectly_writable concept.
The output_iterator_ concept.
The output_iterator concept.
The projected_indirect_relation_ concept.
The projected_indirect_strict_weak_order_ concept.
The random_access_iterator_ concept.
The random_access_iterator concept.
The sentinel_for concept.
The sized_sentinel_for_ concept.
The sized_sentinel_for concept.
The weakly_incrementable_ concept.
The weakly_incrementable concept.
The with_category_ concept.
typename T::type _t
Type alias for T::type.
Definition meta.hpp:141
_t< extension::apply< Fn, L > > apply
Applies the invocable Fn using the types in the type list L as arguments.
Definition meta.hpp:1030
typename detail::_cond< If >::template invoke< Then, Else > conditional_t
Select one type or another depending on a compile-time Boolean.
Definition meta.hpp:1148
Point operator*(double s, const Point &a)
Multiply point by scalar.
Definition shapes.h:250
Definition identity.hpp:25
Definition associated_types.hpp:166
Definition comparisons.hpp:50
Definition concepts.hpp:871
Definition concepts.hpp:873