stl_algobase.h

00001 /*
00002  *
00003  * Copyright (c) 1994
00004  * Hewlett-Packard Company
00005  *
00006  * Permission to use, copy, modify, distribute and sell this software
00007  * and its documentation for any purpose is hereby granted without fee,
00008  * provided that the above copyright notice appear in all copies and
00009  * that both that copyright notice and this permission notice appear
00010  * in supporting documentation.  Hewlett-Packard Company makes no
00011  * representations about the suitability of this software for any
00012  * purpose.  It is provided "as is" without express or implied warranty.
00013  *
00014  *
00015  * Copyright (c) 1996-1998
00016  * Silicon Graphics Computer Systems, Inc.
00017  *
00018  * Permission to use, copy, modify, distribute and sell this software
00019  * and its documentation for any purpose is hereby granted without fee,
00020  * provided that the above copyright notice appear in all copies and
00021  * that both that copyright notice and this permission notice appear
00022  * in supporting documentation.  Silicon Graphics makes no
00023  * representations about the suitability of this software for any
00024  * purpose.  It is provided "as is" without express or implied warranty.
00025  */
00026 
00027 /* NOTE: This is an internal header file, included by other STL headers.
00028  *   You should not attempt to use it directly.
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 /* __STL_USE_NEW_IOSTREAMS */
00059 #include <iostream.h>
00060 #endif /* __STL_USE_NEW_IOSTREAMS */
00061 
00062 #else
00063 #include <wce_defs.h>
00064 #endif /* UNDER_CE */
00065 
00066 #ifndef __SGI_STL_INTERNAL_ITERATOR_H
00067 #include <stl_iterator_base.h>
00068 #include <stl_iterator.h>
00069 #endif
00070 
00071 // We pick up concept_checks.h from stl_iterator_base.h.
00072 
00073 __STL_BEGIN_NAMESPACE
00074 
00075 // swap and iter_swap
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 // min and max
00105 
00106 #if !defined(__BORLANDC__) || __BORLANDC__ >= 0x540 /* C++ Builder 4.0 */
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 /* __BORLANDC__ */
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 // copy
00137 
00138 // All of these auxiliary functions serve two purposes.  (1) Replace
00139 // calls to copy with memmove whenever possible.  (Memmove, not memcpy,
00140 // because the input and output ranges are permitted to overlap.)
00141 // (2) If we're using random access iterators, then write the loop as
00142 // a for loop with an explicit count.
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 /* __USLC__ */
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 // Hack for compilers that don't have partial ordering of function templates
00226 // but do have partial specialization of class templates.
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 // Fallback for compilers with neither partial ordering nor partial
00268 // specialization.  Define the faster version for the basic builtin
00269 // types.
00270 #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
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 /* __STL_CLASS_PARTIAL_SPECIALIZATION */
00309 
00310 //--------------------------------------------------
00311 // copy_backward
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 // This dispatch class is a workaround for compilers that do not 
00341 // have partial ordering of function templates.  All we're doing is
00342 // creating a specialization so that we can turn a call to copy_backward
00343 // into a memmove whenever possible.
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 /* __STL_CLASS_PARTIAL_SPECIALIZATION */
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 /* __STL_CLASS_PARTIAL_SPECIALIZATION */
00403 
00404 //--------------------------------------------------
00405 // copy_n (not part of the C++ standard)
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 // fill and fill_n
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 // Specialization: for one-byte types we can use memset.
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 /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */
00504 
00505 //--------------------------------------------------
00506 // equal and mismatch
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 // lexicographical_compare and lexicographical_compare_3way.
00567 // (the latter is not part of the C++ standard.)
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 /* CHAR_MAX == SCHAR_MAX */
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 /* CHAR_MAX == SCHAR_MAX */
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 /* __SGI_STL_INTERNAL_ALGOBASE_H */
00699 
00700 // Local Variables:
00701 // mode:C++
00702 // End:

Generated on Mon Jun 5 10:20:43 2006 for Intelligence.kdevelop by  doxygen 1.4.6