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
00032 #ifndef __SGI_STL_INTERNAL_ALGOBASE_H
00033 #define __SGI_STL_INTERNAL_ALGOBASE_H
00034
00035 #ifndef __STL_CONFIG_H
00036 #include <stl_config.h>
00037 #endif
00038 #ifndef __SGI_STL_INTERNAL_RELOPS
00039 #include <stl_relops.h>
00040 #endif
00041 #ifndef __SGI_STL_INTERNAL_PAIR_H
00042 #include <stl_pair.h>
00043 #endif
00044 #ifndef __TYPE_TRAITS_H
00045 #include <type_traits.h>
00046 #endif
00047
00048 #include <string.h>
00049 #include <limits.h>
00050 #include <stdlib.h>
00051
00052 #ifndef UNDER_CE
00053 #include <stddef.h>
00054 #include <new.h>
00055
00056 #ifdef __STL_USE_NEW_IOSTREAMS
00057 #include <iosfwd>
00058 #else
00059 #include <iostream.h>
00060 #endif
00061
00062 #else
00063 #include <wce_defs.h>
00064 #endif
00065
00066 #ifndef __SGI_STL_INTERNAL_ITERATOR_H
00067 #include <stl_iterator_base.h>
00068 #include <stl_iterator.h>
00069 #endif
00070
00071
00072
00073 __STL_BEGIN_NAMESPACE
00074
00075
00076
00077 template <class _ForwardIter1, class _ForwardIter2, class _Tp>
00078 inline void __iter_swap(_ForwardIter1 __a, _ForwardIter2 __b, _Tp*) {
00079 _Tp __tmp = *__a;
00080 *__a = *__b;
00081 *__b = __tmp;
00082 }
00083
00084 template <class _ForwardIter1, class _ForwardIter2>
00085 inline void iter_swap(_ForwardIter1 __a, _ForwardIter2 __b) {
00086 __STL_REQUIRES(_ForwardIter1, _Mutable_ForwardIterator);
00087 __STL_REQUIRES(_ForwardIter2, _Mutable_ForwardIterator);
00088 __STL_CONVERTIBLE(typename iterator_traits<_ForwardIter1>::value_type,
00089 typename iterator_traits<_ForwardIter2>::value_type);
00090 __STL_CONVERTIBLE(typename iterator_traits<_ForwardIter2>::value_type,
00091 typename iterator_traits<_ForwardIter1>::value_type);
00092 __iter_swap(__a, __b, __VALUE_TYPE(__a));
00093 }
00094
00095 template <class _Tp>
00096 inline void swap(_Tp& __a, _Tp& __b) {
00097 __STL_REQUIRES(_Tp, _Assignable);
00098 _Tp __tmp = __a;
00099 __a = __b;
00100 __b = __tmp;
00101 }
00102
00103
00104
00105
00106 #if !defined(__BORLANDC__) || __BORLANDC__ >= 0x540
00107
00108 #undef min
00109 #undef max
00110
00111 template <class _Tp>
00112 inline const _Tp& min(const _Tp& __a, const _Tp& __b) {
00113 __STL_REQUIRES(_Tp, _LessThanComparable);
00114 return __b < __a ? __b : __a;
00115 }
00116
00117 template <class _Tp>
00118 inline const _Tp& max(const _Tp& __a, const _Tp& __b) {
00119 __STL_REQUIRES(_Tp, _LessThanComparable);
00120 return __a < __b ? __b : __a;
00121 }
00122
00123 #endif
00124
00125 template <class _Tp, class _Compare>
00126 inline const _Tp& min(const _Tp& __a, const _Tp& __b, _Compare __comp) {
00127 return __comp(__b, __a) ? __b : __a;
00128 }
00129
00130 template <class _Tp, class _Compare>
00131 inline const _Tp& max(const _Tp& __a, const _Tp& __b, _Compare __comp) {
00132 return __comp(__a, __b) ? __b : __a;
00133 }
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 template <class _InputIter, class _OutputIter, class _Distance>
00145 inline _OutputIter __copy(_InputIter __first, _InputIter __last,
00146 _OutputIter __result,
00147 input_iterator_tag, _Distance*)
00148 {
00149 for ( ; __first != __last; ++__result, ++__first)
00150 *__result = *__first;
00151 return __result;
00152 }
00153
00154 template <class _RandomAccessIter, class _OutputIter, class _Distance>
00155 inline _OutputIter
00156 __copy(_RandomAccessIter __first, _RandomAccessIter __last,
00157 _OutputIter __result, random_access_iterator_tag, _Distance*)
00158 {
00159 for (_Distance __n = __last - __first; __n > 0; --__n) {
00160 *__result = *__first;
00161 ++__first;
00162 ++__result;
00163 }
00164 return __result;
00165 }
00166
00167 template <class _Tp>
00168 inline _Tp*
00169 __copy_trivial(const _Tp* __first, const _Tp* __last, _Tp* __result) {
00170 memmove(__result, __first, sizeof(_Tp) * (__last - __first));
00171 return __result + (__last - __first);
00172 }
00173
00174 #if defined(__STL_FUNCTION_TMPL_PARTIAL_ORDER)
00175
00176 template <class _InputIter, class _OutputIter>
00177 inline _OutputIter __copy_aux2(_InputIter __first, _InputIter __last,
00178 _OutputIter __result, __false_type) {
00179 return __copy(__first, __last, __result,
00180 __ITERATOR_CATEGORY(__first),
00181 __DISTANCE_TYPE(__first));
00182 }
00183
00184 template <class _InputIter, class _OutputIter>
00185 inline _OutputIter __copy_aux2(_InputIter __first, _InputIter __last,
00186 _OutputIter __result, __true_type) {
00187 return __copy(__first, __last, __result,
00188 __ITERATOR_CATEGORY(__first),
00189 __DISTANCE_TYPE(__first));
00190 }
00191
00192 #ifndef __USLC__
00193
00194 template <class _Tp>
00195 inline _Tp* __copy_aux2(_Tp* __first, _Tp* __last, _Tp* __result,
00196 __true_type) {
00197 return __copy_trivial(__first, __last, __result);
00198 }
00199
00200 #endif
00201
00202 template <class _Tp>
00203 inline _Tp* __copy_aux2(const _Tp* __first, const _Tp* __last, _Tp* __result,
00204 __true_type) {
00205 return __copy_trivial(__first, __last, __result);
00206 }
00207
00208
00209 template <class _InputIter, class _OutputIter, class _Tp>
00210 inline _OutputIter __copy_aux(_InputIter __first, _InputIter __last,
00211 _OutputIter __result, _Tp*) {
00212 typedef typename __type_traits<_Tp>::has_trivial_assignment_operator
00213 _Trivial;
00214 return __copy_aux2(__first, __last, __result, _Trivial());
00215 }
00216
00217 template <class _InputIter, class _OutputIter>
00218 inline _OutputIter copy(_InputIter __first, _InputIter __last,
00219 _OutputIter __result) {
00220 __STL_REQUIRES(_InputIter, _InputIterator);
00221 __STL_REQUIRES(_OutputIter, _OutputIterator);
00222 return __copy_aux(__first, __last, __result, __VALUE_TYPE(__first));
00223 }
00224
00225
00226
00227 #elif defined(__STL_CLASS_PARTIAL_SPECIALIZATION)
00228
00229 template <class _InputIter, class _OutputIter, class _BoolType>
00230 struct __copy_dispatch {
00231 static _OutputIter copy(_InputIter __first, _InputIter __last,
00232 _OutputIter __result) {
00233 typedef typename iterator_traits<_InputIter>::iterator_category _Category;
00234 typedef typename iterator_traits<_InputIter>::difference_type _Distance;
00235 return __copy(__first, __last, __result, _Category(), (_Distance*) 0);
00236 }
00237 };
00238
00239 template <class _Tp>
00240 struct __copy_dispatch<_Tp*, _Tp*, __true_type>
00241 {
00242 static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) {
00243 return __copy_trivial(__first, __last, __result);
00244 }
00245 };
00246
00247 template <class _Tp>
00248 struct __copy_dispatch<const _Tp*, _Tp*, __true_type>
00249 {
00250 static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) {
00251 return __copy_trivial(__first, __last, __result);
00252 }
00253 };
00254
00255 template <class _InputIter, class _OutputIter>
00256 inline _OutputIter copy(_InputIter __first, _InputIter __last,
00257 _OutputIter __result) {
00258 __STL_REQUIRES(_InputIter, _InputIterator);
00259 __STL_REQUIRES(_OutputIter, _OutputIterator);
00260 typedef typename iterator_traits<_InputIter>::value_type _Tp;
00261 typedef typename __type_traits<_Tp>::has_trivial_assignment_operator
00262 _Trivial;
00263 return __copy_dispatch<_InputIter, _OutputIter, _Trivial>
00264 ::copy(__first, __last, __result);
00265 }
00266
00267
00268
00269
00270 #else
00271
00272 template <class _InputIter, class _OutputIter>
00273 inline _OutputIter copy(_InputIter __first, _InputIter __last,
00274 _OutputIter __result)
00275 {
00276 return __copy(__first, __last, __result,
00277 __ITERATOR_CATEGORY(__first),
00278 __DISTANCE_TYPE(__first));
00279 }
00280
00281 #define __SGI_STL_DECLARE_COPY_TRIVIAL(_Tp) \
00282 inline _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) { \
00283 memmove(__result, __first, sizeof(_Tp) * (__last - __first)); \
00284 return __result + (__last - __first); \
00285 }
00286
00287 __SGI_STL_DECLARE_COPY_TRIVIAL(char)
00288 __SGI_STL_DECLARE_COPY_TRIVIAL(signed char)
00289 __SGI_STL_DECLARE_COPY_TRIVIAL(unsigned char)
00290 __SGI_STL_DECLARE_COPY_TRIVIAL(short)
00291 __SGI_STL_DECLARE_COPY_TRIVIAL(unsigned short)
00292 __SGI_STL_DECLARE_COPY_TRIVIAL(int)
00293 __SGI_STL_DECLARE_COPY_TRIVIAL(unsigned int)
00294 __SGI_STL_DECLARE_COPY_TRIVIAL(long)
00295 __SGI_STL_DECLARE_COPY_TRIVIAL(unsigned long)
00296 #ifdef __STL_HAS_WCHAR_T
00297 __SGI_STL_DECLARE_COPY_TRIVIAL(wchar_t)
00298 #endif
00299 #ifdef _STL_LONG_LONG
00300 __SGI_STL_DECLARE_COPY_TRIVIAL(long long)
00301 __SGI_STL_DECLARE_COPY_TRIVIAL(unsigned long long)
00302 #endif
00303 __SGI_STL_DECLARE_COPY_TRIVIAL(float)
00304 __SGI_STL_DECLARE_COPY_TRIVIAL(double)
00305 __SGI_STL_DECLARE_COPY_TRIVIAL(long double)
00306
00307 #undef __SGI_STL_DECLARE_COPY_TRIVIAL
00308 #endif
00309
00310
00311
00312
00313 template <class _BidirectionalIter1, class _BidirectionalIter2,
00314 class _Distance>
00315 inline _BidirectionalIter2 __copy_backward(_BidirectionalIter1 __first,
00316 _BidirectionalIter1 __last,
00317 _BidirectionalIter2 __result,
00318 bidirectional_iterator_tag,
00319 _Distance*)
00320 {
00321 while (__first != __last)
00322 *--__result = *--__last;
00323 return __result;
00324 }
00325
00326 template <class _RandomAccessIter, class _BidirectionalIter, class _Distance>
00327 inline _BidirectionalIter __copy_backward(_RandomAccessIter __first,
00328 _RandomAccessIter __last,
00329 _BidirectionalIter __result,
00330 random_access_iterator_tag,
00331 _Distance*)
00332 {
00333 for (_Distance __n = __last - __first; __n > 0; --__n)
00334 *--__result = *--__last;
00335 return __result;
00336 }
00337
00338 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
00339
00340
00341
00342
00343
00344
00345 template <class _BidirectionalIter1, class _BidirectionalIter2,
00346 class _BoolType>
00347 struct __copy_backward_dispatch
00348 {
00349 typedef typename iterator_traits<_BidirectionalIter1>::iterator_category
00350 _Cat;
00351 typedef typename iterator_traits<_BidirectionalIter1>::difference_type
00352 _Distance;
00353
00354 static _BidirectionalIter2 copy(_BidirectionalIter1 __first,
00355 _BidirectionalIter1 __last,
00356 _BidirectionalIter2 __result) {
00357 return __copy_backward(__first, __last, __result, _Cat(), (_Distance*) 0);
00358 }
00359 };
00360
00361 template <class _Tp>
00362 struct __copy_backward_dispatch<_Tp*, _Tp*, __true_type>
00363 {
00364 static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) {
00365 const ptrdiff_t _Num = __last - __first;
00366 memmove(__result - _Num, __first, sizeof(_Tp) * _Num);
00367 return __result - _Num;
00368 }
00369 };
00370
00371 template <class _Tp>
00372 struct __copy_backward_dispatch<const _Tp*, _Tp*, __true_type>
00373 {
00374 static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) {
00375 return __copy_backward_dispatch<_Tp*, _Tp*, __true_type>
00376 ::copy(__first, __last, __result);
00377 }
00378 };
00379
00380 template <class _BI1, class _BI2>
00381 inline _BI2 copy_backward(_BI1 __first, _BI1 __last, _BI2 __result) {
00382 __STL_REQUIRES(_BI1, _BidirectionalIterator);
00383 __STL_REQUIRES(_BI2, _Mutable_BidirectionalIterator);
00384 __STL_CONVERTIBLE(typename iterator_traits<_BI1>::value_type,
00385 typename iterator_traits<_BI2>::value_type);
00386 typedef typename __type_traits<typename iterator_traits<_BI2>::value_type>
00387 ::has_trivial_assignment_operator
00388 _Trivial;
00389 return __copy_backward_dispatch<_BI1, _BI2, _Trivial>
00390 ::copy(__first, __last, __result);
00391 }
00392
00393 #else
00394
00395 template <class _BI1, class _BI2>
00396 inline _BI2 copy_backward(_BI1 __first, _BI1 __last, _BI2 __result) {
00397 return __copy_backward(__first, __last, __result,
00398 __ITERATOR_CATEGORY(__first),
00399 __DISTANCE_TYPE(__first));
00400 }
00401
00402 #endif
00403
00404
00405
00406
00407 template <class _InputIter, class _Size, class _OutputIter>
00408 pair<_InputIter, _OutputIter> __copy_n(_InputIter __first, _Size __count,
00409 _OutputIter __result,
00410 input_iterator_tag) {
00411 for ( ; __count > 0; --__count) {
00412 *__result = *__first;
00413 ++__first;
00414 ++__result;
00415 }
00416 return pair<_InputIter, _OutputIter>(__first, __result);
00417 }
00418
00419 template <class _RAIter, class _Size, class _OutputIter>
00420 inline pair<_RAIter, _OutputIter>
00421 __copy_n(_RAIter __first, _Size __count,
00422 _OutputIter __result,
00423 random_access_iterator_tag) {
00424 _RAIter __last = __first + __count;
00425 return pair<_RAIter, _OutputIter>(__last, copy(__first, __last, __result));
00426 }
00427
00428 template <class _InputIter, class _Size, class _OutputIter>
00429 inline pair<_InputIter, _OutputIter>
00430 __copy_n(_InputIter __first, _Size __count, _OutputIter __result) {
00431 return __copy_n(__first, __count, __result,
00432 __ITERATOR_CATEGORY(__first));
00433 }
00434
00435 template <class _InputIter, class _Size, class _OutputIter>
00436 inline pair<_InputIter, _OutputIter>
00437 copy_n(_InputIter __first, _Size __count, _OutputIter __result) {
00438 __STL_REQUIRES(_InputIter, _InputIterator);
00439 __STL_REQUIRES(_OutputIter, _OutputIterator);
00440 return __copy_n(__first, __count, __result);
00441 }
00442
00443
00444
00445
00446
00447 template <class _ForwardIter, class _Tp>
00448 void fill(_ForwardIter __first, _ForwardIter __last, const _Tp& __value) {
00449 __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator);
00450 for ( ; __first != __last; ++__first)
00451 *__first = __value;
00452 }
00453
00454 template <class _OutputIter, class _Size, class _Tp>
00455 _OutputIter fill_n(_OutputIter __first, _Size __n, const _Tp& __value) {
00456 __STL_REQUIRES(_OutputIter, _OutputIterator);
00457 for ( ; __n > 0; --__n, ++__first)
00458 *__first = __value;
00459 return __first;
00460 }
00461
00462
00463
00464 inline void fill(unsigned char* __first, unsigned char* __last,
00465 const unsigned char& __c) {
00466 unsigned char __tmp = __c;
00467 memset(__first, __tmp, __last - __first);
00468 }
00469
00470 inline void fill(signed char* __first, signed char* __last,
00471 const signed char& __c) {
00472 signed char __tmp = __c;
00473 memset(__first, static_cast<unsigned char>(__tmp), __last - __first);
00474 }
00475
00476 inline void fill(char* __first, char* __last, const char& __c) {
00477 char __tmp = __c;
00478 memset(__first, static_cast<unsigned char>(__tmp), __last - __first);
00479 }
00480
00481 #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
00482
00483 template <class _Size>
00484 inline unsigned char* fill_n(unsigned char* __first, _Size __n,
00485 const unsigned char& __c) {
00486 fill(__first, __first + __n, __c);
00487 return __first + __n;
00488 }
00489
00490 template <class _Size>
00491 inline signed char* fill_n(char* __first, _Size __n,
00492 const signed char& __c) {
00493 fill(__first, __first + __n, __c);
00494 return __first + __n;
00495 }
00496
00497 template <class _Size>
00498 inline char* fill_n(char* __first, _Size __n, const char& __c) {
00499 fill(__first, __first + __n, __c);
00500 return __first + __n;
00501 }
00502
00503 #endif
00504
00505
00506
00507
00508 template <class _InputIter1, class _InputIter2>
00509 pair<_InputIter1, _InputIter2> mismatch(_InputIter1 __first1,
00510 _InputIter1 __last1,
00511 _InputIter2 __first2) {
00512 __STL_REQUIRES(_InputIter1, _InputIterator);
00513 __STL_REQUIRES(_InputIter2, _InputIterator);
00514 __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type,
00515 _EqualityComparable);
00516 __STL_REQUIRES(typename iterator_traits<_InputIter2>::value_type,
00517 _EqualityComparable);
00518 while (__first1 != __last1 && *__first1 == *__first2) {
00519 ++__first1;
00520 ++__first2;
00521 }
00522 return pair<_InputIter1, _InputIter2>(__first1, __first2);
00523 }
00524
00525 template <class _InputIter1, class _InputIter2, class _BinaryPredicate>
00526 pair<_InputIter1, _InputIter2> mismatch(_InputIter1 __first1,
00527 _InputIter1 __last1,
00528 _InputIter2 __first2,
00529 _BinaryPredicate __binary_pred) {
00530 __STL_REQUIRES(_InputIter1, _InputIterator);
00531 __STL_REQUIRES(_InputIter2, _InputIterator);
00532 while (__first1 != __last1 && __binary_pred(*__first1, *__first2)) {
00533 ++__first1;
00534 ++__first2;
00535 }
00536 return pair<_InputIter1, _InputIter2>(__first1, __first2);
00537 }
00538
00539 template <class _InputIter1, class _InputIter2>
00540 inline bool equal(_InputIter1 __first1, _InputIter1 __last1,
00541 _InputIter2 __first2) {
00542 __STL_REQUIRES(_InputIter1, _InputIterator);
00543 __STL_REQUIRES(_InputIter2, _InputIterator);
00544 __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type,
00545 _EqualityComparable);
00546 __STL_REQUIRES(typename iterator_traits<_InputIter2>::value_type,
00547 _EqualityComparable);
00548 for ( ; __first1 != __last1; ++__first1, ++__first2)
00549 if (*__first1 != *__first2)
00550 return false;
00551 return true;
00552 }
00553
00554 template <class _InputIter1, class _InputIter2, class _BinaryPredicate>
00555 inline bool equal(_InputIter1 __first1, _InputIter1 __last1,
00556 _InputIter2 __first2, _BinaryPredicate __binary_pred) {
00557 __STL_REQUIRES(_InputIter1, _InputIterator);
00558 __STL_REQUIRES(_InputIter2, _InputIterator);
00559 for ( ; __first1 != __last1; ++__first1, ++__first2)
00560 if (!__binary_pred(*__first1, *__first2))
00561 return false;
00562 return true;
00563 }
00564
00565
00566
00567
00568
00569 template <class _InputIter1, class _InputIter2>
00570 bool lexicographical_compare(_InputIter1 __first1, _InputIter1 __last1,
00571 _InputIter2 __first2, _InputIter2 __last2) {
00572 __STL_REQUIRES(_InputIter1, _InputIterator);
00573 __STL_REQUIRES(_InputIter2, _InputIterator);
00574 __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type,
00575 _LessThanComparable);
00576 __STL_REQUIRES(typename iterator_traits<_InputIter2>::value_type,
00577 _LessThanComparable);
00578 for ( ; __first1 != __last1 && __first2 != __last2
00579 ; ++__first1, ++__first2) {
00580 if (*__first1 < *__first2)
00581 return true;
00582 if (*__first2 < *__first1)
00583 return false;
00584 }
00585 return __first1 == __last1 && __first2 != __last2;
00586 }
00587
00588 template <class _InputIter1, class _InputIter2, class _Compare>
00589 bool lexicographical_compare(_InputIter1 __first1, _InputIter1 __last1,
00590 _InputIter2 __first2, _InputIter2 __last2,
00591 _Compare __comp) {
00592 __STL_REQUIRES(_InputIter1, _InputIterator);
00593 __STL_REQUIRES(_InputIter2, _InputIterator);
00594 for ( ; __first1 != __last1 && __first2 != __last2
00595 ; ++__first1, ++__first2) {
00596 if (__comp(*__first1, *__first2))
00597 return true;
00598 if (__comp(*__first2, *__first1))
00599 return false;
00600 }
00601 return __first1 == __last1 && __first2 != __last2;
00602 }
00603
00604 inline bool
00605 lexicographical_compare(const unsigned char* __first1,
00606 const unsigned char* __last1,
00607 const unsigned char* __first2,
00608 const unsigned char* __last2)
00609 {
00610 const size_t __len1 = __last1 - __first1;
00611 const size_t __len2 = __last2 - __first2;
00612 const int __result = memcmp(__first1, __first2, min(__len1, __len2));
00613 return __result != 0 ? __result < 0 : __len1 < __len2;
00614 }
00615
00616 inline bool lexicographical_compare(const char* __first1, const char* __last1,
00617 const char* __first2, const char* __last2)
00618 {
00619 #if CHAR_MAX == SCHAR_MAX
00620 return lexicographical_compare((const signed char*) __first1,
00621 (const signed char*) __last1,
00622 (const signed char*) __first2,
00623 (const signed char*) __last2);
00624 #else
00625 return lexicographical_compare((const unsigned char*) __first1,
00626 (const unsigned char*) __last1,
00627 (const unsigned char*) __first2,
00628 (const unsigned char*) __last2);
00629 #endif
00630 }
00631
00632 template <class _InputIter1, class _InputIter2>
00633 int __lexicographical_compare_3way(_InputIter1 __first1, _InputIter1 __last1,
00634 _InputIter2 __first2, _InputIter2 __last2)
00635 {
00636 while (__first1 != __last1 && __first2 != __last2) {
00637 if (*__first1 < *__first2)
00638 return -1;
00639 if (*__first2 < *__first1)
00640 return 1;
00641 ++__first1;
00642 ++__first2;
00643 }
00644 if (__first2 == __last2) {
00645 return !(__first1 == __last1);
00646 }
00647 else {
00648 return -1;
00649 }
00650 }
00651
00652 inline int
00653 __lexicographical_compare_3way(const unsigned char* __first1,
00654 const unsigned char* __last1,
00655 const unsigned char* __first2,
00656 const unsigned char* __last2)
00657 {
00658 const ptrdiff_t __len1 = __last1 - __first1;
00659 const ptrdiff_t __len2 = __last2 - __first2;
00660 const int __result = memcmp(__first1, __first2, min(__len1, __len2));
00661 return __result != 0 ? __result
00662 : (__len1 == __len2 ? 0 : (__len1 < __len2 ? -1 : 1));
00663 }
00664
00665 inline int
00666 __lexicographical_compare_3way(const char* __first1, const char* __last1,
00667 const char* __first2, const char* __last2)
00668 {
00669 #if CHAR_MAX == SCHAR_MAX
00670 return __lexicographical_compare_3way(
00671 (const signed char*) __first1,
00672 (const signed char*) __last1,
00673 (const signed char*) __first2,
00674 (const signed char*) __last2);
00675 #else
00676 return __lexicographical_compare_3way((const unsigned char*) __first1,
00677 (const unsigned char*) __last1,
00678 (const unsigned char*) __first2,
00679 (const unsigned char*) __last2);
00680 #endif
00681 }
00682
00683 template <class _InputIter1, class _InputIter2>
00684 int lexicographical_compare_3way(_InputIter1 __first1, _InputIter1 __last1,
00685 _InputIter2 __first2, _InputIter2 __last2)
00686 {
00687 __STL_REQUIRES(_InputIter1, _InputIterator);
00688 __STL_REQUIRES(_InputIter2, _InputIterator);
00689 __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type,
00690 _LessThanComparable);
00691 __STL_REQUIRES(typename iterator_traits<_InputIter2>::value_type,
00692 _LessThanComparable);
00693 return __lexicographical_compare_3way(__first1, __last1, __first2, __last2);
00694 }
00695
00696 __STL_END_NAMESPACE
00697
00698 #endif
00699
00700
00701
00702