00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifndef _STLP_INTERNAL_ALGOBASE_H
00032 #define _STLP_INTERNAL_ALGOBASE_H
00033
00034 # if ! defined (_STLP_CSTDDEF)
00035 # include <cstddef>
00036 # endif
00037
00038 #ifndef _STLP_CSTRING
00039 # include <cstring>
00040 #endif
00041
00042 #ifndef _STLP_CLIMITS
00043 # include <climits>
00044 #endif
00045
00046 # if ! defined (_STLP_CSTDLIB)
00047 # include <cstdlib>
00048 # endif
00049
00050 # ifndef _STLP_INTERNAL_PAIR_H
00051 # include <stl/_pair.h>
00052 # endif
00053
00054 #ifndef _STLP_INTERNAL_ITERATOR_BASE_H
00055 # include <stl/_iterator_base.h>
00056 #endif
00057
00058 _STLP_BEGIN_NAMESPACE
00059
00060 template <class _Tp>
00061 inline void swap(_Tp& __a, _Tp& __b) {
00062 _Tp __tmp = __a;
00063 __a = __b;
00064 __b = __tmp;
00065 }
00066
00067 template <class _ForwardIter1, class _ForwardIter2>
00068 inline void iter_swap(_ForwardIter1 __i1, _ForwardIter2 __i2) {
00069 swap(*__i1, *__i2);
00070 }
00071
00072
00073
00074
00075 # if !defined (__BORLANDC__) || defined (_STLP_USE_OWN_NAMESPACE)
00076 template <class _Tp>
00077 inline const _Tp& (min)(const _Tp& __a, const _Tp& __b) { return __b < __a ? __b : __a; }
00078 template <class _Tp>
00079 inline const _Tp& (max)(const _Tp& __a, const _Tp& __b) { return __a < __b ? __b : __a; }
00080 #endif
00081
00082 # if defined (__BORLANDC__) && ( __BORLANDC__ < 0x530 || defined (_STLP_USE_OWN_NAMESPACE))
00083 inline unsigned long (min) (unsigned long __a, unsigned long __b) { return __b < __a ? __b : __a; }
00084 inline unsigned long (max) (unsigned long __a, unsigned long __b) { return __a < __b ? __b : __a; }
00085 # endif
00086
00087 template <class _Tp, class _Compare>
00088 inline const _Tp& (min)(const _Tp& __a, const _Tp& __b, _Compare __comp) {
00089 return __comp(__b, __a) ? __b : __a;
00090 }
00091
00092 template <class _Tp, class _Compare>
00093 inline const _Tp& (max)(const _Tp& __a, const _Tp& __b, _Compare __comp) {
00094 return __comp(__a, __b) ? __b : __a;
00095 }
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 template <class _InputIter, class _OutputIter, class _Distance>
00107 inline _OutputIter __copy(_InputIter __first, _InputIter __last,
00108 _OutputIter __result,
00109 const input_iterator_tag &, _Distance*) {
00110 for ( ; __first != __last; ++__result, ++__first)
00111 *__result = *__first;
00112 return __result;
00113 }
00114
00115 # if defined (_STLP_NONTEMPL_BASE_MATCH_BUG)
00116 template <class _InputIter, class _OutputIter, class _Distance>
00117 inline _OutputIter __copy(_InputIter __first, _InputIter __last,
00118 _OutputIter __result, const forward_iterator_tag &, _Distance* ) {
00119 for ( ; __first != __last; ++__result, ++__first)
00120 *__result = *__first;
00121 return __result;
00122 }
00123
00124
00125 template <class _InputIter, class _OutputIter, class _Distance>
00126 inline _OutputIter __copy(_InputIter __first, _InputIter __last,
00127 _OutputIter __result, const bidirectional_iterator_tag &, _Distance* __dis) {
00128 for ( ; __first != __last; ++__result, ++__first)
00129 *__result = *__first;
00130 return __result;
00131 }
00132 # endif
00133
00134 template <class _RandomAccessIter, class _OutputIter, class _Distance>
00135 inline _OutputIter
00136 __copy(_RandomAccessIter __first, _RandomAccessIter __last,
00137 _OutputIter __result, const random_access_iterator_tag &, _Distance*) {
00138 for (_Distance __n = __last - __first; __n > 0; --__n) {
00139 *__result = *__first;
00140 ++__first;
00141 ++__result;
00142 }
00143 return __result;
00144 }
00145
00146 inline void*
00147 __copy_trivial(const void* __first, const void* __last, void* __result) {
00148 return (__last == __first) ? __result :
00149 ((char*)memmove(__result, __first, ((const char*)__last - (const char*)__first))) +
00150 ((const char*)__last - (const char*)__first);
00151 }
00152
00153
00154
00155
00156 template <class _BidirectionalIter1, class _BidirectionalIter2,
00157 class _Distance>
00158 inline _BidirectionalIter2 __copy_backward(_BidirectionalIter1 __first,
00159 _BidirectionalIter1 __last,
00160 _BidirectionalIter2 __result,
00161 const bidirectional_iterator_tag &,
00162 _Distance*)
00163 {
00164 while (__first != __last)
00165 *--__result = *--__last;
00166 return __result;
00167 }
00168
00169 template <class _RandomAccessIter, class _BidirectionalIter, class _Distance>
00170 inline _BidirectionalIter __copy_backward(_RandomAccessIter __first,
00171 _RandomAccessIter __last,
00172 _BidirectionalIter __result,
00173 const random_access_iterator_tag &,
00174 _Distance*)
00175 {
00176 for (_Distance __n = __last - __first; __n > 0; --__n)
00177 *--__result = *--__last;
00178 return __result;
00179 }
00180
00181 inline void*
00182 __copy_trivial_backward(const void* __first, const void* __last, void* __result) {
00183 const ptrdiff_t _Num = (const char*)__last - (const char*)__first;
00184 return (_Num > 0) ? memmove((char*)__result - _Num, __first, _Num) : __result ;
00185 }
00186
00187 template <class _InputIter, class _OutputIter>
00188 inline _OutputIter __copy_ptrs(_InputIter __first, _InputIter __last, _OutputIter __result, const __false_type&) {
00189 return __copy(__first, __last, __result,
00190 _STLP_ITERATOR_CATEGORY(__first, _InputIter),
00191 _STLP_DISTANCE_TYPE(__first, _InputIter));
00192 }
00193 template <class _InputIter, class _OutputIter>
00194 inline _OutputIter __copy_ptrs(_InputIter __first, _InputIter __last, _OutputIter __result, const __true_type&) {
00195
00196
00197 return (_OutputIter)__copy_trivial(__first, __last, __result);
00198 }
00199
00200 template <class _InputIter, class _OutputIter>
00201 inline _OutputIter __copy_aux(_InputIter __first, _InputIter __last, _OutputIter __result, const __true_type&) {
00202 return __copy_ptrs(__first, __last, __result,
00203 _IsOKToMemCpy(_STLP_VALUE_TYPE(__first, _InputIter),
00204 _STLP_VALUE_TYPE(__result, _OutputIter))._Ret());
00205 }
00206
00207 template <class _InputIter, class _OutputIter>
00208 inline _OutputIter __copy_aux(_InputIter __first, _InputIter __last, _OutputIter __result, const __false_type&) {
00209 return __copy(__first, __last, __result,
00210 _STLP_ITERATOR_CATEGORY(__first, _InputIter), _STLP_DISTANCE_TYPE(__first, _InputIter));
00211 }
00212
00213 template <class _InputIter, class _OutputIter>
00214 inline _OutputIter copy(_InputIter __first, _InputIter __last, _OutputIter __result) {
00215 _STLP_DEBUG_CHECK(__check_range(__first, __last))
00216 return __copy_aux(__first, __last, __result, _BothPtrType< _InputIter, _OutputIter> :: _Ret());
00217 }
00218
00219 template <class _InputIter, class _OutputIter>
00220 inline _OutputIter __copy_backward_ptrs(_InputIter __first, _InputIter __last, _OutputIter __result, const __false_type&) {
00221 return __copy_backward(__first, __last, __result, _STLP_ITERATOR_CATEGORY(__first, _InputIter), _STLP_DISTANCE_TYPE(__first, _InputIter));
00222 }
00223 template <class _InputIter, class _OutputIter>
00224 inline _OutputIter __copy_backward_ptrs(_InputIter __first, _InputIter __last, _OutputIter __result, const __true_type&) {
00225 return (_OutputIter)__copy_trivial_backward(__first, __last, __result);
00226 }
00227
00228 template <class _InputIter, class _OutputIter>
00229 inline _OutputIter __copy_backward_aux(_InputIter __first, _InputIter __last, _OutputIter __result, const __false_type&) {
00230 return __copy_backward(__first, __last, __result, _STLP_ITERATOR_CATEGORY(__first,_InputIter), _STLP_DISTANCE_TYPE(__first, _InputIter));
00231 }
00232
00233 template <class _InputIter, class _OutputIter>
00234 inline _OutputIter __copy_backward_aux(_InputIter __first, _InputIter __last, _OutputIter __result, const __true_type&) {
00235 return __copy_backward_ptrs(__first, __last, __result,
00236 _IsOKToMemCpy(_STLP_VALUE_TYPE(__first, _InputIter),
00237 _STLP_VALUE_TYPE(__result, _OutputIter))._Ret());
00238 }
00239
00240 template <class _InputIter, class _OutputIter>
00241 inline _OutputIter copy_backward(_InputIter __first, _InputIter __last, _OutputIter __result) {
00242 _STLP_DEBUG_CHECK(__check_range(__first, __last))
00243 return __copy_backward_aux(__first, __last, __result, _BothPtrType< _InputIter, _OutputIter> :: _Ret() );
00244 }
00245
00246 #if ! defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) && ! defined ( _STLP_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS )
00247 #define _STLP_DECLARE_COPY_TRIVIAL(_Tp) \
00248 inline _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) \
00249 { return (_Tp*)__copy_trivial(__first, __last, __result); } \
00250 inline _Tp* copy_backward(const _Tp* __first, const _Tp* __last, _Tp* __result) \
00251 { return (_Tp*)__copy_trivial_backward(__first, __last, __result); }
00252
00253 _STLP_DECLARE_COPY_TRIVIAL(char)
00254 # ifndef _STLP_NO_SIGNED_BUILTINS
00255 _STLP_DECLARE_COPY_TRIVIAL(signed char)
00256 # endif
00257 _STLP_DECLARE_COPY_TRIVIAL(unsigned char)
00258 _STLP_DECLARE_COPY_TRIVIAL(short)
00259 _STLP_DECLARE_COPY_TRIVIAL(unsigned short)
00260 _STLP_DECLARE_COPY_TRIVIAL(int)
00261 _STLP_DECLARE_COPY_TRIVIAL(unsigned int)
00262 _STLP_DECLARE_COPY_TRIVIAL(long)
00263 _STLP_DECLARE_COPY_TRIVIAL(unsigned long)
00264 #if !defined(_STLP_NO_WCHAR_T) && !defined (_STLP_WCHAR_T_IS_USHORT)
00265 _STLP_DECLARE_COPY_TRIVIAL(wchar_t)
00266 #endif
00267 #ifdef _STLP_LONG_LONG
00268 _STLP_DECLARE_COPY_TRIVIAL(long long)
00269 _STLP_DECLARE_COPY_TRIVIAL(unsigned long long)
00270 #endif
00271 _STLP_DECLARE_COPY_TRIVIAL(float)
00272 _STLP_DECLARE_COPY_TRIVIAL(double)
00273 # ifndef _STLP_NO_LONG_DOUBLE
00274 _STLP_DECLARE_COPY_TRIVIAL(long double)
00275 # endif
00276 #undef _STLP_DECLARE_COPY_TRIVIAL
00277 #endif
00278
00279
00280
00281
00282 template <class _InputIter, class _Size, class _OutputIter>
00283 _STLP_INLINE_LOOP
00284 pair<_InputIter, _OutputIter> __copy_n(_InputIter __first, _Size __count,
00285 _OutputIter __result,
00286 const input_iterator_tag &) {
00287 for ( ; __count > 0; --__count) {
00288 *__result = *__first;
00289 ++__first;
00290 ++__result;
00291 }
00292 return pair<_InputIter, _OutputIter>(__first, __result);
00293 }
00294
00295 template <class _RAIter, class _Size, class _OutputIter>
00296 inline pair<_RAIter, _OutputIter>
00297 __copy_n(_RAIter __first, _Size __count,
00298 _OutputIter __result,
00299 const random_access_iterator_tag &) {
00300 _RAIter __last = __first + __count;
00301 return pair<_RAIter, _OutputIter>(__last, copy(__first, __last, __result));
00302 }
00303
00304 template <class _InputIter, class _Size, class _OutputIter>
00305 inline pair<_InputIter, _OutputIter>
00306 __copy_n(_InputIter __first, _Size __count, _OutputIter __result) {
00307 _STLP_FIX_LITERAL_BUG(__first)
00308 return __copy_n(__first, __count, __result, _STLP_ITERATOR_CATEGORY(__first, _InputIter));
00309 }
00310
00311 template <class _InputIter, class _Size, class _OutputIter>
00312 inline pair<_InputIter, _OutputIter>
00313 copy_n(_InputIter __first, _Size __count, _OutputIter __result) {
00314 _STLP_FIX_LITERAL_BUG(__first)
00315 return __copy_n(__first, __count, __result, _STLP_ITERATOR_CATEGORY(__first, _InputIter));
00316 }
00317
00318
00319
00320
00321
00322 template <class _ForwardIter, class _Tp>
00323 _STLP_INLINE_LOOP
00324 void fill(_ForwardIter __first, _ForwardIter __last, const _Tp& __value) {
00325 _STLP_DEBUG_CHECK(__check_range(__first, __last))
00326 for ( ; __first != __last; ++__first)
00327 *__first = __value;
00328 }
00329
00330 template <class _OutputIter, class _Size, class _Tp>
00331 _STLP_INLINE_LOOP
00332 _OutputIter fill_n(_OutputIter __first, _Size __n, const _Tp& __value) {
00333 _STLP_FIX_LITERAL_BUG(__first)
00334 for ( ; __n > 0; --__n, ++__first)
00335 *__first = __value;
00336 return __first;
00337 }
00338
00339
00340
00341
00342 inline void fill(unsigned char* __first, unsigned char* __last,
00343 const unsigned char& __value) {
00344 unsigned char __tmp = __value;
00345 memset(__first, __tmp, __last - __first);
00346 }
00347 # ifndef _STLP_NO_SIGNED_BUILTINS
00348 inline void fill(signed char* __first, signed char* __last,
00349 const signed char& __value) {
00350 signed char __tmp = __value;
00351 memset(__first, __STATIC_CAST(unsigned char,__tmp), __last - __first);
00352 }
00353 # endif
00354 inline void fill(char* __first, char* __last, const char& __value) {
00355 char __tmp = __value;
00356 memset(__first, __STATIC_CAST(unsigned char,__tmp), __last - __first);
00357 }
00358
00359 #ifdef _STLP_FUNCTION_TMPL_PARTIAL_ORDER
00360
00361 template <class _Size>
00362 inline unsigned char* fill_n(unsigned char* __first, _Size __n,
00363 const unsigned char& __value) {
00364 fill(__first, __first + __n, __value);
00365 return __first + __n;
00366 }
00367
00368 template <class _Size>
00369 inline signed char* fill_n(char* __first, _Size __n,
00370 const signed char& __value) {
00371 fill(__first, __first + __n, __value);
00372 return __first + __n;
00373 }
00374
00375 template <class _Size>
00376 inline char* fill_n(char* __first, _Size __n, const char& __value) {
00377 fill(__first, __first + __n, __value);
00378 return __first + __n;
00379 }
00380
00381 #endif
00382
00383
00384
00385
00386
00387 template <class _InputIter1, class _InputIter2>
00388 _STLP_INLINE_LOOP
00389 pair<_InputIter1, _InputIter2> mismatch(_InputIter1 __first1,
00390 _InputIter1 __last1,
00391 _InputIter2 __first2) {
00392 _STLP_FIX_LITERAL_BUG(__first2)
00393 _STLP_DEBUG_CHECK(__check_range(__first1, __last1))
00394 while (__first1 != __last1 && *__first1 == *__first2) {
00395 ++__first1;
00396 ++__first2;
00397 }
00398 return pair<_InputIter1, _InputIter2>(__first1, __first2);
00399 }
00400
00401 template <class _InputIter1, class _InputIter2, class _BinaryPredicate>
00402 _STLP_INLINE_LOOP
00403 pair<_InputIter1, _InputIter2> mismatch(_InputIter1 __first1,
00404 _InputIter1 __last1,
00405 _InputIter2 __first2,
00406 _BinaryPredicate __binary_pred) {
00407 _STLP_FIX_LITERAL_BUG(__first2)
00408 _STLP_DEBUG_CHECK(__check_range(__first1, __last1))
00409 while (__first1 != __last1 && __binary_pred(*__first1, *__first2)) {
00410 ++__first1;
00411 ++__first2;
00412 }
00413 return pair<_InputIter1, _InputIter2>(__first1, __first2);
00414 }
00415
00416 template <class _InputIter1, class _InputIter2>
00417 _STLP_INLINE_LOOP
00418 bool equal(_InputIter1 __first1, _InputIter1 __last1,
00419 _InputIter2 __first2) {
00420 _STLP_FIX_LITERAL_BUG(__first1) _STLP_FIX_LITERAL_BUG(__last1) _STLP_FIX_LITERAL_BUG(__first2)
00421 _STLP_DEBUG_CHECK(__check_range(__first1, __last1))
00422 for ( ; __first1 != __last1; ++__first1, ++__first2)
00423 if (!(*__first1 == *__first2))
00424 return false;
00425 return true;
00426 }
00427
00428 template <class _InputIter1, class _InputIter2, class _BinaryPredicate>
00429 _STLP_INLINE_LOOP
00430 bool equal(_InputIter1 __first1, _InputIter1 __last1,
00431 _InputIter2 __first2, _BinaryPredicate __binary_pred) {
00432 _STLP_FIX_LITERAL_BUG(__first2)
00433 _STLP_DEBUG_CHECK(__check_range(__first1, __last1))
00434 for ( ; __first1 != __last1; ++__first1, ++__first2)
00435 if (!__binary_pred(*__first1, *__first2))
00436 return false;
00437 return true;
00438 }
00439
00440
00441
00442
00443
00444 template <class _InputIter1, class _InputIter2>
00445 bool lexicographical_compare(_InputIter1 __first1, _InputIter1 __last1,
00446 _InputIter2 __first2, _InputIter2 __last2);
00447
00448 template <class _InputIter1, class _InputIter2, class _Compare>
00449 bool lexicographical_compare(_InputIter1 __first1, _InputIter1 __last1,
00450 _InputIter2 __first2, _InputIter2 __last2,
00451 _Compare __comp);
00452
00453 inline bool
00454 lexicographical_compare(const unsigned char* __first1,
00455 const unsigned char* __last1,
00456 const unsigned char* __first2,
00457 const unsigned char* __last2)
00458 {
00459 const size_t __len1 = __last1 - __first1;
00460 const size_t __len2 = __last2 - __first2;
00461 _STLP_DEBUG_CHECK(__check_range(__first1, __last1))
00462 _STLP_DEBUG_CHECK(__check_range(__first2, __last2))
00463
00464 const int __result = memcmp(__first1, __first2, (min) (__len1, __len2));
00465 return __result != 0 ? (__result < 0) : (__len1 < __len2);
00466 }
00467
00468
00469 # if !(CHAR_MAX == SCHAR_MAX)
00470 inline bool lexicographical_compare(const char* __first1, const char* __last1,
00471 const char* __first2, const char* __last2)
00472 {
00473 _STLP_DEBUG_CHECK(__check_range(__first1, __last1))
00474 _STLP_DEBUG_CHECK(__check_range(__first2, __last2))
00475
00476 return lexicographical_compare((const unsigned char*) __first1,
00477 (const unsigned char*) __last1,
00478 (const unsigned char*) __first2,
00479 (const unsigned char*) __last2);
00480 }
00481 #endif
00482
00483 template <class _InputIter1, class _InputIter2>
00484 int __lexicographical_compare_3way(_InputIter1 __first1, _InputIter1 __last1,
00485 _InputIter2 __first2, _InputIter2 __last2);
00486
00487 inline int
00488 __lexicographical_compare_3way(const unsigned char* __first1,
00489 const unsigned char* __last1,
00490 const unsigned char* __first2,
00491 const unsigned char* __last2)
00492 {
00493 const ptrdiff_t __len1 = __last1 - __first1;
00494 const ptrdiff_t __len2 = __last2 - __first2;
00495 const int __result = memcmp(__first1, __first2, (min) (__len1, __len2));
00496 return __result != 0 ? __result
00497 : (__len1 == __len2 ? 0 : (__len1 < __len2 ? -1 : 1));
00498 }
00499
00500
00501 # if !(CHAR_MAX == SCHAR_MAX)
00502 inline int
00503 __lexicographical_compare_3way(const char* __first1, const char* __last1,
00504 const char* __first2, const char* __last2)
00505 {
00506 return __lexicographical_compare_3way((const unsigned char*) __first1,
00507 (const unsigned char*) __last1,
00508 (const unsigned char*) __first2,
00509 (const unsigned char*) __last2);
00510 }
00511 # endif
00512
00513 # ifndef _STLP_NO_EXTENSIONS
00514
00515 template <class _InputIter1, class _InputIter2>
00516 int lexicographical_compare_3way(_InputIter1 __first1, _InputIter1 __last1,
00517 _InputIter2 __first2, _InputIter2 __last2);
00518
00519 # endif
00520
00521
00522 template <class _InputIter, class _Tp>
00523 _STLP_INLINE_LOOP _STLP_DIFFERENCE_TYPE(_InputIter)
00524 count(_InputIter __first, _InputIter __last, const _Tp& __value) {
00525 _STLP_DEBUG_CHECK(__check_range(__first, __last))
00526 _STLP_DIFFERENCE_TYPE(_InputIter) __n = 0;
00527 for ( ; __first != __last; ++__first)
00528 if (*__first == __value)
00529 ++__n;
00530 return __n;
00531 }
00532
00533
00534 template <class _InputIter, class _Tp>
00535 _InputIter find(_InputIter __first, _InputIter __last, const _Tp& __val);
00536 template <class _InputIter, class _Predicate>
00537 _InputIter find_if(_InputIter __first, _InputIter __last, _Predicate __pred);
00538
00539
00540 template <class _ForwardIter1, class _ForwardIter2, class _BinaryPred>
00541 _ForwardIter1 search(_ForwardIter1 __first1, _ForwardIter1 __last1,
00542 _ForwardIter2 __first2, _ForwardIter2 __last2, _BinaryPred __predicate);
00543
00544
00545 template <class _InputIter, class _ForwardIter, class _BinaryPredicate>
00546 _InputIter __find_first_of(_InputIter __first1, _InputIter __last1,
00547 _ForwardIter __first2, _ForwardIter __last2,
00548 _BinaryPredicate __comp);
00549
00550 template <class _ForwardIter1, class _ForwardIter2,
00551 class _BinaryPredicate>
00552 _ForwardIter1
00553 find_end(_ForwardIter1 __first1, _ForwardIter1 __last1,
00554 _ForwardIter2 __first2, _ForwardIter2 __last2,
00555 _BinaryPredicate __comp);
00556
00557
00558 template <class _ForwardIter, class _Tp>
00559 _STLP_INLINE_LOOP void
00560 replace(_ForwardIter __first, _ForwardIter __last,
00561 const _Tp& __old_value, const _Tp& __new_value) {
00562 _STLP_DEBUG_CHECK(__check_range(__first, __last))
00563 for ( ; __first != __last; ++__first)
00564 if (*__first == __old_value)
00565 *__first = __new_value;
00566 }
00567
00568 template <class _ForwardIter, class _Tp, class _Compare, class _Distance>
00569 _ForwardIter __lower_bound(_ForwardIter __first, _ForwardIter __last,
00570 const _Tp& __val, _Compare __comp, _Distance*);
00571
00572 _STLP_END_NAMESPACE
00573
00574 # if !defined (_STLP_LINK_TIME_INSTANTIATION)
00575 # include <stl/_algobase.c>
00576 # endif
00577
00578 #endif
00579
00580
00581
00582
00583