Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygen_algobase.c
Go to the documentation of this file.
00001 /* 00002 * 00003 * Copyright (c) 1994 00004 * Hewlett-Packard Company 00005 * 00006 * Copyright (c) 1996,1997 00007 * Silicon Graphics Computer Systems, Inc. 00008 * 00009 * Copyright (c) 1997 00010 * Moscow Center for SPARC Technology 00011 * 00012 * Copyright (c) 1999 00013 * Boris Fomitchev 00014 * 00015 * This material is provided "as is", with absolutely no warranty expressed 00016 * or implied. Any use is at your own risk. 00017 * 00018 * Permission to use or copy this software for any purpose is hereby granted 00019 * without fee, provided the above notices are retained on all copies. 00020 * Permission to modify the code and to distribute modified code is granted, 00021 * provided the above notices are retained, and a notice that the code was 00022 * modified is included with the above copyright notice. 00023 * 00024 */ 00025 #ifndef _STLP_ALGOBASE_C 00026 #define _STLP_ALGOBASE_C 00027 00028 #ifndef _STLP_INTERNAL_ALGOBASE_H 00029 # include <stl/_algobase.h> 00030 #endif 00031 00032 #ifndef _STLP_INTERNAL_FUNCTION_BASE_H 00033 # include <stl/_function_base.h> 00034 #endif 00035 00036 _STLP_BEGIN_NAMESPACE 00037 00038 template <class _InputIter1, class _InputIter2> 00039 bool lexicographical_compare(_InputIter1 __first1, _InputIter1 __last1, 00040 _InputIter2 __first2, _InputIter2 __last2) { 00041 _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first1, __last1)) 00042 _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first2, __last2)) 00043 for ( ; __first1 != __last1 && __first2 != __last2 00044 ; ++__first1, ++__first2) { 00045 if (*__first1 < *__first2) { 00046 _STLP_VERBOSE_ASSERT(!(*__first2 < *__first1), _StlMsg_INVALID_STRICT_WEAK_PREDICATE) 00047 return true; 00048 } 00049 if (*__first2 < *__first1) 00050 return false; 00051 } 00052 return __first1 == __last1 && __first2 != __last2; 00053 } 00054 00055 template <class _InputIter1, class _InputIter2, class _Compare> 00056 bool lexicographical_compare(_InputIter1 __first1, _InputIter1 __last1, 00057 _InputIter2 __first2, _InputIter2 __last2, 00058 _Compare __comp) { 00059 _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first1, __last1)) 00060 _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first2, __last2)) 00061 for ( ; __first1 != __last1 && __first2 != __last2 00062 ; ++__first1, ++__first2) { 00063 if (__comp(*__first1, *__first2)) { 00064 _STLP_VERBOSE_ASSERT(!__comp(*__first2, *__first1), 00065 _StlMsg_INVALID_STRICT_WEAK_PREDICATE) 00066 return true; 00067 } 00068 if (__comp(*__first2, *__first1)) 00069 return false; 00070 } 00071 return __first1 == __last1 && __first2 != __last2; 00072 } 00073 00074 #if !defined (_STLP_NO_EXTENSIONS) 00075 _STLP_MOVE_TO_PRIV_NAMESPACE 00076 00077 template <class _InputIter1, class _InputIter2> 00078 int __lexicographical_compare_3way(_InputIter1 __first1, _InputIter1 __last1, 00079 _InputIter2 __first2, _InputIter2 __last2) { 00080 while (__first1 != __last1 && __first2 != __last2) { 00081 if (*__first1 < *__first2) { 00082 _STLP_VERBOSE_ASSERT(!(*__first2 < *__first1), _StlMsg_INVALID_STRICT_WEAK_PREDICATE) 00083 return -1; 00084 } 00085 if (*__first2 < *__first1) 00086 return 1; 00087 ++__first1; 00088 ++__first2; 00089 } 00090 if (__first2 == __last2) { 00091 return !(__first1 == __last1); 00092 } 00093 else { 00094 return -1; 00095 } 00096 } 00097 00098 _STLP_MOVE_TO_STD_NAMESPACE 00099 00100 template <class _InputIter1, class _InputIter2> 00101 int lexicographical_compare_3way(_InputIter1 __first1, _InputIter1 __last1, 00102 _InputIter2 __first2, _InputIter2 __last2) { 00103 _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first1, __last1)) 00104 _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first2, __last2)) 00105 return _STLP_PRIV __lexicographical_compare_3way(__first1, __last1, __first2, __last2); 00106 } 00107 #endif 00108 00109 _STLP_MOVE_TO_PRIV_NAMESPACE 00110 00111 template <class _RandomAccessIter, class _Tp> 00112 _STLP_INLINE_LOOP _RandomAccessIter __find(_RandomAccessIter __first, _RandomAccessIter __last, 00113 const _Tp& __val, 00114 const random_access_iterator_tag &) { 00115 _STLP_DIFFERENCE_TYPE(_RandomAccessIter) __trip_count = (__last - __first) >> 2; 00116 00117 for ( ; __trip_count > 0 ; --__trip_count) { 00118 if (*__first == __val) return __first; 00119 ++__first; 00120 00121 if (*__first == __val) return __first; 00122 ++__first; 00123 00124 if (*__first == __val) return __first; 00125 ++__first; 00126 00127 if (*__first == __val) return __first; 00128 ++__first; 00129 } 00130 00131 switch (__last - __first) { 00132 case 3: 00133 if (*__first == __val) return __first; 00134 ++__first; 00135 case 2: 00136 if (*__first == __val) return __first; 00137 ++__first; 00138 case 1: 00139 if (*__first == __val) return __first; 00140 //++__first; 00141 case 0: 00142 default: 00143 return __last; 00144 } 00145 } 00146 00147 inline char* 00148 __find(char* __first, char* __last, char __val, const random_access_iterator_tag &) { 00149 void *res = memchr(__first, __val, __last - __first); 00150 return res != 0 ? __STATIC_CAST(char*, res) : __last; 00151 } 00152 inline const char* 00153 __find(const char* __first, const char* __last, char __val, const random_access_iterator_tag &) { 00154 const void *res = memchr(__first, __val, __last - __first); 00155 return res != 0 ? __STATIC_CAST(const char*, res) : __last; 00156 } 00157 00158 template <class _RandomAccessIter, class _Predicate> 00159 _STLP_INLINE_LOOP _RandomAccessIter __find_if(_RandomAccessIter __first, _RandomAccessIter __last, 00160 _Predicate __pred, 00161 const random_access_iterator_tag &) { 00162 _STLP_DIFFERENCE_TYPE(_RandomAccessIter) __trip_count = (__last - __first) >> 2; 00163 00164 for ( ; __trip_count > 0 ; --__trip_count) { 00165 if (__pred(*__first)) return __first; 00166 ++__first; 00167 00168 if (__pred(*__first)) return __first; 00169 ++__first; 00170 00171 if (__pred(*__first)) return __first; 00172 ++__first; 00173 00174 if (__pred(*__first)) return __first; 00175 ++__first; 00176 } 00177 00178 switch(__last - __first) { 00179 case 3: 00180 if (__pred(*__first)) return __first; 00181 ++__first; 00182 case 2: 00183 if (__pred(*__first)) return __first; 00184 ++__first; 00185 case 1: 00186 if (__pred(*__first)) return __first; 00187 //++__first; 00188 case 0: 00189 default: 00190 return __last; 00191 } 00192 } 00193 00194 template <class _InputIter, class _Tp> 00195 _STLP_INLINE_LOOP _InputIter __find(_InputIter __first, _InputIter __last, 00196 const _Tp& __val, 00197 const input_iterator_tag &) { 00198 while (__first != __last && !(*__first == __val)) ++__first; 00199 return __first; 00200 } 00201 00202 template <class _InputIter, class _Predicate> 00203 _STLP_INLINE_LOOP _InputIter __find_if(_InputIter __first, _InputIter __last, 00204 _Predicate __pred, 00205 const input_iterator_tag &) { 00206 while (__first != __last && !__pred(*__first)) 00207 ++__first; 00208 return __first; 00209 } 00210 00211 _STLP_MOVE_TO_STD_NAMESPACE 00212 00213 template <class _InputIter, class _Predicate> 00214 _InputIter find_if(_InputIter __first, _InputIter __last, 00215 _Predicate __pred) { 00216 _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last)) 00217 return _STLP_PRIV __find_if(__first, __last, __pred, _STLP_ITERATOR_CATEGORY(__first, _InputIter)); 00218 } 00219 00220 template <class _InputIter, class _Tp> 00221 _InputIter find(_InputIter __first, _InputIter __last, const _Tp& __val) { 00222 _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last)) 00223 return _STLP_PRIV __find(__first, __last, __val, _STLP_ITERATOR_CATEGORY(__first, _InputIter)); 00224 } 00225 00226 template <class _ForwardIter1, class _ForwardIter2, class _BinaryPred> 00227 _ForwardIter1 search(_ForwardIter1 __first1, _ForwardIter1 __last1, 00228 _ForwardIter2 __first2, _ForwardIter2 __last2, 00229 _BinaryPred __pred) { 00230 _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first1, __last1)) 00231 _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first2, __last2)) 00232 // Test for empty ranges 00233 if (__first1 == __last1 || __first2 == __last2) 00234 return __first1; 00235 00236 // Test for a pattern of length 1. 00237 _ForwardIter2 __p1(__first2); 00238 00239 if ( ++__p1 == __last2 ) { 00240 while (__first1 != __last1 && !__pred(*__first1, *__first2)) { 00241 ++__first1; 00242 } 00243 return __first1; 00244 } 00245 00246 // General case. 00247 00248 for ( ; ; ) { // __first1 != __last1 will be checked below 00249 while (__first1 != __last1 && !__pred(*__first1, *__first2)) { 00250 ++__first1; 00251 } 00252 if (__first1 == __last1) { 00253 return __last1; 00254 } 00255 _ForwardIter2 __p = __p1; 00256 _ForwardIter1 __current = __first1; 00257 if (++__current == __last1) return __last1; 00258 00259 while (__pred(*__current, *__p)) { 00260 if (++__p == __last2) 00261 return __first1; 00262 if (++__current == __last1) 00263 return __last1; 00264 } 00265 ++__first1; 00266 } 00267 return __first1; 00268 } 00269 00270 _STLP_MOVE_TO_PRIV_NAMESPACE 00271 template <class _Tp> 00272 struct _IsCharLikeType 00273 { typedef __false_type _Ret; }; 00274 00275 _STLP_TEMPLATE_NULL struct _IsCharLikeType<char> 00276 { typedef __true_type _Ret; }; 00277 00278 _STLP_TEMPLATE_NULL struct _IsCharLikeType<unsigned char> 00279 { typedef __true_type _Ret; }; 00280 00281 # ifndef _STLP_NO_SIGNED_BUILTINS 00282 _STLP_TEMPLATE_NULL struct _IsCharLikeType<signed char> 00283 { typedef __true_type _Ret; }; 00284 # endif 00285 00286 template <class _Tp1, class _Tp2> 00287 inline bool __stlp_eq(_Tp1 __val1, _Tp2 __val2) 00288 { return __val1 == __val2; } 00289 00290 #if defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER) 00291 template <class _Tp> 00292 inline bool __stlp_eq(_Tp, _Tp) 00293 { return true; } 00294 #endif 00295 00296 template <class _InputIter, class _ForwardIter, class _Tp2, class _Predicate> 00297 inline _InputIter __find_first_of_aux2(_InputIter __first1, _InputIter __last1, 00298 _ForwardIter __first2, _ForwardIter __last2, 00299 _Tp2*, _Predicate __pred, 00300 const __true_type& /* _UseStrcspnLikeAlgo */) { 00301 unsigned char __hints[(UCHAR_MAX + 1) / CHAR_BIT]; 00302 memset(__hints, 0, sizeof(__hints) / sizeof(unsigned char)); 00303 for (; __first2 != __last2; ++__first2) { 00304 unsigned char __tmp = (unsigned char)*__first2; 00305 __hints[__tmp / CHAR_BIT] |= (1 << (__tmp % CHAR_BIT)); 00306 } 00307 00308 for (; __first1 != __last1; ++__first1) { 00309 _Tp2 __tmp = (_Tp2)*__first1; 00310 if (__stlp_eq(*__first1, __tmp) && 00311 __pred((__hints[(unsigned char)__tmp / CHAR_BIT] & (1 << ((unsigned char)__tmp % CHAR_BIT))) != 0)) 00312 break; 00313 } 00314 return __first1; 00315 } 00316 00317 template <class _InputIter, class _ForwardIter, class _Tp2, class _Predicate> 00318 inline _InputIter __find_first_of_aux2(_InputIter __first1, _InputIter __last1, 00319 _ForwardIter __first2, _ForwardIter __last2, 00320 _Tp2* /* __dummy */, _Predicate /* __pred */, 00321 const __false_type& /* _UseStrcspnLikeAlgo */) { 00322 return _STLP_PRIV __find_first_of(__first1, __last1, __first2, __last2, 00323 _STLP_PRIV __equal_to(_STLP_VALUE_TYPE(__first1, _InputIter))); 00324 } 00325 00326 template <class _InputIter, class _ForwardIter, class _Tp1, class _Tp2> 00327 inline _InputIter __find_first_of_aux1(_InputIter __first1, _InputIter __last1, 00328 _ForwardIter __first2, _ForwardIter __last2, 00329 _Tp1* __pt1, _Tp2* __pt2) { 00330 typedef _STLP_TYPENAME _STLP_STD::_IsIntegral<_Tp1>::_Ret _IsIntegral; 00331 typedef _STLP_TYPENAME _STLP_PRIV _IsCharLikeType<_Tp2>::_Ret _IsCharLike; 00332 typedef _STLP_TYPENAME _STLP_STD::_Land2<_IsIntegral, _IsCharLike>::_Ret _UseStrcspnLikeAlgo; 00333 return _STLP_PRIV __find_first_of_aux2(__first1, __last1, 00334 __first2, __last2, 00335 __pt2, _Identity<bool>(), _UseStrcspnLikeAlgo()); 00336 } 00337 00338 template <class _InputIter, class _ForwardIter> 00339 inline _InputIter __find_first_of(_InputIter __first1, _InputIter __last1, 00340 _ForwardIter __first2, _ForwardIter __last2) { 00341 return _STLP_PRIV __find_first_of_aux1(__first1, __last1, __first2, __last2, 00342 _STLP_VALUE_TYPE(__first1, _InputIter), 00343 _STLP_VALUE_TYPE(__first2, _ForwardIter)); 00344 } 00345 00346 // find_first_of, with and without an explicitly supplied comparison function. 00347 template <class _InputIter, class _ForwardIter, class _BinaryPredicate> 00348 _InputIter __find_first_of(_InputIter __first1, _InputIter __last1, 00349 _ForwardIter __first2, _ForwardIter __last2, 00350 _BinaryPredicate __comp) { 00351 for ( ; __first1 != __last1; ++__first1) { 00352 for (_ForwardIter __iter = __first2; __iter != __last2; ++__iter) { 00353 if (__comp(*__first1, *__iter)) { 00354 return __first1; 00355 } 00356 } 00357 } 00358 return __last1; 00359 } 00360 00361 // find_end, with and without an explicitly supplied comparison function. 00362 // Search [first2, last2) as a subsequence in [first1, last1), and return 00363 // the *last* possible match. Note that find_end for bidirectional iterators 00364 // is much faster than for forward iterators. 00365 00366 // find_end for forward iterators. 00367 template <class _ForwardIter1, class _ForwardIter2, 00368 class _BinaryPredicate> 00369 _ForwardIter1 __find_end(_ForwardIter1 __first1, _ForwardIter1 __last1, 00370 _ForwardIter2 __first2, _ForwardIter2 __last2, 00371 const forward_iterator_tag &, const forward_iterator_tag &, 00372 _BinaryPredicate __comp) { 00373 if (__first2 == __last2) 00374 return __last1; 00375 else { 00376 _ForwardIter1 __result = __last1; 00377 for (;;) { 00378 _ForwardIter1 __new_result = _STLP_STD::search(__first1, __last1, __first2, __last2, __comp); 00379 if (__new_result == __last1) 00380 return __result; 00381 else { 00382 __result = __new_result; 00383 __first1 = __new_result; 00384 ++__first1; 00385 } 00386 } 00387 } 00388 } 00389 00390 _STLP_MOVE_TO_STD_NAMESPACE 00391 00392 // find_end for bidirectional iterators. Requires partial specialization. 00393 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) 00394 00395 # ifndef _STLP_INTERNAL_ITERATOR_H 00396 _STLP_END_NAMESPACE 00397 # include <stl/_iterator.h> 00398 _STLP_BEGIN_NAMESPACE 00399 # endif /*_STLP_INTERNAL_ITERATOR_H*/ 00400 00401 _STLP_MOVE_TO_PRIV_NAMESPACE 00402 00403 template <class _BidirectionalIter1, class _BidirectionalIter2, 00404 class _BinaryPredicate> 00405 _BidirectionalIter1 00406 __find_end(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1, 00407 _BidirectionalIter2 __first2, _BidirectionalIter2 __last2, 00408 const bidirectional_iterator_tag &, const bidirectional_iterator_tag &, 00409 _BinaryPredicate __comp) { 00410 typedef _STLP_STD::reverse_iterator<_BidirectionalIter1> _RevIter1; 00411 typedef _STLP_STD::reverse_iterator<_BidirectionalIter2> _RevIter2; 00412 00413 _RevIter1 __rlast1(__first1); 00414 _RevIter2 __rlast2(__first2); 00415 _RevIter1 __rresult = _STLP_STD::search(_RevIter1(__last1), __rlast1, 00416 _RevIter2(__last2), __rlast2, 00417 __comp); 00418 00419 if (__rresult == __rlast1) 00420 return __last1; 00421 else { 00422 _BidirectionalIter1 __result = __rresult.base(); 00423 _STLP_STD::advance(__result, -_STLP_STD::distance(__first2, __last2)); 00424 return __result; 00425 } 00426 } 00427 00428 _STLP_MOVE_TO_STD_NAMESPACE 00429 #endif /* _STLP_CLASS_PARTIAL_SPECIALIZATION */ 00430 00431 template <class _ForwardIter1, class _ForwardIter2, 00432 class _BinaryPredicate> 00433 _ForwardIter1 00434 find_end(_ForwardIter1 __first1, _ForwardIter1 __last1, 00435 _ForwardIter2 __first2, _ForwardIter2 __last2, 00436 _BinaryPredicate __comp) { 00437 _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first1, __last1)) 00438 _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first2, __last2)) 00439 return _STLP_PRIV __find_end(__first1, __last1, __first2, __last2, 00440 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) 00441 _STLP_ITERATOR_CATEGORY(__first1, _ForwardIter1), 00442 _STLP_ITERATOR_CATEGORY(__first2, _ForwardIter2), 00443 #else 00444 forward_iterator_tag(), 00445 forward_iterator_tag(), 00446 #endif 00447 __comp); 00448 } 00449 00450 _STLP_MOVE_TO_PRIV_NAMESPACE 00451 00452 template <class _ForwardIter, class _Tp, class _Compare1, class _Compare2, class _Distance> 00453 _ForwardIter __lower_bound(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, 00454 _Compare1 __comp1, _Compare2 __comp2, _Distance*) { 00455 _Distance __len = _STLP_STD::distance(__first, __last); 00456 _Distance __half; 00457 _ForwardIter __middle; 00458 00459 while (__len > 0) { 00460 __half = __len >> 1; 00461 __middle = __first; 00462 _STLP_STD::advance(__middle, __half); 00463 if (__comp1(*__middle, __val)) { 00464 _STLP_VERBOSE_ASSERT(!__comp2(__val, *__middle), _StlMsg_INVALID_STRICT_WEAK_PREDICATE) 00465 __first = __middle; 00466 ++__first; 00467 __len = __len - __half - 1; 00468 } 00469 else 00470 __len = __half; 00471 } 00472 return __first; 00473 } 00474 00475 _STLP_MOVE_TO_STD_NAMESPACE 00476 00477 _STLP_END_NAMESPACE 00478 00479 #endif /* _STLP_ALGOBASE_C */ 00480 00481 // Local Variables: 00482 // mode:C++ 00483 // End: Generated on Sun May 27 2012 04:28:48 for ReactOS by
1.7.6.1
|