Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

stl_algobase.h

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

Generated at Tue May 1 16:28:39 2001 for libstdc++-v3 by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001