File indexing completed on 2025-09-18 08:53:49
0001
0002
0003
0004
0005
0006 #ifndef BOOST_PARSER_DETAIL_STL_INTERFACES_ITERATOR_INTERFACE_HPP
0007 #define BOOST_PARSER_DETAIL_STL_INTERFACES_ITERATOR_INTERFACE_HPP
0008
0009 #include <boost/parser/detail/stl_interfaces/fwd.hpp>
0010
0011 #include <utility>
0012 #include <type_traits>
0013 #if defined(__cpp_lib_three_way_comparison)
0014 #include <compare>
0015 #endif
0016
0017
0018 namespace boost::parser::detail { namespace stl_interfaces {
0019
0020
0021
0022 struct access
0023 {
0024 #ifndef BOOST_STL_INTERFACES_DOXYGEN
0025
0026 template<typename D>
0027 static constexpr auto base(D & d) noexcept
0028 -> decltype(d.base_reference())
0029 {
0030 return d.base_reference();
0031 }
0032 template<typename D>
0033 static constexpr auto base(D const & d) noexcept
0034 -> decltype(d.base_reference())
0035 {
0036 return d.base_reference();
0037 }
0038
0039 #endif
0040 };
0041
0042
0043
0044
0045
0046
0047
0048 template<typename T>
0049 #if defined(BOOST_STL_INTERFACES_DOXYGEN) || BOOST_PARSER_USE_CONCEPTS
0050 requires std::is_object_v<T>
0051 #endif
0052 struct proxy_arrow_result
0053 {
0054 constexpr proxy_arrow_result(T const & value) noexcept(
0055 noexcept(T(value))) :
0056 value_(value)
0057 {}
0058 constexpr proxy_arrow_result(T && value) noexcept(
0059 noexcept(T(std::move(value)))) :
0060 value_(std::move(value))
0061 {}
0062
0063 constexpr T const * operator->() const noexcept { return &value_; }
0064 constexpr T * operator->() noexcept { return &value_; }
0065
0066 private:
0067 T value_;
0068 };
0069
0070 namespace detail {
0071 template<typename Pointer, typename Reference, typename T>
0072 auto make_pointer(
0073 T && value,
0074 std::enable_if_t<
0075 std::is_pointer<Pointer>::value &&
0076 std::is_reference<Reference>::value,
0077 int> = 0) -> decltype(std::addressof(value))
0078 {
0079 return std::addressof(value);
0080 }
0081
0082 template<typename Pointer, typename Reference, typename T>
0083 auto make_pointer(
0084 T && value,
0085 std::enable_if_t<
0086 !std::is_pointer<Pointer>::value &&
0087 !std::is_same<Pointer, void>::value &&
0088 std::is_reference<Reference>::value,
0089 int> = 0)
0090 {
0091 return Pointer(std::forward<T>(value));
0092 }
0093
0094 template<typename Pointer, typename IteratorConcept>
0095 struct pointer
0096 {
0097 using type = Pointer;
0098 };
0099 template<typename Pointer>
0100 struct pointer<Pointer, std::output_iterator_tag>
0101 {
0102 using type = void;
0103 };
0104 template<typename Pointer, typename IteratorConcept>
0105 using pointer_t = typename pointer<Pointer, IteratorConcept>::type;
0106
0107 template<typename T, typename U>
0108 using interoperable = std::integral_constant<
0109 bool,
0110 (std::is_convertible<T, U>::value ||
0111 std::is_convertible<U, T>::value)>;
0112
0113 template<typename T, typename U>
0114 using common_t =
0115 std::conditional_t<std::is_convertible<T, U>::value, U, T>;
0116
0117 template<typename T>
0118 using use_base = decltype(access::base(std::declval<T &>()));
0119
0120 template<typename... T>
0121 using void_t = void;
0122
0123 template<
0124 typename AlwaysVoid,
0125 template<class...> class Template,
0126 typename... Args>
0127 struct detector : std::false_type
0128 {
0129 };
0130
0131 template<template<class...> class Template, typename... Args>
0132 struct detector<void_t<Template<Args...>>, Template, Args...>
0133 : std::true_type
0134 {
0135 };
0136
0137 template<
0138 typename T,
0139 typename U,
0140 bool UseBase = detector<void, use_base, T>::value>
0141 struct common_eq
0142 {
0143 static constexpr auto call(T lhs, U rhs)
0144 {
0145 return static_cast<common_t<T, U>>(lhs).derived() ==
0146 static_cast<common_t<T, U>>(rhs).derived();
0147 }
0148 };
0149 template<typename T, typename U>
0150 struct common_eq<T, U, true>
0151 {
0152 static constexpr auto call(T lhs, U rhs)
0153 {
0154 return access::base(lhs) == access::base(rhs);
0155 }
0156 };
0157
0158 template<typename T, typename U>
0159 constexpr auto common_diff(T lhs, U rhs) noexcept(noexcept(
0160 static_cast<common_t<T, U>>(lhs) -
0161 static_cast<common_t<T, U>>(rhs)))
0162 -> decltype(
0163 static_cast<common_t<T, U>>(lhs) -
0164 static_cast<common_t<T, U>>(rhs))
0165 {
0166 return static_cast<common_t<T, U>>(lhs) -
0167 static_cast<common_t<T, U>>(rhs);
0168 }
0169 }
0170
0171 }}
0172
0173 namespace boost::parser::detail { namespace stl_interfaces { BOOST_PARSER_DETAIL_STL_INTERFACES_NAMESPACE_V1 {
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183 template<
0184 typename Derived,
0185 typename IteratorConcept,
0186 typename ValueType,
0187 typename Reference = ValueType &,
0188 typename Pointer = ValueType *,
0189 typename DifferenceType = std::ptrdiff_t
0190 #ifndef BOOST_STL_INTERFACES_DOXYGEN
0191 ,
0192 typename E = std::enable_if_t<
0193 std::is_class<Derived>::value &&
0194 std::is_same<Derived, std::remove_cv_t<Derived>>::value>
0195 #endif
0196 >
0197 struct iterator_interface;
0198
0199 namespace v1_dtl {
0200 template<typename Iterator, typename = void>
0201 struct ra_iter : std::false_type
0202 {
0203 };
0204 template<typename Iterator>
0205 struct ra_iter<Iterator, void_t<typename Iterator::iterator_concept>>
0206 : std::integral_constant<
0207 bool,
0208 std::is_base_of<
0209 std::random_access_iterator_tag,
0210 typename Iterator::iterator_concept>::value>
0211 {
0212 };
0213
0214 template<typename Iterator, typename DifferenceType, typename = void>
0215 struct plus_eq : std::false_type
0216 {
0217 };
0218 template<typename Iterator, typename DifferenceType>
0219 struct plus_eq<
0220 Iterator,
0221 DifferenceType,
0222 void_t<decltype(
0223 std::declval<Iterator &>() += std::declval<DifferenceType>())>>
0224 : std::true_type
0225 {
0226 };
0227
0228 template<
0229 typename D,
0230 typename IteratorConcept,
0231 typename ValueType,
0232 typename Reference,
0233 typename Pointer,
0234 typename DifferenceType>
0235 void derived_iterator(iterator_interface<
0236 D,
0237 IteratorConcept,
0238 ValueType,
0239 Reference,
0240 Pointer,
0241 DifferenceType> const &);
0242 }
0243
0244 template<
0245 typename Derived,
0246 typename IteratorConcept,
0247 typename ValueType,
0248 typename Reference,
0249 typename Pointer,
0250 typename DifferenceType
0251 #ifndef BOOST_STL_INTERFACES_DOXYGEN
0252 ,
0253 typename E
0254 #endif
0255 >
0256 struct iterator_interface
0257 {
0258 #ifndef BOOST_STL_INTERFACES_DOXYGEN
0259 private:
0260 constexpr Derived & derived() noexcept
0261 {
0262 return static_cast<Derived &>(*this);
0263 }
0264 constexpr Derived const & derived() const noexcept
0265 {
0266 return static_cast<Derived const &>(*this);
0267 }
0268
0269 template<typename T, typename U, bool UseBase>
0270 friend struct detail::common_eq;
0271 #endif
0272
0273 public:
0274 using iterator_concept = IteratorConcept;
0275 using iterator_category = iterator_concept;
0276 using value_type = std::remove_const_t<ValueType>;
0277 using reference = Reference;
0278 using pointer = detail::pointer_t<Pointer, iterator_concept>;
0279 using difference_type = DifferenceType;
0280
0281 template<typename D = Derived>
0282 constexpr auto operator*()
0283 noexcept(noexcept(*access::base(std::declval<D &>())))
0284 -> decltype(*access::base(std::declval<D &>()))
0285 {
0286 return *access::base(derived());
0287 }
0288 template<typename D = Derived>
0289 constexpr auto operator*() const
0290 noexcept(noexcept(*access::base(std::declval<D const &>())))
0291 -> decltype(*access::base(std::declval<D const &>()))
0292 {
0293 return *access::base(derived());
0294 }
0295
0296 template<typename D = Derived>
0297 constexpr auto operator->() noexcept(noexcept(
0298 detail::make_pointer<pointer, reference>(*std::declval<D &>())))
0299 -> decltype(
0300 detail::make_pointer<pointer, reference>(*std::declval<D &>()))
0301 {
0302 return detail::make_pointer<pointer, reference>(*derived());
0303 }
0304 template<typename D = Derived>
0305 constexpr auto operator->() const noexcept(noexcept(
0306 detail::make_pointer<pointer, reference>(
0307 *std::declval<D const &>())))
0308 -> decltype(
0309 detail::make_pointer<pointer, reference>(
0310 *std::declval<D const &>()))
0311 {
0312 return detail::make_pointer<pointer, reference>(*derived());
0313 }
0314
0315 template<typename D = Derived>
0316 constexpr auto operator[](difference_type i) const noexcept(noexcept(
0317 D(std::declval<D const &>()),
0318 std::declval<D &>() += i,
0319 *std::declval<D &>()))
0320 -> decltype(std::declval<D &>() += i, *std::declval<D &>())
0321 {
0322 D retval = derived();
0323 retval += i;
0324 return *retval;
0325 }
0326
0327 template<
0328 typename D = Derived,
0329 typename Enable =
0330 std::enable_if_t<!v1_dtl::plus_eq<D, difference_type>::value>>
0331 constexpr auto
0332 operator++() noexcept(noexcept(++access::base(std::declval<D &>())))
0333 -> decltype(
0334 ++access::base(std::declval<D &>()), std::declval<D &>())
0335 {
0336 ++access::base(derived());
0337 return derived();
0338 }
0339
0340 template<typename D = Derived>
0341 constexpr auto operator++() noexcept(
0342 noexcept(std::declval<D &>() += difference_type(1)))
0343 -> decltype(
0344 std::declval<D &>() += difference_type(1), std::declval<D &>())
0345 {
0346 derived() += difference_type(1);
0347 return derived();
0348 }
0349 template<typename D = Derived>
0350 constexpr auto operator++(int)noexcept(
0351 noexcept(D(std::declval<D &>()), ++std::declval<D &>()))
0352 -> std::remove_reference_t<decltype(
0353 D(std::declval<D &>()),
0354 ++std::declval<D &>(),
0355 std::declval<D &>())>
0356 {
0357 D retval = derived();
0358 ++derived();
0359 return retval;
0360 }
0361
0362 template<typename D = Derived>
0363 constexpr auto operator+=(difference_type n) noexcept(
0364 noexcept(access::base(std::declval<D &>()) += n))
0365 -> decltype(
0366 access::base(std::declval<D &>()) += n, std::declval<D &>())
0367 {
0368 access::base(derived()) += n;
0369 return derived();
0370 }
0371
0372 template<typename D = Derived>
0373 constexpr auto operator+(difference_type i) const
0374 noexcept(noexcept(D(std::declval<D &>()), std::declval<D &>() += i))
0375 -> std::remove_reference_t<decltype(
0376 D(std::declval<D &>()),
0377 std::declval<D &>() += i,
0378 std::declval<D &>())>
0379 {
0380 D retval = derived();
0381 retval += i;
0382 return retval;
0383 }
0384 friend constexpr Derived
0385 operator+(difference_type i, Derived it) noexcept
0386 {
0387 return it + i;
0388 }
0389
0390 template<
0391 typename D = Derived,
0392 typename Enable =
0393 std::enable_if_t<!v1_dtl::plus_eq<D, difference_type>::value>>
0394 constexpr auto
0395 operator--() noexcept(noexcept(--access::base(std::declval<D &>())))
0396 -> decltype(--access::base(std::declval<D &>()), std::declval<D &>())
0397 {
0398 --access::base(derived());
0399 return derived();
0400 }
0401
0402 template<typename D = Derived>
0403 constexpr auto operator--() noexcept(noexcept(
0404 D(std::declval<D &>()), std::declval<D &>() += -difference_type(1)))
0405 -> decltype(
0406 std::declval<D &>() += -difference_type(1), std::declval<D &>())
0407 {
0408 derived() += -difference_type(1);
0409 return derived();
0410 }
0411 template<typename D = Derived>
0412 constexpr auto operator--(int)noexcept(
0413 noexcept(D(std::declval<D &>()), --std::declval<D &>()))
0414 -> std::remove_reference_t<decltype(
0415 D(std::declval<D &>()),
0416 --std::declval<D &>(),
0417 std::declval<D &>())>
0418 {
0419 D retval = derived();
0420 --derived();
0421 return retval;
0422 }
0423
0424 template<typename D = Derived>
0425 constexpr D & operator-=(difference_type i) noexcept
0426 {
0427 derived() += -i;
0428 return derived();
0429 }
0430
0431 template<typename D = Derived>
0432 constexpr auto operator-(D other) const noexcept(noexcept(
0433 access::base(std::declval<D const &>()) - access::base(other)))
0434 -> decltype(
0435 access::base(std::declval<D const &>()) - access::base(other))
0436 {
0437 return access::base(derived()) - access::base(other);
0438 }
0439
0440 friend constexpr Derived
0441 operator-(Derived it, difference_type i) noexcept
0442 {
0443 Derived retval = it;
0444 retval += -i;
0445 return retval;
0446 }
0447 };
0448
0449
0450
0451
0452
0453 template<
0454 typename IteratorInterface1,
0455 typename IteratorInterface2,
0456 typename Enable =
0457 std::enable_if_t<!v1_dtl::ra_iter<IteratorInterface1>::value>>
0458 constexpr auto
0459 operator==(IteratorInterface1 lhs, IteratorInterface2 rhs) noexcept
0460 -> decltype(
0461 access::base(std::declval<IteratorInterface1 &>()) ==
0462 access::base(std::declval<IteratorInterface2 &>()))
0463 {
0464 return access::base(lhs) == access::base(rhs);
0465 }
0466
0467
0468
0469
0470 template<
0471 typename IteratorInterface1,
0472 typename IteratorInterface2,
0473 typename Enable =
0474 std::enable_if_t<v1_dtl::ra_iter<IteratorInterface1>::value>>
0475 constexpr auto
0476 operator==(IteratorInterface1 lhs, IteratorInterface2 rhs) noexcept(
0477 noexcept(detail::common_diff(lhs, rhs)))
0478 -> decltype(
0479 v1_dtl::derived_iterator(lhs), detail::common_diff(lhs, rhs) == 0)
0480 {
0481 return detail::common_diff(lhs, rhs) == 0;
0482 }
0483
0484
0485
0486 template<typename IteratorInterface1, typename IteratorInterface2>
0487 constexpr auto operator!=(
0488 IteratorInterface1 lhs,
0489 IteratorInterface2 rhs) noexcept(noexcept(!(lhs == rhs)))
0490 -> decltype(v1_dtl::derived_iterator(lhs), !(lhs == rhs))
0491 {
0492 return !(lhs == rhs);
0493 }
0494
0495
0496
0497
0498 template<typename IteratorInterface1, typename IteratorInterface2>
0499 constexpr auto
0500 operator<(IteratorInterface1 lhs, IteratorInterface2 rhs) noexcept(
0501 noexcept(detail::common_diff(lhs, rhs)))
0502 -> decltype(
0503 v1_dtl::derived_iterator(lhs), detail::common_diff(lhs, rhs) < 0)
0504 {
0505 return detail::common_diff(lhs, rhs) < 0;
0506 }
0507
0508
0509
0510
0511 template<typename IteratorInterface1, typename IteratorInterface2>
0512 constexpr auto
0513 operator<=(IteratorInterface1 lhs, IteratorInterface2 rhs) noexcept(
0514 noexcept(detail::common_diff(lhs, rhs)))
0515 -> decltype(
0516 v1_dtl::derived_iterator(lhs), detail::common_diff(lhs, rhs) <= 0)
0517 {
0518 return detail::common_diff(lhs, rhs) <= 0;
0519 }
0520
0521
0522
0523
0524 template<typename IteratorInterface1, typename IteratorInterface2>
0525 constexpr auto
0526 operator>(IteratorInterface1 lhs, IteratorInterface2 rhs) noexcept(
0527 noexcept(detail::common_diff(lhs, rhs)))
0528 -> decltype(
0529 v1_dtl::derived_iterator(lhs), detail::common_diff(lhs, rhs) > 0)
0530 {
0531 return detail::common_diff(lhs, rhs) > 0;
0532 }
0533
0534
0535
0536
0537 template<typename IteratorInterface1, typename IteratorInterface2>
0538 constexpr auto
0539 operator>=(IteratorInterface1 lhs, IteratorInterface2 rhs) noexcept(
0540 noexcept(detail::common_diff(lhs, rhs)))
0541 -> decltype(
0542 v1_dtl::derived_iterator(lhs), detail::common_diff(lhs, rhs) >= 0)
0543 {
0544 return detail::common_diff(lhs, rhs) >= 0;
0545 }
0546
0547
0548
0549
0550 template<
0551 typename Derived,
0552 typename IteratorConcept,
0553 typename ValueType,
0554 typename Reference = ValueType,
0555 typename DifferenceType = std::ptrdiff_t>
0556 using proxy_iterator_interface = iterator_interface<
0557 Derived,
0558 IteratorConcept,
0559 ValueType,
0560 Reference,
0561 proxy_arrow_result<Reference>,
0562 DifferenceType>;
0563
0564 }}}
0565
0566 #if defined(BOOST_STL_INTERFACES_DOXYGEN) || BOOST_PARSER_USE_CONCEPTS
0567
0568 namespace boost::parser::detail { namespace stl_interfaces { BOOST_PARSER_DETAIL_STL_INTERFACES_NAMESPACE_V2 {
0569
0570 namespace v2_dtl {
0571 template<typename Iterator>
0572 struct iter_concept;
0573
0574 template<typename Iterator>
0575 requires requires
0576 {
0577 typename std::iterator_traits<Iterator>::iterator_concept;
0578 }
0579 struct iter_concept<Iterator>
0580 {
0581 using type =
0582 typename std::iterator_traits<Iterator>::iterator_concept;
0583 };
0584
0585 template<typename Iterator>
0586 requires(
0587 !requires {
0588 typename std::iterator_traits<Iterator>::iterator_concept;
0589 } &&
0590 requires {
0591 typename std::iterator_traits<Iterator>::iterator_category;
0592 })
0593 struct iter_concept<Iterator>
0594 {
0595 using type =
0596 typename std::iterator_traits<Iterator>::iterator_category;
0597 };
0598
0599 template<typename Iterator>
0600 requires(
0601 !requires {
0602 typename std::iterator_traits<Iterator>::iterator_concept;
0603 } &&
0604 !requires {
0605 typename std::iterator_traits<Iterator>::iterator_category;
0606 })
0607 struct iter_concept<Iterator>
0608 {
0609 using type = std::random_access_iterator_tag;
0610 };
0611
0612 template<typename Iterator>
0613 struct iter_concept
0614 {};
0615
0616 template<typename Iterator>
0617 using iter_concept_t = typename iter_concept<Iterator>::type;
0618
0619 template<typename D, typename DifferenceType>
0620 concept plus_eq = requires(D d) { d += DifferenceType(1); };
0621
0622 template<typename D, typename D2 = D>
0623 concept base_3way =
0624 #if defined(__cpp_impl_three_way_comparison)
0625 requires(D d, D2 d2) { access::base(d) <=> access::base(d2); };
0626 #else
0627 false;
0628 #endif
0629
0630 template<typename D1, typename D2 = D1>
0631 concept base_eq =
0632 requires(D1 d1, D2 d2) { access::base(d1) == access::base(d2); };
0633
0634 template<typename D, typename D2 = D>
0635 concept iter_sub = requires(D d, D2 d2) {
0636 typename D::difference_type;
0637 { d - d2 } -> std::convertible_to<typename D::difference_type>;
0638 };
0639
0640
0641
0642
0643
0644 template<typename IteratorConcept, typename ReferenceType>
0645 constexpr auto category_tag()
0646 {
0647 if constexpr (std::is_base_of_v<
0648 std::forward_iterator_tag,
0649 IteratorConcept>) {
0650 if constexpr (!std::is_reference_v<ReferenceType>) {
0651 return std::input_iterator_tag{};
0652 } else if constexpr (std::is_base_of_v<
0653 std::random_access_iterator_tag,
0654 IteratorConcept>) {
0655 return std::random_access_iterator_tag{};
0656 } else if constexpr (std::is_base_of_v<
0657 std::bidirectional_iterator_tag,
0658 IteratorConcept>) {
0659 return std::bidirectional_iterator_tag{};
0660 } else {
0661 return std::forward_iterator_tag{};
0662 }
0663 } else {
0664 return 0;
0665 }
0666 }
0667 template<
0668 typename IteratorConcept,
0669 typename ReferenceType,
0670 typename IteratorCategory =
0671 decltype(v2_dtl::
0672 category_tag<IteratorConcept, ReferenceType>())>
0673 struct iterator_category_base
0674 {
0675 using iterator_category = IteratorCategory;
0676 };
0677
0678 template<typename IteratorConcept, typename ReferenceType>
0679 struct iterator_category_base<IteratorConcept, ReferenceType, int>
0680 {};
0681
0682 template<typename IteratorConcept, typename ReferenceType>
0683 constexpr bool non_input_tag()
0684 {
0685 if (std::same_as<IteratorConcept, std::input_iterator_tag>)
0686 return false;
0687 using tag_t =
0688 decltype(v2_dtl::
0689 category_tag<IteratorConcept, ReferenceType>());
0690 return !std::same_as<tag_t, std::input_iterator_tag>;
0691 }
0692 }
0693
0694
0695
0696
0697
0698
0699
0700
0701
0702
0703
0704 template<
0705 typename D,
0706 typename IteratorConcept,
0707 typename ValueType,
0708 typename Reference = ValueType &,
0709 typename Pointer = ValueType *,
0710 typename DifferenceType = std::ptrdiff_t>
0711 requires std::is_class_v<D> && std::same_as<D, std::remove_cv_t<D>>
0712 struct iterator_interface
0713 : v2_dtl::iterator_category_base<IteratorConcept, Reference>
0714 {
0715 private:
0716 constexpr D& derived() noexcept {
0717 return static_cast<D&>(*this);
0718 }
0719 constexpr const D& derived() const noexcept {
0720 return static_cast<const D&>(*this);
0721 }
0722
0723 public:
0724 using iterator_concept = IteratorConcept;
0725 using value_type = std::remove_const_t<ValueType>;
0726 using reference = Reference;
0727 using pointer = detail::pointer_t<Pointer, iterator_concept>;
0728 using difference_type = DifferenceType;
0729
0730 constexpr decltype(auto) operator*()
0731 requires requires (D d) { *access::base(d); } {
0732 return *access::base(derived());
0733 }
0734 constexpr decltype(auto) operator*() const
0735 requires requires (D const d) { *access::base(d); } {
0736 return *access::base(derived());
0737 }
0738
0739 constexpr auto operator->()
0740 requires (!std::same_as<pointer, void> && std::is_reference_v<reference> &&
0741 requires (D d) { *d; }) {
0742 return detail::make_pointer<pointer, reference>(*derived());
0743 }
0744 constexpr auto operator->() const
0745 requires (!std::same_as<pointer, void> && std::is_reference_v<reference> &&
0746 requires (D const d) { *d; }) {
0747 return detail::make_pointer<pointer, reference>(*derived());
0748 }
0749
0750 constexpr decltype(auto) operator[](difference_type n) const
0751 requires requires (D const d) { d + n; } {
0752 D retval = derived();
0753 retval += n;
0754 return *retval;
0755 }
0756
0757 constexpr decltype(auto) operator++()
0758 requires requires (D d) { ++access::base(d); } &&
0759 (!v2_dtl::plus_eq<D, difference_type>) {
0760 ++access::base(derived());
0761 return derived();
0762 }
0763 constexpr decltype(auto) operator++()
0764 requires requires (D d) { d += difference_type(1); } {
0765 return derived() += difference_type(1);
0766 }
0767 constexpr auto operator++(int) requires requires (D d) { ++d; } {
0768 if constexpr (std::is_same_v<IteratorConcept, std::input_iterator_tag>){
0769 ++derived();
0770 } else {
0771 D retval = derived();
0772 ++derived();
0773 return retval;
0774 }
0775 }
0776 constexpr decltype(auto) operator+=(difference_type n)
0777 requires requires (D d) { access::base(d) += n; } {
0778 access::base(derived()) += n;
0779 return derived();
0780 }
0781
0782 constexpr decltype(auto) operator--()
0783 requires requires (D d) { --access::base(d); } &&
0784 (!v2_dtl::plus_eq<D, difference_type>) {
0785 --access::base(derived());
0786 return derived();
0787 }
0788 constexpr decltype(auto) operator--()
0789 requires requires (D d) { d += -difference_type(1); } {
0790 return derived() += -difference_type(1);
0791 }
0792 constexpr auto operator--(int) requires requires (D d) { --d; } {
0793 D retval = derived();
0794 --derived();
0795 return retval;
0796 }
0797 constexpr decltype(auto) operator-=(difference_type n)
0798 requires requires (D d) { d += -n; } {
0799 return derived() += -n;
0800 }
0801 };
0802
0803 namespace v2_dtl {
0804 template<
0805 typename D,
0806 typename IteratorConcept,
0807 typename ValueType,
0808 typename Reference,
0809 typename Pointer,
0810 typename DifferenceType>
0811 void derived_iterator(v2::iterator_interface<
0812 D,
0813 IteratorConcept,
0814 ValueType,
0815 Reference,
0816 Pointer,
0817 DifferenceType> const &);
0818
0819 template<typename D>
0820 concept derived_iter = requires (D d) { v2_dtl::derived_iterator(d); };
0821 }
0822
0823 template<typename D>
0824 constexpr auto operator+(D it, typename D::difference_type n)
0825 requires v2_dtl::derived_iter<D> && requires { it += n; }
0826 { return it += n; }
0827 template<typename D>
0828 constexpr auto operator+(typename D::difference_type n, D it)
0829 requires v2_dtl::derived_iter<D> && requires { it += n; }
0830 { return it += n; }
0831
0832 template<typename D1, typename D2>
0833 constexpr auto operator-(D1 lhs, D2 rhs)
0834 requires v2_dtl::derived_iter<D1> && v2_dtl::derived_iter<D2> &&
0835 requires { access::base(lhs) - access::base(rhs); }
0836 { return access::base(lhs) - access::base(rhs); }
0837 template<typename D>
0838 constexpr auto operator-(D it, typename D::difference_type n)
0839 requires v2_dtl::derived_iter<D> && requires { it += -n; }
0840 { return it += -n; }
0841
0842 #if defined(__cpp_lib_three_way_comparison)
0843 template<typename D1, typename D2>
0844 constexpr auto operator<=>(D1 lhs, D2 rhs)
0845 requires v2_dtl::derived_iter<D1> && v2_dtl::derived_iter<D2> &&
0846 (v2_dtl::base_3way<D1, D2> || v2_dtl::iter_sub<D1, D2>) {
0847 if constexpr (v2_dtl::base_3way<D1, D2>) {
0848 return access::base(lhs) <=> access::base(rhs);
0849 } else {
0850 using diff_type = typename D1::difference_type;
0851 diff_type const diff = rhs - lhs;
0852 return diff < diff_type(0) ? std::strong_ordering::less :
0853 diff_type(0) < diff ? std::strong_ordering::greater :
0854 std::strong_ordering::equal;
0855 }
0856 }
0857 #endif
0858 template<typename D1, typename D2>
0859 constexpr bool operator<(D1 lhs, D2 rhs)
0860 requires v2_dtl::derived_iter<D1> && v2_dtl::derived_iter<D2> && v2_dtl::iter_sub<D1, D2>
0861 { return (lhs - rhs) < typename D1::difference_type(0); }
0862 template<typename D1, typename D2>
0863 constexpr bool operator<=(D1 lhs, D2 rhs)
0864 requires v2_dtl::derived_iter<D1> && v2_dtl::derived_iter<D2> && v2_dtl::iter_sub<D1, D2>
0865 { return (lhs - rhs) <= typename D1::difference_type(0); }
0866 template<typename D1, typename D2>
0867 constexpr bool operator>(D1 lhs, D2 rhs)
0868 requires v2_dtl::derived_iter<D1> && v2_dtl::derived_iter<D2> && v2_dtl::iter_sub<D1, D2>
0869 { return (lhs - rhs) > typename D1::difference_type(0); }
0870 template<typename D1, typename D2>
0871 constexpr bool operator>=(D1 lhs, D2 rhs)
0872 requires v2_dtl::derived_iter<D1> && v2_dtl::derived_iter<D2> && v2_dtl::iter_sub<D1, D2>
0873 { return (lhs - rhs) >= typename D1::difference_type(0); }
0874
0875 template<typename D1, typename D2>
0876 constexpr bool operator==(D1 lhs, D2 rhs)
0877 requires v2_dtl::derived_iter<D1> && v2_dtl::derived_iter<D2> &&
0878 detail::interoperable<D1, D2>::value &&
0879 (v2_dtl::base_eq<D1, D2> || v2_dtl::iter_sub<D1, D2>) {
0880 if constexpr (v2_dtl::base_eq<D1, D2>) {
0881 return (access::base(lhs) == access::base(rhs));
0882 } else if constexpr (v2_dtl::iter_sub<D1, D2>) {
0883 return (lhs - rhs) == typename D1::difference_type(0);
0884 }
0885 }
0886
0887 template<typename D1, typename D2>
0888 constexpr auto operator!=(D1 lhs, D2 rhs) -> decltype(!(lhs == rhs))
0889 requires v2_dtl::derived_iter<D1> && v2_dtl::derived_iter<D2>
0890 { return !(lhs == rhs); }
0891
0892
0893
0894
0895
0896
0897 template<
0898 typename Derived,
0899 typename IteratorConcept,
0900 typename ValueType,
0901 typename Reference = ValueType,
0902 typename DifferenceType = std::ptrdiff_t>
0903 using proxy_iterator_interface = iterator_interface<
0904 Derived,
0905 IteratorConcept,
0906 ValueType,
0907 Reference,
0908 proxy_arrow_result<Reference>,
0909 DifferenceType>;
0910
0911 }}}
0912
0913 #endif
0914
0915 #if defined(BOOST_STL_INTERFACES_DOXYGEN) || BOOST_PARSER_USE_DEDUCED_THIS
0916
0917 namespace boost::parser::detail { namespace stl_interfaces { BOOST_PARSER_DETAIL_STL_INTERFACES_NAMESPACE_V3 {
0918
0919
0920
0921
0922
0923 template<
0924 typename IteratorConcept,
0925 typename ValueType,
0926 typename Reference = ValueType &,
0927 typename Pointer = ValueType *,
0928 typename DifferenceType = std::ptrdiff_t>
0929 struct iterator_interface
0930 : v2::v2_dtl::iterator_category_base<IteratorConcept, Reference>
0931 {
0932 using iterator_concept = IteratorConcept;
0933 using value_type = std::remove_const_t<ValueType>;
0934 using reference = Reference;
0935 using pointer = detail::pointer_t<Pointer, iterator_concept>;
0936 using difference_type = DifferenceType;
0937
0938 constexpr decltype(auto) operator*(this auto&& self)
0939 requires requires { *access::base(self); } {
0940 return *access::base(self);
0941 }
0942
0943 constexpr auto operator->(this auto&& self)
0944 requires (!std::same_as<pointer, void>) && std::is_reference_v<reference> && requires { *self; } {
0945 return detail::make_pointer<pointer, reference>(*self);
0946 }
0947
0948 constexpr decltype(auto) operator[](this auto const& self, difference_type n)
0949 requires requires { self + n; } {
0950 auto retval = self;
0951 retval = retval + n;
0952 return *retval;
0953 }
0954
0955 constexpr decltype(auto) operator++(this auto& self)
0956 requires requires { ++access::base(self); } && (!requires { self += difference_type(1); }) {
0957 ++access::base(self);
0958 return self;
0959 }
0960 constexpr decltype(auto) operator++(this auto& self)
0961 requires requires { self += difference_type(1); } {
0962 return self += difference_type(1);
0963 }
0964 constexpr auto operator++(this auto& self, int) requires requires { ++self; } {
0965 if constexpr (std::is_same_v<IteratorConcept, std::input_iterator_tag>){
0966 ++self;
0967 } else {
0968 auto retval = self;
0969 ++self;
0970 return retval;
0971 }
0972 }
0973 constexpr decltype(auto) operator+=(this auto& self, difference_type n)
0974 requires requires { access::base(self) += n; } {
0975 access::base(self) += n;
0976 return self;
0977 }
0978
0979 constexpr decltype(auto) operator--(this auto& self)
0980 requires requires { --access::base(self); } && (!requires { self += difference_type(1); }) {
0981 --access::base(self);
0982 return self;
0983 }
0984 constexpr decltype(auto) operator--(this auto& self)
0985 requires requires { self += -difference_type(1); } {
0986 return self += -difference_type(1);
0987 }
0988 constexpr auto operator--(this auto& self, int) requires requires { --self; } {
0989 auto retval = self;
0990 --self;
0991 return retval;
0992 }
0993 constexpr decltype(auto) operator-=(this auto& self, difference_type n)
0994 requires requires { self += -n; } {
0995 return self += -n;
0996 }
0997 };
0998
0999 namespace v3_dtl {
1000 template<
1001 typename IteratorConcept,
1002 typename ValueType,
1003 typename Reference,
1004 typename Pointer,
1005 typename DifferenceType>
1006 void derived_iterator(v3::iterator_interface<
1007 IteratorConcept,
1008 ValueType,
1009 Reference,
1010 Pointer,
1011 DifferenceType> const &);
1012
1013 template<typename D>
1014 concept derived_iter = requires (D d) { v3_dtl::derived_iterator(d); };
1015 }
1016
1017 template<typename D>
1018 constexpr auto operator+(D it, typename D::difference_type n)
1019 requires v3_dtl::derived_iter<D> && requires { it += n; }
1020 { return it += n; }
1021 template<typename D>
1022 constexpr auto operator+(typename D::difference_type n, D it)
1023 requires v3_dtl::derived_iter<D> && requires { it += n; }
1024 { return it += n; }
1025
1026 template<typename D1, typename D2>
1027 constexpr auto operator-(D1 lhs, D2 rhs)
1028 requires v3_dtl::derived_iter<D1> && v3_dtl::derived_iter<D2> &&
1029 requires { access::base(lhs) - access::base(rhs); }
1030 { return access::base(lhs) - access::base(rhs); }
1031 template<typename D>
1032 constexpr auto operator-(D it, typename D::difference_type n)
1033 requires v3_dtl::derived_iter<D> && requires { it += -n; }
1034 { return it += -n; }
1035
1036 #if defined(__cpp_lib_three_way_comparison)
1037 template<typename D1, typename D2>
1038 constexpr auto operator<=>(D1 lhs, D2 rhs)
1039 requires v3_dtl::derived_iter<D1> && v3_dtl::derived_iter<D2> &&
1040 (v2::v2_dtl::base_3way<D1, D2> || v2::v2_dtl::iter_sub<D1, D2>) {
1041 if constexpr (v2::v2_dtl::base_3way<D1, D2>) {
1042 return access::base(lhs) <=> access::base(rhs);
1043 } else {
1044 using diff_type = typename D1::difference_type;
1045 diff_type const diff = rhs - lhs;
1046 return diff < diff_type(0) ? std::strong_ordering::less :
1047 diff_type(0) < diff ? std::strong_ordering::greater :
1048 std::strong_ordering::equal;
1049 }
1050 }
1051 #endif
1052 template<typename D1, typename D2>
1053 constexpr bool operator<(D1 lhs, D2 rhs)
1054 requires v3_dtl::derived_iter<D1> && v3_dtl::derived_iter<D2> && v2::v2_dtl::iter_sub<D1, D2>
1055 { return (lhs - rhs) < typename D1::difference_type(0); }
1056 template<typename D1, typename D2>
1057 constexpr bool operator<=(D1 lhs, D2 rhs)
1058 requires v3_dtl::derived_iter<D1> && v3_dtl::derived_iter<D2> && v2::v2_dtl::iter_sub<D1, D2>
1059 { return (lhs - rhs) <= typename D1::difference_type(0); }
1060 template<typename D1, typename D2>
1061 constexpr bool operator>(D1 lhs, D2 rhs)
1062 requires v3_dtl::derived_iter<D1> && v3_dtl::derived_iter<D2> && v2::v2_dtl::iter_sub<D1, D2>
1063 { return (lhs - rhs) > typename D1::difference_type(0); }
1064 template<typename D1, typename D2>
1065 constexpr bool operator>=(D1 lhs, D2 rhs)
1066 requires v3_dtl::derived_iter<D1> && v3_dtl::derived_iter<D2> && v2::v2_dtl::iter_sub<D1, D2>
1067 { return (lhs - rhs) >= typename D1::difference_type(0); }
1068
1069 template<typename D1, typename D2>
1070 constexpr bool operator==(D1 lhs, D2 rhs)
1071 requires v3_dtl::derived_iter<D1> && v3_dtl::derived_iter<D2> &&
1072 detail::interoperable<D1, D2>::value &&
1073 (v2::v2_dtl::base_eq<D1, D2> || v2::v2_dtl::iter_sub<D1, D2>) {
1074 if constexpr (v2::v2_dtl::base_eq<D1, D2>) {
1075 return (access::base(lhs) == access::base(rhs));
1076 } else if constexpr (v2::v2_dtl::iter_sub<D1, D2>) {
1077 return (lhs - rhs) == typename D1::difference_type(0);
1078 }
1079 }
1080
1081 template<typename D1, typename D2>
1082 constexpr auto operator!=(D1 lhs, D2 rhs) -> decltype(!(lhs == rhs))
1083 requires v3_dtl::derived_iter<D1> && v3_dtl::derived_iter<D2>
1084 { return !(lhs == rhs); }
1085
1086
1087
1088
1089
1090
1091 template<
1092 typename IteratorConcept,
1093 typename ValueType,
1094 typename Reference = ValueType,
1095 typename DifferenceType = std::ptrdiff_t>
1096 using proxy_iterator_interface = iterator_interface<
1097 IteratorConcept,
1098 ValueType,
1099 Reference,
1100 proxy_arrow_result<Reference>,
1101 DifferenceType>;
1102
1103 }}}
1104
1105 #endif
1106
1107 #endif