@@ -80,109 +80,6 @@ _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1>
8080 }
8181}
8282
83- template < class _IterOps ,
84- class _Pred ,
85- class _Iter1 ,
86- class _Sent1 ,
87- class _Iter2 ,
88- class _Sent2 ,
89- class _Proj1 ,
90- class _Proj2 >
91- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter1 __find_end (
92- _Iter1 __first1,
93- _Sent1 __sent1,
94- _Iter2 __first2,
95- _Sent2 __sent2,
96- _Pred& __pred,
97- _Proj1& __proj1,
98- _Proj2& __proj2,
99- bidirectional_iterator_tag,
100- bidirectional_iterator_tag) {
101- auto __last1 = _IterOps::next (__first1, __sent1);
102- auto __last2 = _IterOps::next (__first2, __sent2);
103- // modeled after search algorithm (in reverse)
104- if (__first2 == __last2)
105- return __last1; // Everything matches an empty sequence
106- _Iter1 __l1 = __last1;
107- _Iter2 __l2 = __last2;
108- --__l2;
109- while (true ) {
110- // Find last element in sequence 1 that matchs *(__last2-1), with a mininum of loop checks
111- while (true ) {
112- if (__first1 == __l1) // return __last1 if no element matches *__first2
113- return __last1;
114- if (std::__invoke (__pred, std::__invoke (__proj1, *--__l1), std::__invoke (__proj2, *__l2)))
115- break ;
116- }
117- // *__l1 matches *__l2, now match elements before here
118- _Iter1 __m1 = __l1;
119- _Iter2 __m2 = __l2;
120- while (true ) {
121- if (__m2 == __first2) // If pattern exhausted, __m1 is the answer (works for 1 element pattern)
122- return __m1;
123- if (__m1 == __first1) // Otherwise if source exhaused, pattern not found
124- return __last1;
125-
126- // if there is a mismatch, restart with a new __l1
127- if (!std::__invoke (__pred, std::__invoke (__proj1, *--__m1), std::__invoke (__proj2, *--__m2))) {
128- break ;
129- } // else there is a match, check next elements
130- }
131- }
132- }
133-
134- template < class _AlgPolicy ,
135- class _Pred ,
136- class _Iter1 ,
137- class _Sent1 ,
138- class _Iter2 ,
139- class _Sent2 ,
140- class _Proj1 ,
141- class _Proj2 >
142- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter1 __find_end (
143- _Iter1 __first1,
144- _Sent1 __sent1,
145- _Iter2 __first2,
146- _Sent2 __sent2,
147- _Pred& __pred,
148- _Proj1& __proj1,
149- _Proj2& __proj2,
150- random_access_iterator_tag,
151- random_access_iterator_tag) {
152- typedef typename iterator_traits<_Iter1>::difference_type _D1;
153- auto __last1 = _IterOps<_AlgPolicy>::next (__first1, __sent1);
154- auto __last2 = _IterOps<_AlgPolicy>::next (__first2, __sent2);
155- // Take advantage of knowing source and pattern lengths. Stop short when source is smaller than pattern
156- auto __len2 = __last2 - __first2;
157- if (__len2 == 0 )
158- return __last1;
159- auto __len1 = __last1 - __first1;
160- if (__len1 < __len2)
161- return __last1;
162- const _Iter1 __s = __first1 + _D1 (__len2 - 1 ); // End of pattern match can't go before here
163- _Iter1 __l1 = __last1;
164- _Iter2 __l2 = __last2;
165- --__l2;
166- while (true ) {
167- while (true ) {
168- if (__s == __l1)
169- return __last1;
170- if (std::__invoke (__pred, std::__invoke (__proj1, *--__l1), std::__invoke (__proj2, *__l2)))
171- break ;
172- }
173- _Iter1 __m1 = __l1;
174- _Iter2 __m2 = __l2;
175- while (true ) {
176- if (__m2 == __first2)
177- return __m1;
178- // no need to check range on __m1 because __s guarantees we have enough source
179- if (!std::__invoke (__pred, std::__invoke (__proj1, *--__m1), std::__invoke (*--__m2))) {
180- break ;
181- }
182- }
183- }
184- }
185-
18683template <class _ForwardIterator1 , class _ForwardIterator2 , class _BinaryPredicate >
18784_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator1 __find_end_classic (
18885 _ForwardIterator1 __first1,
0 commit comments