File indexing completed on 2026-05-03 08:13:17
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef _LIBCPP___CXX03___ALGORITHM_FIND_END_OF_H
0011 #define _LIBCPP___CXX03___ALGORITHM_FIND_END_OF_H
0012
0013 #include <__cxx03/__algorithm/comp.h>
0014 #include <__cxx03/__algorithm/iterator_operations.h>
0015 #include <__cxx03/__algorithm/search.h>
0016 #include <__cxx03/__config>
0017 #include <__cxx03/__functional/identity.h>
0018 #include <__cxx03/__functional/invoke.h>
0019 #include <__cxx03/__iterator/advance.h>
0020 #include <__cxx03/__iterator/iterator_traits.h>
0021 #include <__cxx03/__iterator/next.h>
0022 #include <__cxx03/__iterator/reverse_iterator.h>
0023 #include <__cxx03/__utility/pair.h>
0024
0025 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0026 # pragma GCC system_header
0027 #endif
0028
0029 _LIBCPP_BEGIN_NAMESPACE_STD
0030
0031 template < class _AlgPolicy,
0032 class _Iter1,
0033 class _Sent1,
0034 class _Iter2,
0035 class _Sent2,
0036 class _Pred,
0037 class _Proj1,
0038 class _Proj2>
0039 _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __find_end_impl(
0040 _Iter1 __first1,
0041 _Sent1 __last1,
0042 _Iter2 __first2,
0043 _Sent2 __last2,
0044 _Pred& __pred,
0045 _Proj1& __proj1,
0046 _Proj2& __proj2,
0047 forward_iterator_tag,
0048 forward_iterator_tag) {
0049
0050 _Iter1 __match_first = _IterOps<_AlgPolicy>::next(__first1, __last1);
0051 _Iter1 __match_last = __match_first;
0052 if (__first2 == __last2)
0053 return pair<_Iter1, _Iter1>(__match_last, __match_last);
0054 while (true) {
0055 while (true) {
0056 if (__first1 == __last1)
0057 return pair<_Iter1, _Iter1>(__match_first, __match_last);
0058 if (std::__invoke(__pred, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2)))
0059 break;
0060 ++__first1;
0061 }
0062
0063 _Iter1 __m1 = __first1;
0064 _Iter2 __m2 = __first2;
0065 while (true) {
0066 if (++__m2 == __last2) {
0067 __match_first = __first1;
0068 __match_last = ++__m1;
0069 ++__first1;
0070 break;
0071 }
0072 if (++__m1 == __last1)
0073 return pair<_Iter1, _Iter1>(__match_first, __match_last);
0074
0075 if (!std::__invoke(__pred, std::__invoke(__proj1, *__m1), std::__invoke(__proj2, *__m2))) {
0076 ++__first1;
0077 break;
0078 }
0079 }
0080 }
0081 }
0082
0083 template < class _IterOps,
0084 class _Pred,
0085 class _Iter1,
0086 class _Sent1,
0087 class _Iter2,
0088 class _Sent2,
0089 class _Proj1,
0090 class _Proj2>
0091 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter1 __find_end(
0092 _Iter1 __first1,
0093 _Sent1 __sent1,
0094 _Iter2 __first2,
0095 _Sent2 __sent2,
0096 _Pred& __pred,
0097 _Proj1& __proj1,
0098 _Proj2& __proj2,
0099 bidirectional_iterator_tag,
0100 bidirectional_iterator_tag) {
0101 auto __last1 = _IterOps::next(__first1, __sent1);
0102 auto __last2 = _IterOps::next(__first2, __sent2);
0103
0104 if (__first2 == __last2)
0105 return __last1;
0106 _Iter1 __l1 = __last1;
0107 _Iter2 __l2 = __last2;
0108 --__l2;
0109 while (true) {
0110
0111 while (true) {
0112 if (__first1 == __l1)
0113 return __last1;
0114 if (std::__invoke(__pred, std::__invoke(__proj1, *--__l1), std::__invoke(__proj2, *__l2)))
0115 break;
0116 }
0117
0118 _Iter1 __m1 = __l1;
0119 _Iter2 __m2 = __l2;
0120 while (true) {
0121 if (__m2 == __first2)
0122 return __m1;
0123 if (__m1 == __first1)
0124 return __last1;
0125
0126
0127 if (!std::__invoke(__pred, std::__invoke(__proj1, *--__m1), std::__invoke(__proj2, *--__m2))) {
0128 break;
0129 }
0130 }
0131 }
0132 }
0133
0134 template < class _AlgPolicy,
0135 class _Pred,
0136 class _Iter1,
0137 class _Sent1,
0138 class _Iter2,
0139 class _Sent2,
0140 class _Proj1,
0141 class _Proj2>
0142 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter1 __find_end(
0143 _Iter1 __first1,
0144 _Sent1 __sent1,
0145 _Iter2 __first2,
0146 _Sent2 __sent2,
0147 _Pred& __pred,
0148 _Proj1& __proj1,
0149 _Proj2& __proj2,
0150 random_access_iterator_tag,
0151 random_access_iterator_tag) {
0152 typedef typename iterator_traits<_Iter1>::difference_type _D1;
0153 auto __last1 = _IterOps<_AlgPolicy>::next(__first1, __sent1);
0154 auto __last2 = _IterOps<_AlgPolicy>::next(__first2, __sent2);
0155
0156 auto __len2 = __last2 - __first2;
0157 if (__len2 == 0)
0158 return __last1;
0159 auto __len1 = __last1 - __first1;
0160 if (__len1 < __len2)
0161 return __last1;
0162 const _Iter1 __s = __first1 + _D1(__len2 - 1);
0163 _Iter1 __l1 = __last1;
0164 _Iter2 __l2 = __last2;
0165 --__l2;
0166 while (true) {
0167 while (true) {
0168 if (__s == __l1)
0169 return __last1;
0170 if (std::__invoke(__pred, std::__invoke(__proj1, *--__l1), std::__invoke(__proj2, *__l2)))
0171 break;
0172 }
0173 _Iter1 __m1 = __l1;
0174 _Iter2 __m2 = __l2;
0175 while (true) {
0176 if (__m2 == __first2)
0177 return __m1;
0178
0179 if (!std::__invoke(__pred, std::__invoke(__proj1, *--__m1), std::__invoke(*--__m2))) {
0180 break;
0181 }
0182 }
0183 }
0184 }
0185
0186 template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
0187 _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator1 __find_end_classic(
0188 _ForwardIterator1 __first1,
0189 _ForwardIterator1 __last1,
0190 _ForwardIterator2 __first2,
0191 _ForwardIterator2 __last2,
0192 _BinaryPredicate& __pred) {
0193 auto __proj = __identity();
0194 return std::__find_end_impl<_ClassicAlgPolicy>(
0195 __first1,
0196 __last1,
0197 __first2,
0198 __last2,
0199 __pred,
0200 __proj,
0201 __proj,
0202 typename iterator_traits<_ForwardIterator1>::iterator_category(),
0203 typename iterator_traits<_ForwardIterator2>::iterator_category())
0204 .first;
0205 }
0206
0207 template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
0208 _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 find_end(
0209 _ForwardIterator1 __first1,
0210 _ForwardIterator1 __last1,
0211 _ForwardIterator2 __first2,
0212 _ForwardIterator2 __last2,
0213 _BinaryPredicate __pred) {
0214 return std::__find_end_classic(__first1, __last1, __first2, __last2, __pred);
0215 }
0216
0217 template <class _ForwardIterator1, class _ForwardIterator2>
0218 _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1
0219 find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) {
0220 return std::find_end(__first1, __last1, __first2, __last2, __equal_to());
0221 }
0222
0223 _LIBCPP_END_NAMESPACE_STD
0224
0225 #endif