File indexing completed on 2025-12-15 10:26:41
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef RANGES_V3_ITERATOR_CONCEPTS_HPP
0015 #define RANGES_V3_ITERATOR_CONCEPTS_HPP
0016
0017 #include <iterator>
0018 #include <type_traits>
0019
0020 #include <meta/meta.hpp>
0021
0022 #include <concepts/concepts.hpp>
0023
0024 #include <range/v3/range_fwd.hpp>
0025
0026 #include <range/v3/functional/comparisons.hpp>
0027 #include <range/v3/functional/concepts.hpp>
0028 #include <range/v3/functional/identity.hpp>
0029 #include <range/v3/functional/invoke.hpp>
0030 #include <range/v3/iterator/access.hpp>
0031 #include <range/v3/iterator/traits.hpp>
0032
0033 #ifdef _GLIBCXX_DEBUG
0034 #include <debug/safe_iterator.h>
0035 #endif
0036
0037 #include <range/v3/detail/prologue.hpp>
0038
0039 namespace ranges
0040 {
0041
0042
0043
0044
0045 namespace detail
0046 {
0047 template<typename I>
0048 using iter_traits_t = meta::conditional_t<is_std_iterator_traits_specialized_v<I>,
0049 std::iterator_traits<I>, I>;
0050
0051 #if defined(_GLIBCXX_DEBUG)
0052 template(typename I, typename T, typename Seq)(
0053 requires same_as<I, __gnu_debug::_Safe_iterator<T *, Seq>>)
0054 auto iter_concept_(__gnu_debug::_Safe_iterator<T *, Seq>, priority_tag<3>)
0055 -> ranges::contiguous_iterator_tag;
0056 #endif
0057 #if defined(__GLIBCXX__)
0058 template(typename I, typename T, typename Seq)(
0059 requires same_as<I, __gnu_cxx::__normal_iterator<T *, Seq>>)
0060 auto iter_concept_(__gnu_cxx::__normal_iterator<T *, Seq>, priority_tag<3>)
0061 -> ranges::contiguous_iterator_tag;
0062 #endif
0063 #if defined(_LIBCPP_VERSION)
0064 template(typename I, typename T)(
0065 requires same_as<I, std::__wrap_iter<T *>>)
0066 auto iter_concept_(std::__wrap_iter<T *>, priority_tag<3>)
0067 -> ranges::contiguous_iterator_tag;
0068 #endif
0069 #if defined(_MSVC_STL_VERSION) || defined(_IS_WRS)
0070 template(typename I)(
0071 requires same_as<I, class I::_Array_iterator>)
0072 auto iter_concept_(I, priority_tag<3>)
0073 -> ranges::contiguous_iterator_tag;
0074 template(typename I)(
0075 requires same_as<I, class I::_Array_const_iterator>)
0076 auto iter_concept_(I, priority_tag<3>)
0077 -> ranges::contiguous_iterator_tag;
0078 template(typename I)(
0079 requires same_as<I, class I::_Vector_iterator>)
0080 auto iter_concept_(I, priority_tag<3>)
0081 -> ranges::contiguous_iterator_tag;
0082 template(typename I)(
0083 requires same_as<I, class I::_Vector_const_iterator>)
0084 auto iter_concept_(I, priority_tag<3>)
0085 -> ranges::contiguous_iterator_tag;
0086 template(typename I)(
0087 requires same_as<I, class I::_String_iterator>)
0088 auto iter_concept_(I, priority_tag<3>)
0089 -> ranges::contiguous_iterator_tag;
0090 template(typename I)(
0091 requires same_as<I, class I::_String_const_iterator>)
0092 auto iter_concept_(I, priority_tag<3>)
0093 -> ranges::contiguous_iterator_tag;
0094 template(typename I)(
0095 requires same_as<I, class I::_String_view_iterator>)
0096 auto iter_concept_(I, priority_tag<3>)
0097 -> ranges::contiguous_iterator_tag;
0098 #endif
0099 template(typename I, typename T)(
0100 requires same_as<I, T *>)
0101 auto iter_concept_(T *, priority_tag<3>)
0102 -> ranges::contiguous_iterator_tag;
0103 template<typename I>
0104 auto iter_concept_(I, priority_tag<2>) ->
0105 typename iter_traits_t<I>::iterator_concept;
0106 template<typename I>
0107 auto iter_concept_(I, priority_tag<1>) ->
0108 typename iter_traits_t<I>::iterator_category;
0109 template<typename I>
0110 auto iter_concept_(I, priority_tag<0>)
0111 -> enable_if_t<!is_std_iterator_traits_specialized_v<I>,
0112 std::random_access_iterator_tag>;
0113
0114 template<typename I>
0115 using iter_concept_t =
0116 decltype(iter_concept_<I>(std::declval<I>(), priority_tag<3>{}));
0117
0118 using ::concepts::detail::weakly_equality_comparable_with_;
0119
0120 template<typename I>
0121 using readable_types_t =
0122 meta::list<iter_value_t<I>, iter_reference_t<I>, iter_rvalue_reference_t<I>>;
0123 }
0124
0125
0126
0127
0128
0129 template(typename I)(
0130 concept (readable_)(I),
0131
0132
0133
0134
0135
0136 same_as<iter_reference_t<I const>, iter_reference_t<I>> AND
0137 same_as<iter_rvalue_reference_t<I const>, iter_rvalue_reference_t<I>> AND
0138 common_reference_with<iter_reference_t<I> &&, iter_value_t<I> &> AND
0139 common_reference_with<iter_reference_t<I> &&,
0140 iter_rvalue_reference_t<I> &&> AND
0141 common_reference_with<iter_rvalue_reference_t<I> &&, iter_value_t<I> const &>
0142 );
0143
0144
0145
0146 template<typename I>
0147 CPP_concept indirectly_readable =
0148 CPP_concept_ref(ranges::readable_, uncvref_t<I>);
0149
0150 template<typename I>
0151 RANGES_DEPRECATED("Please use ranges::indirectly_readable instead")
0152 RANGES_INLINE_VAR constexpr bool readable =
0153 indirectly_readable<I>;
0154
0155
0156
0157 template<typename O, typename T>
0158 CPP_requires(writable_,
0159 requires(O && o, T && t)
0160 (
0161 *o = (T &&) t,
0162 *(O &&) o = (T &&) t,
0163 const_cast<iter_reference_t<O> const &&>(*o) = (T &&) t,
0164 const_cast<iter_reference_t<O> const &&>(*(O &&) o) = (T &&) t
0165 ));
0166
0167
0168 template<typename O, typename T>
0169 CPP_concept indirectly_writable =
0170 CPP_requires_ref(ranges::writable_, O, T);
0171
0172 template<typename O, typename T>
0173 RANGES_DEPRECATED("Please use ranges::indirectly_writable instead")
0174 RANGES_INLINE_VAR constexpr bool writable =
0175 indirectly_writable<O, T>;
0176
0177
0178
0179 namespace detail
0180 {
0181 #if RANGES_CXX_INLINE_VARIABLES >= RANGES_CXX_INLINE_VARIABLES_17
0182 template<typename D>
0183 inline constexpr bool _is_integer_like_ = std::is_integral<D>::value;
0184 #else
0185 template<typename D, typename = void>
0186 constexpr bool _is_integer_like_ = std::is_integral<D>::value;
0187 #endif
0188
0189
0190
0191 #if __SIZEOF_INT128__
0192 __extension__ typedef __int128 int128_t;
0193 #if RANGES_CXX_INLINE_VARIABLES >= RANGES_CXX_INLINE_VARIABLES_17
0194 template<>
0195 inline constexpr bool _is_integer_like_<int128_t> = true;
0196 #else
0197 template<typename Enable>
0198 constexpr bool _is_integer_like_<int128_t, Enable> = true;
0199 #endif
0200 #endif
0201
0202
0203
0204
0205 template<typename D>
0206 CPP_concept integer_like_ = _is_integer_like_<D>;
0207
0208
0209 #ifdef RANGES_WORKAROUND_MSVC_792338
0210 template<typename D, bool Signed = (D(-1) < D(0))>
0211 constexpr bool _is_signed_(D *)
0212 {
0213 return Signed;
0214 }
0215 constexpr bool _is_signed_(void *)
0216 {
0217 return false;
0218 }
0219
0220
0221
0222 template<typename D>
0223 CPP_concept signed_integer_like_ =
0224 integer_like_<D> && detail::_is_signed_((D*) nullptr);
0225 #else
0226
0227
0228 template(typename D)(
0229 concept (signed_integer_like_impl_)(D),
0230 integer_like_<D> AND
0231 concepts::type<std::integral_constant<bool, (D(-1) < D(0))>> AND
0232 std::integral_constant<bool, (D(-1) < D(0))>::value
0233 );
0234
0235
0236
0237 template<typename D>
0238 CPP_concept signed_integer_like_ =
0239 integer_like_<D> &&
0240 CPP_concept_ref(detail::signed_integer_like_impl_, D);
0241 #endif
0242
0243 }
0244
0245
0246
0247
0248
0249 template<typename I>
0250 CPP_requires(weakly_incrementable_,
0251 requires(I i)
0252 (
0253 ++i,
0254 i++,
0255 concepts::requires_<same_as<I&, decltype(++i)>>
0256 ));
0257
0258
0259
0260 template(typename I)(
0261 concept (weakly_incrementable_)(I),
0262 concepts::type<iter_difference_t<I>> AND
0263 detail::signed_integer_like_<iter_difference_t<I>>);
0264
0265
0266
0267 template<typename I>
0268 CPP_concept weakly_incrementable =
0269 copyable<I> &&
0270 CPP_requires_ref(ranges::weakly_incrementable_, I) &&
0271 CPP_concept_ref(ranges::weakly_incrementable_, I);
0272
0273
0274
0275 template<typename I>
0276 CPP_requires(incrementable_,
0277 requires(I i)
0278 (
0279 concepts::requires_<same_as<I, decltype(i++)>>
0280 ));
0281
0282
0283 template<typename I>
0284 CPP_concept incrementable =
0285 regular<I> &&
0286 weakly_incrementable<I> &&
0287 CPP_requires_ref(ranges::incrementable_, I);
0288
0289
0290
0291 template(typename I)(
0292 concept (input_or_output_iterator_)(I),
0293 detail::dereferenceable_<I&>
0294 );
0295
0296
0297
0298 template<typename I>
0299 CPP_concept input_or_output_iterator =
0300 weakly_incrementable<I> &&
0301 CPP_concept_ref(ranges::input_or_output_iterator_, I);
0302
0303
0304
0305 template<typename S, typename I>
0306 CPP_concept sentinel_for =
0307 semiregular<S> &&
0308 input_or_output_iterator<I> &&
0309 detail::weakly_equality_comparable_with_<S, I>;
0310
0311
0312
0313 template<typename S, typename I>
0314 CPP_requires(sized_sentinel_for_,
0315 requires(S const & s, I const & i)
0316 (
0317 s - i,
0318 i - s,
0319 concepts::requires_<same_as<iter_difference_t<I>, decltype(s - i)>>,
0320 concepts::requires_<same_as<iter_difference_t<I>, decltype(i - s)>>
0321 ));
0322
0323
0324 template(typename S, typename I)(
0325 concept (sized_sentinel_for_)(S, I),
0326 (!disable_sized_sentinel<std::remove_cv_t<S>, std::remove_cv_t<I>>) AND
0327 sentinel_for<S, I>);
0328
0329
0330
0331 template<typename S, typename I>
0332 CPP_concept sized_sentinel_for =
0333 CPP_concept_ref(sized_sentinel_for_, S, I) &&
0334 CPP_requires_ref(ranges::sized_sentinel_for_, S, I);
0335
0336
0337
0338 template<typename Out, typename T>
0339 CPP_requires(output_iterator_,
0340 requires(Out o, T && t)
0341 (
0342 *o++ = (T &&) t
0343 ));
0344
0345
0346 template<typename Out, typename T>
0347 CPP_concept output_iterator =
0348 input_or_output_iterator<Out> &&
0349 indirectly_writable<Out, T> &&
0350 CPP_requires_ref(ranges::output_iterator_, Out, T);
0351
0352
0353
0354 template(typename I, typename Tag)(
0355 concept (with_category_)(I, Tag),
0356 derived_from<detail::iter_concept_t<I>, Tag>
0357 );
0358
0359
0360
0361 template<typename I>
0362 CPP_concept input_iterator =
0363 input_or_output_iterator<I> &&
0364 indirectly_readable<I> &&
0365 CPP_concept_ref(ranges::with_category_, I, std::input_iterator_tag);
0366
0367
0368
0369 template<typename I>
0370 CPP_concept forward_iterator =
0371 input_iterator<I> &&
0372 incrementable<I> &&
0373 sentinel_for<I, I> &&
0374 CPP_concept_ref(ranges::with_category_, I, std::forward_iterator_tag);
0375
0376
0377
0378 template<typename I>
0379 CPP_requires(bidirectional_iterator_,
0380 requires(I i)
0381 (
0382 --i,
0383 i--,
0384 concepts::requires_<same_as<I&, decltype(--i)>>,
0385 concepts::requires_<same_as<I, decltype(i--)>>
0386 ));
0387
0388
0389 template<typename I>
0390 CPP_concept bidirectional_iterator =
0391 forward_iterator<I> &&
0392 CPP_requires_ref(ranges::bidirectional_iterator_, I) &&
0393 CPP_concept_ref(ranges::with_category_, I, std::bidirectional_iterator_tag);
0394
0395
0396
0397 template<typename I>
0398 CPP_requires(random_access_iterator_,
0399 requires(I i, iter_difference_t<I> n)
0400 (
0401 i + n,
0402 n + i,
0403 i - n,
0404 i += n,
0405 i -= n,
0406 concepts::requires_<same_as<decltype(i + n), I>>,
0407 concepts::requires_<same_as<decltype(n + i), I>>,
0408 concepts::requires_<same_as<decltype(i - n), I>>,
0409 concepts::requires_<same_as<decltype(i += n), I&>>,
0410 concepts::requires_<same_as<decltype(i -= n), I&>>,
0411 concepts::requires_<same_as<decltype(i[n]), iter_reference_t<I>>>
0412 ));
0413
0414
0415 template<typename I>
0416 CPP_concept random_access_iterator =
0417 bidirectional_iterator<I> &&
0418 totally_ordered<I> &&
0419 sized_sentinel_for<I, I> &&
0420 CPP_requires_ref(ranges::random_access_iterator_, I) &&
0421 CPP_concept_ref(ranges::with_category_, I, std::random_access_iterator_tag);
0422
0423
0424
0425 template(typename I)(
0426 concept (contiguous_iterator_)(I),
0427 std::is_lvalue_reference<iter_reference_t<I>>::value AND
0428 same_as<iter_value_t<I>, uncvref_t<iter_reference_t<I>>> AND
0429 derived_from<detail::iter_concept_t<I>, ranges::contiguous_iterator_tag>
0430 );
0431
0432
0433
0434 template<typename I>
0435 CPP_concept contiguous_iterator =
0436 random_access_iterator<I> &&
0437 CPP_concept_ref(ranges::contiguous_iterator_, I);
0438
0439
0440
0441
0442 template<typename Rng>
0443 using iterator_tag_of =
0444 std::enable_if_t<
0445 input_iterator<Rng>,
0446 meta::conditional_t<
0447 contiguous_iterator<Rng>,
0448 ranges::contiguous_iterator_tag,
0449 meta::conditional_t<
0450 random_access_iterator<Rng>,
0451 std::random_access_iterator_tag,
0452 meta::conditional_t<
0453 bidirectional_iterator<Rng>,
0454 std::bidirectional_iterator_tag,
0455 meta::conditional_t<
0456 forward_iterator<Rng>,
0457 std::forward_iterator_tag,
0458 std::input_iterator_tag>>>>>;
0459
0460
0461 namespace detail
0462 {
0463 template<typename, bool>
0464 struct iterator_category_
0465 {};
0466
0467 template<typename I>
0468 struct iterator_category_<I, true>
0469 {
0470 using type = iterator_tag_of<I>;
0471 };
0472
0473 template<typename T, typename U = meta::_t<std::remove_const<T>>>
0474 using iterator_category = iterator_category_<U, (bool)input_iterator<U>>;
0475 }
0476
0477
0478
0479
0480
0481
0482
0483 template<typename I>
0484 CPP_concept single_pass_iterator_ =
0485 input_or_output_iterator<I> && !forward_iterator<I>;
0486
0487
0488
0489
0490
0491 template<typename Fun, typename... Is>
0492 using indirect_result_t =
0493 detail::enable_if_t<(bool)and_v<(bool)indirectly_readable<Is>...>,
0494 invoke_result_t<Fun, iter_reference_t<Is>...>>;
0495
0496
0497 namespace detail
0498 {
0499
0500
0501
0502 template(typename T1, typename T2, typename T3, typename T4)(
0503 concept (common_reference_with_4_impl_)(T1, T2, T3, T4),
0504 concepts::type<common_reference_t<T1, T2, T3, T4>> AND
0505 convertible_to<T1, common_reference_t<T1, T2, T3, T4>> AND
0506 convertible_to<T2, common_reference_t<T1, T2, T3, T4>> AND
0507 convertible_to<T3, common_reference_t<T1, T2, T3, T4>> AND
0508 convertible_to<T4, common_reference_t<T1, T2, T3, T4>>
0509 );
0510
0511
0512
0513 template<typename T1, typename T2, typename T3, typename T4>
0514 CPP_concept common_reference_with_4_ =
0515 CPP_concept_ref(detail::common_reference_with_4_impl_, T1, T2, T3, T4);
0516
0517
0518
0519
0520
0521 template(typename F, typename I)(
0522 concept (indirectly_unary_invocable_impl_)(F, I),
0523 invocable<F &, iter_value_t<I> &> AND
0524 invocable<F &, iter_reference_t<I>> AND
0525 invocable<F &, iter_common_reference_t<I>> AND
0526 common_reference_with<
0527 invoke_result_t<F &, iter_value_t<I> &>,
0528 invoke_result_t<F &, iter_reference_t<I>>>
0529 );
0530
0531
0532
0533 template<typename F, typename I>
0534 CPP_concept indirectly_unary_invocable_ =
0535 indirectly_readable<I> &&
0536 CPP_concept_ref(detail::indirectly_unary_invocable_impl_, F, I);
0537
0538 }
0539
0540
0541
0542
0543
0544 template<typename F, typename I>
0545 CPP_concept indirectly_unary_invocable =
0546 detail::indirectly_unary_invocable_<F, I> &&
0547 copy_constructible<F>;
0548
0549
0550
0551 template(typename F, typename I)(
0552 concept (indirectly_regular_unary_invocable_)(F, I),
0553 regular_invocable<F &, iter_value_t<I> &> AND
0554 regular_invocable<F &, iter_reference_t<I>> AND
0555 regular_invocable<F &, iter_common_reference_t<I>> AND
0556 common_reference_with<
0557 invoke_result_t<F &, iter_value_t<I> &>,
0558 invoke_result_t<F &, iter_reference_t<I>>>
0559 );
0560
0561
0562
0563 template<typename F, typename I>
0564 CPP_concept indirectly_regular_unary_invocable =
0565 indirectly_readable<I> &&
0566 copy_constructible<F> &&
0567 CPP_concept_ref(ranges::indirectly_regular_unary_invocable_, F, I);
0568
0569
0570
0571
0572
0573 template(typename F, typename I1, typename I2)(
0574 concept (indirectly_binary_invocable_impl_)(F, I1, I2),
0575 invocable<F &, iter_value_t<I1> &, iter_value_t<I2> &> AND
0576 invocable<F &, iter_value_t<I1> &, iter_reference_t<I2>> AND
0577 invocable<F &, iter_reference_t<I1>, iter_value_t<I2> &> AND
0578 invocable<F &, iter_reference_t<I1>, iter_reference_t<I2>> AND
0579 invocable<F &, iter_common_reference_t<I1>, iter_common_reference_t<I2>> AND
0580 detail::common_reference_with_4_<
0581 invoke_result_t<F &, iter_value_t<I1> &, iter_value_t<I2> &>,
0582 invoke_result_t<F &, iter_value_t<I1> &, iter_reference_t<I2>>,
0583 invoke_result_t<F &, iter_reference_t<I1>, iter_value_t<I2> &>,
0584 invoke_result_t<F &, iter_reference_t<I1>, iter_reference_t<I2>>>
0585 );
0586
0587
0588
0589 template<typename F, typename I1, typename I2>
0590 CPP_concept indirectly_binary_invocable_ =
0591 indirectly_readable<I1> && indirectly_readable<I2> &&
0592 copy_constructible<F> &&
0593 CPP_concept_ref(ranges::indirectly_binary_invocable_impl_, F, I1, I2);
0594
0595
0596
0597 template(typename F, typename I1, typename I2)(
0598 concept (indirectly_regular_binary_invocable_impl_)(F, I1, I2),
0599 regular_invocable<F &, iter_value_t<I1> &, iter_value_t<I2> &> AND
0600 regular_invocable<F &, iter_value_t<I1> &, iter_reference_t<I2>> AND
0601 regular_invocable<F &, iter_reference_t<I1>, iter_value_t<I2> &> AND
0602 regular_invocable<F &, iter_reference_t<I1>, iter_reference_t<I2>> AND
0603 regular_invocable<F &, iter_common_reference_t<I1>, iter_common_reference_t<I2>> AND
0604 detail::common_reference_with_4_<
0605 invoke_result_t<F &, iter_value_t<I1> &, iter_value_t<I2> &>,
0606 invoke_result_t<F &, iter_value_t<I1> &, iter_reference_t<I2>>,
0607 invoke_result_t<F &, iter_reference_t<I1>, iter_value_t<I2> &>,
0608 invoke_result_t<F &, iter_reference_t<I1>, iter_reference_t<I2>>>
0609 );
0610
0611
0612
0613 template<typename F, typename I1, typename I2>
0614 CPP_concept indirectly_regular_binary_invocable_ =
0615 indirectly_readable<I1> && indirectly_readable<I2> &&
0616 copy_constructible<F> &&
0617 CPP_concept_ref(ranges::indirectly_regular_binary_invocable_impl_, F, I1, I2);
0618
0619
0620
0621
0622 template(typename F, typename I)(
0623 concept (indirect_unary_predicate_)(F, I),
0624 predicate<F &, iter_value_t<I> &> AND
0625 predicate<F &, iter_reference_t<I>> AND
0626 predicate<F &, iter_common_reference_t<I>>
0627 );
0628
0629
0630
0631 template<typename F, typename I>
0632 CPP_concept indirect_unary_predicate =
0633 indirectly_readable<I> &&
0634 copy_constructible<F> &&
0635 CPP_concept_ref(ranges::indirect_unary_predicate_, F, I);
0636
0637
0638
0639 template(typename F, typename I1, typename I2)(
0640 concept (indirect_binary_predicate_impl_)(F, I1, I2),
0641 predicate<F &, iter_value_t<I1> &, iter_value_t<I2> &> AND
0642 predicate<F &, iter_value_t<I1> &, iter_reference_t<I2>> AND
0643 predicate<F &, iter_reference_t<I1>, iter_value_t<I2> &> AND
0644 predicate<F &, iter_reference_t<I1>, iter_reference_t<I2>> AND
0645 predicate<F &, iter_common_reference_t<I1>, iter_common_reference_t<I2>>
0646 );
0647
0648
0649
0650 template<typename F, typename I1, typename I2>
0651 CPP_concept indirect_binary_predicate_ =
0652 indirectly_readable<I1> && indirectly_readable<I2> &&
0653 copy_constructible<F> &&
0654 CPP_concept_ref(ranges::indirect_binary_predicate_impl_, F, I1, I2);
0655
0656
0657
0658 template(typename F, typename I1, typename I2)(
0659 concept (indirect_relation_)(F, I1, I2),
0660 relation<F &, iter_value_t<I1> &, iter_value_t<I2> &> AND
0661 relation<F &, iter_value_t<I1> &, iter_reference_t<I2>> AND
0662 relation<F &, iter_reference_t<I1>, iter_value_t<I2> &> AND
0663 relation<F &, iter_reference_t<I1>, iter_reference_t<I2>> AND
0664 relation<F &, iter_common_reference_t<I1>, iter_common_reference_t<I2>>
0665 );
0666
0667
0668
0669 template<typename F, typename I1, typename I2 = I1>
0670 CPP_concept indirect_relation =
0671 indirectly_readable<I1> && indirectly_readable<I2> &&
0672 copy_constructible<F> &&
0673 CPP_concept_ref(ranges::indirect_relation_, F, I1, I2);
0674
0675
0676
0677 template(typename F, typename I1, typename I2)(
0678 concept (indirect_strict_weak_order_)(F, I1, I2),
0679 strict_weak_order<F &, iter_value_t<I1> &, iter_value_t<I2> &> AND
0680 strict_weak_order<F &, iter_value_t<I1> &, iter_reference_t<I2>> AND
0681 strict_weak_order<F &, iter_reference_t<I1>, iter_value_t<I2> &> AND
0682 strict_weak_order<F &, iter_reference_t<I1>, iter_reference_t<I2>> AND
0683 strict_weak_order<F &, iter_common_reference_t<I1>, iter_common_reference_t<I2>>
0684 );
0685
0686
0687
0688 template<typename F, typename I1, typename I2 = I1>
0689 CPP_concept indirect_strict_weak_order =
0690 indirectly_readable<I1> && indirectly_readable<I2> &&
0691 copy_constructible<F> &&
0692 CPP_concept_ref(ranges::indirect_strict_weak_order_, F, I1, I2);
0693
0694
0695
0696
0697
0698 namespace detail
0699 {
0700 RANGES_DIAGNOSTIC_PUSH
0701 RANGES_DIAGNOSTIC_IGNORE_UNDEFINED_INTERNAL
0702 template<typename I, typename Proj>
0703 struct projected_
0704 {
0705 struct type
0706 {
0707 using reference = indirect_result_t<Proj &, I>;
0708 using value_type = uncvref_t<reference>;
0709 reference operator*() const;
0710 };
0711 };
0712 RANGES_DIAGNOSTIC_POP
0713
0714 template<typename Proj>
0715 struct select_projected_
0716 {
0717 template<typename I>
0718 using apply =
0719 meta::_t<
0720 detail::enable_if_t<
0721 (bool)indirectly_regular_unary_invocable<Proj, I>,
0722 detail::projected_<I, Proj>>>;
0723 };
0724
0725 template<>
0726 struct select_projected_<identity>
0727 {
0728 template<typename I>
0729 using apply = detail::enable_if_t<(bool)indirectly_readable<I>, I>;
0730 };
0731 }
0732
0733
0734 template<typename I, typename Proj>
0735 using projected = typename detail::select_projected_<Proj>::template apply<I>;
0736
0737 template<typename I, typename Proj>
0738 struct incrementable_traits<detail::projected_<I, Proj>> : incrementable_traits<I>
0739 {};
0740
0741
0742
0743
0744 template(typename I, typename O)(
0745 concept (indirectly_movable_)(I, O),
0746 indirectly_writable<O, iter_rvalue_reference_t<I>>
0747 );
0748
0749
0750
0751 template<typename I, typename O>
0752 CPP_concept indirectly_movable =
0753 indirectly_readable<I> && CPP_concept_ref(ranges::indirectly_movable_, I, O);
0754
0755
0756
0757 template(typename I, typename O)(
0758 concept (indirectly_movable_storable_)(I, O),
0759 indirectly_writable<O, iter_value_t<I>> AND
0760 movable<iter_value_t<I>> AND
0761 constructible_from<iter_value_t<I>, iter_rvalue_reference_t<I>> AND
0762 assignable_from<iter_value_t<I> &, iter_rvalue_reference_t<I>>
0763 );
0764
0765
0766
0767 template<typename I, typename O>
0768 CPP_concept indirectly_movable_storable =
0769 indirectly_movable<I, O> &&
0770 CPP_concept_ref(ranges::indirectly_movable_storable_, I, O);
0771
0772
0773
0774 template(typename I, typename O)(
0775 concept (indirectly_copyable_)(I, O),
0776 indirectly_writable<O, iter_reference_t<I>>
0777 );
0778
0779
0780
0781 template<typename I, typename O>
0782 CPP_concept indirectly_copyable =
0783 indirectly_readable<I> && CPP_concept_ref(ranges::indirectly_copyable_, I, O);
0784
0785
0786
0787 template(typename I, typename O)(
0788 concept (indirectly_copyable_storable_)(I, O),
0789 indirectly_writable<O, iter_value_t<I> const &> AND
0790 copyable<iter_value_t<I>> AND
0791 constructible_from<iter_value_t<I>, iter_reference_t<I>> AND
0792 assignable_from<iter_value_t<I> &, iter_reference_t<I>>
0793 );
0794
0795
0796
0797 template<typename I, typename O>
0798 CPP_concept indirectly_copyable_storable =
0799 indirectly_copyable<I, O> &&
0800 CPP_concept_ref(ranges::indirectly_copyable_storable_, I, O);
0801
0802
0803
0804 template<typename I1, typename I2>
0805 CPP_requires(indirectly_swappable_,
0806 requires(I1 const i1, I2 const i2)
0807 (
0808 ranges::iter_swap(i1, i2),
0809 ranges::iter_swap(i1, i1),
0810 ranges::iter_swap(i2, i2),
0811 ranges::iter_swap(i2, i1)
0812 ));
0813
0814
0815 template<typename I1, typename I2 = I1>
0816 CPP_concept indirectly_swappable =
0817 indirectly_readable<I1> &&
0818 indirectly_readable<I2> &&
0819 CPP_requires_ref(ranges::indirectly_swappable_, I1, I2);
0820
0821
0822
0823 template(typename C, typename I1, typename P1, typename I2, typename P2)(
0824 concept (projected_indirect_relation_)(C, I1, P1, I2, P2),
0825 indirect_relation<C, projected<I1, P1>, projected<I2, P2>>
0826 );
0827
0828
0829
0830 template<typename I1, typename I2, typename C, typename P1 = identity,
0831 typename P2 = identity>
0832 CPP_concept indirectly_comparable =
0833 CPP_concept_ref(ranges::projected_indirect_relation_, C, I1, P1, I2, P2);
0834
0835
0836
0837
0838
0839 template<typename I>
0840 CPP_concept permutable =
0841 forward_iterator<I> &&
0842 indirectly_swappable<I, I> &&
0843 indirectly_movable_storable<I, I>;
0844
0845
0846
0847 template(typename C, typename I1, typename P1, typename I2, typename P2)(
0848 concept (projected_indirect_strict_weak_order_)(C, I1, P1, I2, P2),
0849 indirect_strict_weak_order<C, projected<I1, P1>, projected<I2, P2>>
0850 );
0851
0852 template<typename I1, typename I2, typename Out, typename C = less,
0853 typename P1 = identity, typename P2 = identity>
0854 CPP_concept mergeable =
0855 input_iterator<I1> &&
0856 input_iterator<I2> &&
0857 weakly_incrementable<Out> &&
0858 indirectly_copyable<I1, Out> &&
0859 indirectly_copyable<I2, Out> &&
0860 CPP_concept_ref(ranges::projected_indirect_strict_weak_order_, C, I1, P1, I2, P2);
0861
0862
0863
0864 template<typename I, typename C = less, typename P = identity>
0865 CPP_concept sortable =
0866 permutable<I> &&
0867 CPP_concept_ref(ranges::projected_indirect_strict_weak_order_, C, I, P, I, P);
0868
0869
0870 struct sentinel_tag
0871 {};
0872 struct sized_sentinel_tag : sentinel_tag
0873 {};
0874
0875 template<typename S, typename I>
0876 using sentinel_tag_of =
0877 std::enable_if_t<
0878 sentinel_for<S, I>,
0879 meta::conditional_t<
0880 sized_sentinel_for<S, I>,
0881 sized_sentinel_tag,
0882 sentinel_tag>>;
0883
0884
0885
0886 template<typename I>
0887 using iterator_category RANGES_DEPRECATED(
0888 "iterator_category is deprecated. Use the iterator concepts instead") =
0889 detail::iterator_category<I>;
0890
0891 template<typename I>
0892 using iterator_category_t RANGES_DEPRECATED(
0893 "iterator_category_t is deprecated. Use the iterator concepts instead") =
0894 meta::_t<detail::iterator_category<I>>;
0895
0896 template<typename Fun, typename... Is>
0897 using indirect_invoke_result_t RANGES_DEPRECATED(
0898 "Please switch to indirect_result_t") = indirect_result_t<Fun, Is...>;
0899
0900 template<typename Fun, typename... Is>
0901 struct RANGES_DEPRECATED("Please switch to indirect_result_t") indirect_invoke_result
0902 : meta::defer<indirect_result_t, Fun, Is...>
0903 {};
0904
0905 template<typename Sig>
0906 struct indirect_result_of
0907 {};
0908
0909 template<typename Fun, typename... Is>
0910 struct RANGES_DEPRECATED("Please switch to indirect_result_t")
0911 indirect_result_of<Fun(Is...)> : meta::defer<indirect_result_t, Fun, Is...>
0912 {};
0913
0914 template<typename Sig>
0915 using indirect_result_of_t RANGES_DEPRECATED("Please switch to indirect_result_t") =
0916 meta::_t<indirect_result_of<Sig>>;
0917
0918
0919 namespace cpp20
0920 {
0921 using ranges::bidirectional_iterator;
0922 using ranges::contiguous_iterator;
0923 using ranges::forward_iterator;
0924 using ranges::incrementable;
0925 using ranges::indirect_relation;
0926 using ranges::indirect_result_t;
0927 using ranges::indirect_strict_weak_order;
0928 using ranges::indirect_unary_predicate;
0929 using ranges::indirectly_comparable;
0930 using ranges::indirectly_copyable;
0931 using ranges::indirectly_copyable_storable;
0932 using ranges::indirectly_movable;
0933 using ranges::indirectly_movable_storable;
0934 using ranges::indirectly_readable;
0935 using ranges::indirectly_regular_unary_invocable;
0936 using ranges::indirectly_swappable;
0937 using ranges::indirectly_unary_invocable;
0938 using ranges::indirectly_writable;
0939 using ranges::input_iterator;
0940 using ranges::input_or_output_iterator;
0941 using ranges::mergeable;
0942 using ranges::output_iterator;
0943 using ranges::permutable;
0944 using ranges::projected;
0945 using ranges::random_access_iterator;
0946 using ranges::sentinel_for;
0947 using ranges::sized_sentinel_for;
0948 using ranges::sortable;
0949 using ranges::weakly_incrementable;
0950 }
0951
0952 }
0953
0954 #ifdef _GLIBCXX_DEBUG
0955
0956
0957
0958 namespace __gnu_debug
0959 {
0960 template(typename I1, typename I2, typename Seq)(
0961 requires (!::ranges::sized_sentinel_for<I1, I2>))
0962 void operator-(_Safe_iterator<I1, Seq> const &, _Safe_iterator<I2, Seq> const &) =
0963 delete;
0964
0965 template(typename I1, typename Seq)(
0966 requires (!::ranges::sized_sentinel_for<I1, I1>))
0967 void operator-(_Safe_iterator<I1, Seq> const &, _Safe_iterator<I1, Seq> const &) =
0968 delete;
0969 }
0970 #endif
0971
0972 #if defined(__GLIBCXX__) || (defined(_LIBCPP_VERSION) && _LIBCPP_VERSION <= 3900)
0973
0974
0975
0976
0977
0978 namespace ranges
0979 {
0980 template<typename S, typename I>
0981 constexpr bool
0982 disable_sized_sentinel<std::reverse_iterator<S>, std::reverse_iterator<I>> =
0983 !static_cast<bool>(sized_sentinel_for<I, S>);
0984 }
0985
0986 #endif
0987
0988 #include <range/v3/detail/epilogue.hpp>
0989
0990 #endif