3 * Portions Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
6 * Hewlett-Packard Company
8 * Copyright (c) 1996,1997
9 * Silicon Graphics Computer Systems, Inc.
12 * Moscow Center for SPARC Technology
17 * This material is provided "as is", with absolutely no warranty expressed
18 * or implied. Any use is at your own risk.
20 * Permission to use or copy this software for any purpose is hereby granted
21 * without fee, provided the above notices are retained on all copies.
22 * Permission to modify the code and to distribute modified code is granted,
23 * provided the above notices are retained, and a notice that the code was
24 * modified is included with the above copyright notice.
27 #ifndef _STLP_ALGOBASE_C
28 #define _STLP_ALGOBASE_C
30 #ifndef _STLP_INTERNAL_ALGOBASE_H
31 # include <stl/_algobase.h>
36 template <class _InputIter1, class _InputIter2>
37 bool lexicographical_compare(_InputIter1 __first1, _InputIter1 __last1,
38 _InputIter2 __first2, _InputIter2 __last2) {
39 _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first1, __last1))
40 _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first2, __last2))
41 for ( ; __first1 != __last1 && __first2 != __last2
42 ; ++__first1, ++__first2) {
43 if (*__first1 < *__first2) {
46 if (*__first2 < *__first1)
49 return __first1 == __last1 && __first2 != __last2;
52 template <class _InputIter1, class _InputIter2, class _Compare>
53 bool lexicographical_compare(_InputIter1 __first1, _InputIter1 __last1,
54 _InputIter2 __first2, _InputIter2 __last2,
56 _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first1, __last1))
57 _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first2, __last2))
58 for ( ; __first1 != __last1 && __first2 != __last2
59 ; ++__first1, ++__first2) {
60 if (__comp(*__first1, *__first2)) {
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 __p1(__first2);
234 if ( ++__p1 == __last2 ) {
235 while (__first1 != __last1 && !__pred(*__first1, *__first2)) {
243 for ( ; ; ) { // __first1 != __last1 will be checked below
244 while (__first1 != __last1 && !__pred(*__first1, *__first2)) {
247 if (__first1 == __last1) {
250 _ForwardIter2 __p = __p1;
251 _ForwardIter1 __current = __first1;
252 if (++__current == __last1) return __last1;
254 while (__pred(*__current, *__p)) {
255 if (++__p == __last2)
257 if (++__current == __last1)
266 _STLP_MOVE_TO_PRIV_NAMESPACE
268 // find_first_of, with and without an explicitly supplied comparison function.
269 template <class _InputIter, class _ForwardIter, class _BinaryPredicate>
270 _InputIter __find_first_of(_InputIter __first1, _InputIter __last1,
271 _ForwardIter __first2, _ForwardIter __last2,
272 _BinaryPredicate __comp) {
273 for ( ; __first1 != __last1; ++__first1) {
274 for (_ForwardIter __iter = __first2; __iter != __last2; ++__iter) {
275 if (__comp(*__first1, *__iter)) {
283 // find_end, with and without an explicitly supplied comparison function.
284 // Search [first2, last2) as a subsequence in [first1, last1), and return
285 // the *last* possible match. Note that find_end for bidirectional iterators
286 // is much faster than for forward iterators.
288 // find_end for forward iterators.
289 template <class _ForwardIter1, class _ForwardIter2,
290 class _BinaryPredicate>
291 _ForwardIter1 __find_end(_ForwardIter1 __first1, _ForwardIter1 __last1,
292 _ForwardIter2 __first2, _ForwardIter2 __last2,
293 const forward_iterator_tag &, const forward_iterator_tag &,
294 _BinaryPredicate __comp) {
295 if (__first2 == __last2)
298 _ForwardIter1 __result = __last1;
300 _ForwardIter1 __new_result = search(__first1, __last1, __first2, __last2, __comp);
301 if (__new_result == __last1)
304 __result = __new_result;
305 __first1 = __new_result;
312 _STLP_MOVE_TO_STD_NAMESPACE
314 // find_end for bidirectional iterators. Requires partial specialization.
315 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
317 # ifndef _STLP_INTERNAL_ITERATOR_H
319 # include <stl/_iterator.h>
320 _STLP_BEGIN_NAMESPACE
321 # endif /*_STLP_INTERNAL_ITERATOR_H*/
323 _STLP_MOVE_TO_PRIV_NAMESPACE
325 template <class _BidirectionalIter1, class _BidirectionalIter2,
326 class _BinaryPredicate>
328 __find_end(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1,
329 _BidirectionalIter2 __first2, _BidirectionalIter2 __last2,
330 const bidirectional_iterator_tag &, const bidirectional_iterator_tag &,
331 _BinaryPredicate __comp) {
332 typedef reverse_iterator<_BidirectionalIter1> _RevIter1;
333 typedef reverse_iterator<_BidirectionalIter2> _RevIter2;
335 _RevIter1 __rlast1(__first1);
336 _RevIter2 __rlast2(__first2);
337 _RevIter1 __rresult = search(_RevIter1(__last1), __rlast1,
338 _RevIter2(__last2), __rlast2,
341 if (__rresult == __rlast1)
344 _BidirectionalIter1 __result = __rresult.base();
345 advance(__result, -distance(__first2, __last2));
350 _STLP_MOVE_TO_STD_NAMESPACE
351 #endif /* _STLP_CLASS_PARTIAL_SPECIALIZATION */
353 template <class _ForwardIter1, class _ForwardIter2,
354 class _BinaryPredicate>
356 find_end(_ForwardIter1 __first1, _ForwardIter1 __last1,
357 _ForwardIter2 __first2, _ForwardIter2 __last2,
358 _BinaryPredicate __comp) {
359 _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first1, __last1))
360 _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first2, __last2))
361 return _STLP_PRIV __find_end(__first1, __last1, __first2, __last2,
362 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
363 _STLP_ITERATOR_CATEGORY(__first1, _ForwardIter1),
364 _STLP_ITERATOR_CATEGORY(__first2, _ForwardIter2),
366 forward_iterator_tag(),
367 forward_iterator_tag(),
372 _STLP_MOVE_TO_PRIV_NAMESPACE
374 template <class _ForwardIter, class _Tp, class _Compare1, class _Compare2, class _Distance>
375 _ForwardIter __lower_bound(_ForwardIter __first, _ForwardIter __last, const _Tp& __val,
376 _Compare1 __comp1, _Compare2 __comp2, _Distance*) {
377 _Distance __len = distance(__first, __last);
379 _ForwardIter __middle;
384 advance(__middle, __half);
385 if (__comp1(*__middle, __val)) {
386 _STLP_VERBOSE_ASSERT(!__comp2(__val, *__middle), _StlMsg_INVALID_STRICT_WEAK_PREDICATE)
389 __len = __len - __half - 1;
394 if (&__comp2) {/* do nothing. to avoid warnings */}
398 _STLP_MOVE_TO_STD_NAMESPACE
402 #endif /* _STLP_ALGOBASE_C */