4 * Hewlett-Packard Company
6 * Copyright (c) 1996,1997
7 * Silicon Graphics Computer Systems, Inc.
10 * Moscow Center for SPARC Technology
15 * This material is provided "as is", with absolutely no warranty expressed
16 * or implied. Any use is at your own risk.
18 * Permission to use or copy this software for any purpose is hereby granted
19 * without fee, provided the above notices are retained on all copies.
20 * Permission to modify the code and to distribute modified code is granted,
21 * provided the above notices are retained, and a notice that the code was
22 * modified is included with the above copyright notice.
25 #ifndef _STLP_ALGOBASE_C
26 #define _STLP_ALGOBASE_C
28 #ifndef _STLP_INTERNAL_ALGOBASE_H
29 # include <stl/_algobase.h>
34 template <class _InputIter1, class _InputIter2>
35 bool lexicographical_compare(_InputIter1 __first1, _InputIter1 __last1,
36 _InputIter2 __first2, _InputIter2 __last2) {
37 _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first1, __last1))
38 _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first2, __last2))
39 for ( ; __first1 != __last1 && __first2 != __last2
40 ; ++__first1, ++__first2) {
41 if (*__first1 < *__first2) {
42 _STLP_VERBOSE_ASSERT(!(*__first2 < *__first1), _StlMsg_INVALID_STRICT_WEAK_PREDICATE)
45 if (*__first2 < *__first1)
48 return __first1 == __last1 && __first2 != __last2;
51 template <class _InputIter1, class _InputIter2, class _Compare>
52 bool lexicographical_compare(_InputIter1 __first1, _InputIter1 __last1,
53 _InputIter2 __first2, _InputIter2 __last2,
55 _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first1, __last1))
56 _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first2, __last2))
57 for ( ; __first1 != __last1 && __first2 != __last2
58 ; ++__first1, ++__first2) {
59 if (__comp(*__first1, *__first2)) {
60 _STLP_VERBOSE_ASSERT(!__comp(*__first2, *__first1), _StlMsg_INVALID_STRICT_WEAK_PREDICATE)
63 if (__comp(*__first2, *__first1))
66 return __first1 == __last1 && __first2 != __last2;
69 #if !defined (_STLP_NO_EXTENSIONS)
70 _STLP_MOVE_TO_PRIV_NAMESPACE
72 template <class _InputIter1, class _InputIter2>
73 int __lexicographical_compare_3way(_InputIter1 __first1, _InputIter1 __last1,
74 _InputIter2 __first2, _InputIter2 __last2) {
75 while (__first1 != __last1 && __first2 != __last2) {
76 if (*__first1 < *__first2) {
77 _STLP_VERBOSE_ASSERT(!(*__first2 < *__first1), _StlMsg_INVALID_STRICT_WEAK_PREDICATE)
80 if (*__first2 < *__first1)
85 if (__first2 == __last2) {
86 return !(__first1 == __last1);
93 _STLP_MOVE_TO_STD_NAMESPACE
95 template <class _InputIter1, class _InputIter2>
96 int lexicographical_compare_3way(_InputIter1 __first1, _InputIter1 __last1,
97 _InputIter2 __first2, _InputIter2 __last2) {
98 _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first1, __last1))
99 _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first2, __last2))
100 return _STLP_PRIV __lexicographical_compare_3way(__first1, __last1, __first2, __last2);
104 _STLP_MOVE_TO_PRIV_NAMESPACE
106 template <class _RandomAccessIter, class _Tp>
107 _STLP_INLINE_LOOP _RandomAccessIter __find(_RandomAccessIter __first, _RandomAccessIter __last,
109 const random_access_iterator_tag &) {
110 _STLP_DIFFERENCE_TYPE(_RandomAccessIter) __trip_count = (__last - __first) >> 2;
112 for ( ; __trip_count > 0 ; --__trip_count) {
113 if (*__first == __val) return __first;
116 if (*__first == __val) return __first;
119 if (*__first == __val) return __first;
122 if (*__first == __val) return __first;
126 switch (__last - __first) {
128 if (*__first == __val) return __first;
131 if (*__first == __val) return __first;
134 if (*__first == __val) return __first;
143 __find(char* __first, char* __last, char __val, const random_access_iterator_tag &) {
144 void *res = memchr(__first, __val, __last - __first);
145 return res != 0 ? __STATIC_CAST(char*, res) : __last;
148 __find(const char* __first, const char* __last, char __val, const random_access_iterator_tag &) {
149 const void *res = memchr(__first, __val, __last - __first);
150 return res != 0 ? __STATIC_CAST(const char*, res) : __last;
153 template <class _RandomAccessIter, class _Predicate>
154 _STLP_INLINE_LOOP _RandomAccessIter __find_if(_RandomAccessIter __first, _RandomAccessIter __last,
156 const random_access_iterator_tag &) {
157 _STLP_DIFFERENCE_TYPE(_RandomAccessIter) __trip_count = (__last - __first) >> 2;
159 for ( ; __trip_count > 0 ; --__trip_count) {
160 if (__pred(*__first)) return __first;
163 if (__pred(*__first)) return __first;
166 if (__pred(*__first)) return __first;
169 if (__pred(*__first)) return __first;
173 switch(__last - __first) {
175 if (__pred(*__first)) return __first;
178 if (__pred(*__first)) return __first;
181 if (__pred(*__first)) return __first;
189 template <class _InputIter, class _Tp>
190 _STLP_INLINE_LOOP _InputIter __find(_InputIter __first, _InputIter __last,
192 const input_iterator_tag &) {
193 while (__first != __last && !(*__first == __val)) ++__first;
197 template <class _InputIter, class _Predicate>
198 _STLP_INLINE_LOOP _InputIter __find_if(_InputIter __first, _STLP_MPW_EXTRA_CONST _InputIter __last,
200 const input_iterator_tag &) {
201 while (__first != __last && !__pred(*__first))
206 _STLP_MOVE_TO_STD_NAMESPACE
208 template <class _InputIter, class _Predicate>
209 _InputIter find_if(_InputIter __first, _InputIter __last,
211 _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last))
212 return _STLP_PRIV __find_if(__first, __last, __pred, _STLP_ITERATOR_CATEGORY(__first, _InputIter));
215 template <class _InputIter, class _Tp>
216 _InputIter find(_InputIter __first, _InputIter __last, const _Tp& __val) {
217 _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last))
218 return _STLP_PRIV __find(__first, __last, __val, _STLP_ITERATOR_CATEGORY(__first, _InputIter));
221 template <class _ForwardIter1, class _ForwardIter2, class _BinaryPred>
222 _ForwardIter1 search(_ForwardIter1 __first1, _ForwardIter1 __last1,
223 _ForwardIter2 __first2, _ForwardIter2 __last2,
224 _BinaryPred __pred) {
225 _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first1, __last1))
226 _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first2, __last2))
227 // Test for empty ranges
228 if (__first1 == __last1 || __first2 == __last2)
231 // Test for a pattern of length 1.
232 _ForwardIter2 __tmp(__first2);
234 if (__tmp == __last2) {
235 while (__first1 != __last1 && !__pred(*__first1, *__first2)) {
236 _STLP_VERBOSE_ASSERT(!__pred(*__first2, *__first1), _StlMsg_INVALID_EQUIVALENT_PREDICATE)
239 _STLP_VERBOSE_ASSERT((__first1 == __last1) || __pred(*__first2, *__first1),
240 _StlMsg_INVALID_EQUIVALENT_PREDICATE)
246 _ForwardIter2 __p1, __p;
248 __p1 = __first2; ++__p1;
250 // _ForwardIter1 __current = __first1;
252 while (__first1 != __last1) {
253 while (__first1 != __last1) {
254 if (__pred(*__first1, *__first2)) {
255 _STLP_VERBOSE_ASSERT(__pred(*__first2, *__first1), _StlMsg_INVALID_EQUIVALENT_PREDICATE)
258 _STLP_VERBOSE_ASSERT(!__pred(*__first2, *__first1), _StlMsg_INVALID_EQUIVALENT_PREDICATE)
261 while (__first1 != __last1 && !__pred(*__first1, *__first2)) {
262 _STLP_VERBOSE_ASSERT(!__pred(*__first2, *__first1), _StlMsg_INVALID_EQUIVALENT_PREDICATE)
265 if (__first1 == __last1)
267 _STLP_VERBOSE_ASSERT(__pred(*__first2, *__first1), _StlMsg_INVALID_EQUIVALENT_PREDICATE)
270 _ForwardIter1 __current = __first1;
271 if (++__current == __last1) return __last1;
273 while (__pred(*__current, *__p)) {
274 _STLP_VERBOSE_ASSERT(__pred(*__p, *__current), _StlMsg_INVALID_EQUIVALENT_PREDICATE)
275 if (++__p == __last2)
277 if (++__current == __last1)
281 _STLP_VERBOSE_ASSERT(!__pred(*__p, *__current), _StlMsg_INVALID_EQUIVALENT_PREDICATE)
287 _STLP_MOVE_TO_PRIV_NAMESPACE
289 // find_first_of, with and without an explicitly supplied comparison function.
290 template <class _InputIter, class _ForwardIter, class _BinaryPredicate>
291 _InputIter __find_first_of(_InputIter __first1, _InputIter __last1,
292 _ForwardIter __first2, _ForwardIter __last2,
293 _BinaryPredicate __comp) {
294 for ( ; __first1 != __last1; ++__first1) {
295 for (_ForwardIter __iter = __first2; __iter != __last2; ++__iter) {
296 if (__comp(*__first1, *__iter)) {
297 _STLP_VERBOSE_ASSERT(__comp(*__iter, *__first1), _StlMsg_INVALID_EQUIVALENT_PREDICATE)
300 _STLP_VERBOSE_ASSERT(!__comp(*__iter, *__first1), _StlMsg_INVALID_EQUIVALENT_PREDICATE)
306 // find_end, with and without an explicitly supplied comparison function.
307 // Search [first2, last2) as a subsequence in [first1, last1), and return
308 // the *last* possible match. Note that find_end for bidirectional iterators
309 // is much faster than for forward iterators.
311 // find_end for forward iterators.
312 template <class _ForwardIter1, class _ForwardIter2,
313 class _BinaryPredicate>
314 _ForwardIter1 __find_end(_ForwardIter1 __first1, _ForwardIter1 __last1,
315 _ForwardIter2 __first2, _ForwardIter2 __last2,
316 const forward_iterator_tag &, const forward_iterator_tag &,
317 _BinaryPredicate __comp) {
318 if (__first2 == __last2)
321 _ForwardIter1 __result = __last1;
323 _ForwardIter1 __new_result = search(__first1, __last1, __first2, __last2, __comp);
324 if (__new_result == __last1)
327 __result = __new_result;
328 __first1 = __new_result;
335 _STLP_MOVE_TO_STD_NAMESPACE
337 // find_end for bidirectional iterators. Requires partial specialization.
338 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
340 # ifndef _STLP_INTERNAL_ITERATOR_H
342 # include <stl/_iterator.h>
343 _STLP_BEGIN_NAMESPACE
344 # endif /*_STLP_INTERNAL_ITERATOR_H*/
346 _STLP_MOVE_TO_PRIV_NAMESPACE
348 template <class _BidirectionalIter1, class _BidirectionalIter2,
349 class _BinaryPredicate>
351 __find_end(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1,
352 _BidirectionalIter2 __first2, _BidirectionalIter2 __last2,
353 const bidirectional_iterator_tag &, const bidirectional_iterator_tag &,
354 _BinaryPredicate __comp) {
355 typedef reverse_iterator<_BidirectionalIter1> _RevIter1;
356 typedef reverse_iterator<_BidirectionalIter2> _RevIter2;
358 _RevIter1 __rlast1(__first1);
359 _RevIter2 __rlast2(__first2);
360 _RevIter1 __rresult = search(_RevIter1(__last1), __rlast1,
361 _RevIter2(__last2), __rlast2,
364 if (__rresult == __rlast1)
367 _BidirectionalIter1 __result = __rresult.base();
368 advance(__result, -distance(__first2, __last2));
373 _STLP_MOVE_TO_STD_NAMESPACE
374 #endif /* _STLP_CLASS_PARTIAL_SPECIALIZATION */
376 template <class _ForwardIter1, class _ForwardIter2,
377 class _BinaryPredicate>
379 find_end(_ForwardIter1 __first1, _ForwardIter1 __last1,
380 _ForwardIter2 __first2, _ForwardIter2 __last2,
381 _BinaryPredicate __comp) {
382 _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first1, __last1))
383 _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first2, __last2))
384 return _STLP_PRIV __find_end(__first1, __last1, __first2, __last2,
385 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
386 _STLP_ITERATOR_CATEGORY(__first1, _ForwardIter1),
387 _STLP_ITERATOR_CATEGORY(__first2, _ForwardIter2),
389 forward_iterator_tag(),
390 forward_iterator_tag(),
395 _STLP_MOVE_TO_PRIV_NAMESPACE
397 template <class _ForwardIter, class _Tp, class _Compare1, class _Compare2, class _Distance>
398 _ForwardIter __lower_bound(_ForwardIter __first, _ForwardIter __last, const _Tp& __val,
399 _Compare1 __comp1, _Compare2 __comp2, _Distance*) {
400 _Distance __len = distance(__first, __last);
402 _ForwardIter __middle;
407 advance(__middle, __half);
408 if (__comp1(*__middle, __val)) {
409 _STLP_VERBOSE_ASSERT(!__comp2(__val, *__middle), _StlMsg_INVALID_STRICT_WEAK_PREDICATE)
412 __len = __len - __half - 1;
420 _STLP_MOVE_TO_STD_NAMESPACE
424 #endif /* _STLP_ALGOBASE_C */