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
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 #ifndef _STL_ALGOBASE_H
00058 #define _STL_ALGOBASE_H 1
00059
00060 #include <bits/c++config.h>
00061 #include <cstddef>
00062 #include <bits/functexcept.h>
00063 #include <bits/cpp_type_traits.h>
00064 #include <ext/type_traits.h>
00065 #include <ext/numeric_traits.h>
00066 #include <bits/stl_pair.h>
00067 #include <bits/stl_iterator_base_types.h>
00068 #include <bits/stl_iterator_base_funcs.h>
00069 #include <bits/stl_iterator.h>
00070 #include <bits/concept_check.h>
00071 #include <debug/debug.h>
00072 #include <bits/move.h>
00073
00074 _GLIBCXX_BEGIN_NAMESPACE(std)
00075
00076
00077
00078
00079 template<bool _BoolType>
00080 struct __iter_swap
00081 {
00082 template<typename _ForwardIterator1, typename _ForwardIterator2>
00083 static void
00084 iter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b)
00085 {
00086 typedef typename iterator_traits<_ForwardIterator1>::value_type
00087 _ValueType1;
00088 _ValueType1 __tmp = _GLIBCXX_MOVE(*__a);
00089 *__a = _GLIBCXX_MOVE(*__b);
00090 *__b = _GLIBCXX_MOVE(__tmp);
00091 }
00092 };
00093
00094 template<>
00095 struct __iter_swap<true>
00096 {
00097 template<typename _ForwardIterator1, typename _ForwardIterator2>
00098 static void
00099 iter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b)
00100 {
00101 swap(*__a, *__b);
00102 }
00103 };
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115 template<typename _ForwardIterator1, typename _ForwardIterator2>
00116 inline void
00117 iter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b)
00118 {
00119 typedef typename iterator_traits<_ForwardIterator1>::value_type
00120 _ValueType1;
00121 typedef typename iterator_traits<_ForwardIterator2>::value_type
00122 _ValueType2;
00123
00124
00125 __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
00126 _ForwardIterator1>)
00127 __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
00128 _ForwardIterator2>)
00129 __glibcxx_function_requires(_ConvertibleConcept<_ValueType1,
00130 _ValueType2>)
00131 __glibcxx_function_requires(_ConvertibleConcept<_ValueType2,
00132 _ValueType1>)
00133
00134 typedef typename iterator_traits<_ForwardIterator1>::reference
00135 _ReferenceType1;
00136 typedef typename iterator_traits<_ForwardIterator2>::reference
00137 _ReferenceType2;
00138 std::__iter_swap<__are_same<_ValueType1, _ValueType2>::__value
00139 && __are_same<_ValueType1&, _ReferenceType1>::__value
00140 && __are_same<_ValueType2&, _ReferenceType2>::__value>::
00141 iter_swap(__a, __b);
00142 }
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 template<typename _ForwardIterator1, typename _ForwardIterator2>
00157 _ForwardIterator2
00158 swap_ranges(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
00159 _ForwardIterator2 __first2)
00160 {
00161
00162 __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
00163 _ForwardIterator1>)
00164 __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
00165 _ForwardIterator2>)
00166 __glibcxx_requires_valid_range(__first1, __last1);
00167
00168 for (; __first1 != __last1; ++__first1, ++__first2)
00169 std::iter_swap(__first1, __first2);
00170 return __first2;
00171 }
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184 template<typename _Tp>
00185 inline const _Tp&
00186 min(const _Tp& __a, const _Tp& __b)
00187 {
00188
00189 __glibcxx_function_requires(_LessThanComparableConcept<_Tp>)
00190
00191 if (__b < __a)
00192 return __b;
00193 return __a;
00194 }
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207 template<typename _Tp>
00208 inline const _Tp&
00209 max(const _Tp& __a, const _Tp& __b)
00210 {
00211
00212 __glibcxx_function_requires(_LessThanComparableConcept<_Tp>)
00213
00214 if (__a < __b)
00215 return __b;
00216 return __a;
00217 }
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230 template<typename _Tp, typename _Compare>
00231 inline const _Tp&
00232 min(const _Tp& __a, const _Tp& __b, _Compare __comp)
00233 {
00234
00235 if (__comp(__b, __a))
00236 return __b;
00237 return __a;
00238 }
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251 template<typename _Tp, typename _Compare>
00252 inline const _Tp&
00253 max(const _Tp& __a, const _Tp& __b, _Compare __comp)
00254 {
00255
00256 if (__comp(__a, __b))
00257 return __b;
00258 return __a;
00259 }
00260
00261
00262
00263
00264 template<typename _Iterator, bool _HasBase>
00265 struct _Iter_base
00266 {
00267 typedef _Iterator iterator_type;
00268 static iterator_type
00269 _S_base(_Iterator __it)
00270 { return __it; }
00271 };
00272
00273 template<typename _Iterator>
00274 struct _Iter_base<_Iterator, true>
00275 {
00276 typedef typename _Iterator::iterator_type iterator_type;
00277 static iterator_type
00278 _S_base(_Iterator __it)
00279 { return __it.base(); }
00280 };
00281
00282
00283
00284 template<typename _Iterator>
00285 struct _Niter_base
00286 : _Iter_base<_Iterator, __is_normal_iterator<_Iterator>::__value>
00287 { };
00288
00289 template<typename _Iterator>
00290 inline typename _Niter_base<_Iterator>::iterator_type
00291 __niter_base(_Iterator __it)
00292 { return std::_Niter_base<_Iterator>::_S_base(__it); }
00293
00294
00295 template<typename _Iterator>
00296 struct _Miter_base
00297 : _Iter_base<_Iterator, __is_move_iterator<_Iterator>::__value>
00298 { };
00299
00300 template<typename _Iterator>
00301 inline typename _Miter_base<_Iterator>::iterator_type
00302 __miter_base(_Iterator __it)
00303 { return std::_Miter_base<_Iterator>::_S_base(__it); }
00304
00305
00306
00307
00308
00309
00310
00311 template<bool, bool, typename>
00312 struct __copy_move
00313 {
00314 template<typename _II, typename _OI>
00315 static _OI
00316 __copy_m(_II __first, _II __last, _OI __result)
00317 {
00318 for (; __first != __last; ++__result, ++__first)
00319 *__result = *__first;
00320 return __result;
00321 }
00322 };
00323
00324 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00325 template<typename _Category>
00326 struct __copy_move<true, false, _Category>
00327 {
00328 template<typename _II, typename _OI>
00329 static _OI
00330 __copy_m(_II __first, _II __last, _OI __result)
00331 {
00332 for (; __first != __last; ++__result, ++__first)
00333 *__result = std::move(*__first);
00334 return __result;
00335 }
00336 };
00337 #endif
00338
00339 template<>
00340 struct __copy_move<false, false, random_access_iterator_tag>
00341 {
00342 template<typename _II, typename _OI>
00343 static _OI
00344 __copy_m(_II __first, _II __last, _OI __result)
00345 {
00346 typedef typename iterator_traits<_II>::difference_type _Distance;
00347 for(_Distance __n = __last - __first; __n > 0; --__n)
00348 {
00349 *__result = *__first;
00350 ++__first;
00351 ++__result;
00352 }
00353 return __result;
00354 }
00355 };
00356
00357 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00358 template<>
00359 struct __copy_move<true, false, random_access_iterator_tag>
00360 {
00361 template<typename _II, typename _OI>
00362 static _OI
00363 __copy_m(_II __first, _II __last, _OI __result)
00364 {
00365 typedef typename iterator_traits<_II>::difference_type _Distance;
00366 for(_Distance __n = __last - __first; __n > 0; --__n)
00367 {
00368 *__result = std::move(*__first);
00369 ++__first;
00370 ++__result;
00371 }
00372 return __result;
00373 }
00374 };
00375 #endif
00376
00377 template<bool _IsMove>
00378 struct __copy_move<_IsMove, true, random_access_iterator_tag>
00379 {
00380 template<typename _Tp>
00381 static _Tp*
00382 __copy_m(const _Tp* __first, const _Tp* __last, _Tp* __result)
00383 {
00384 const ptrdiff_t _Num = __last - __first;
00385 if (_Num)
00386 __builtin_memmove(__result, __first, sizeof(_Tp) * _Num);
00387 return __result + _Num;
00388 }
00389 };
00390
00391 template<bool _IsMove, typename _II, typename _OI>
00392 inline _OI
00393 __copy_move_a(_II __first, _II __last, _OI __result)
00394 {
00395 typedef typename iterator_traits<_II>::value_type _ValueTypeI;
00396 typedef typename iterator_traits<_OI>::value_type _ValueTypeO;
00397 typedef typename iterator_traits<_II>::iterator_category _Category;
00398 const bool __simple = (__is_pod(_ValueTypeI)
00399 && __is_pointer<_II>::__value
00400 && __is_pointer<_OI>::__value
00401 && __are_same<_ValueTypeI, _ValueTypeO>::__value);
00402
00403 return std::__copy_move<_IsMove, __simple,
00404 _Category>::__copy_m(__first, __last, __result);
00405 }
00406
00407
00408
00409 template<typename _CharT>
00410 struct char_traits;
00411
00412 template<typename _CharT, typename _Traits>
00413 class istreambuf_iterator;
00414
00415 template<typename _CharT, typename _Traits>
00416 class ostreambuf_iterator;
00417
00418 template<bool _IsMove, typename _CharT>
00419 typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
00420 ostreambuf_iterator<_CharT, char_traits<_CharT> > >::__type
00421 __copy_move_a2(_CharT*, _CharT*,
00422 ostreambuf_iterator<_CharT, char_traits<_CharT> >);
00423
00424 template<bool _IsMove, typename _CharT>
00425 typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
00426 ostreambuf_iterator<_CharT, char_traits<_CharT> > >::__type
00427 __copy_move_a2(const _CharT*, const _CharT*,
00428 ostreambuf_iterator<_CharT, char_traits<_CharT> >);
00429
00430 template<bool _IsMove, typename _CharT>
00431 typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
00432 _CharT*>::__type
00433 __copy_move_a2(istreambuf_iterator<_CharT, char_traits<_CharT> >,
00434 istreambuf_iterator<_CharT, char_traits<_CharT> >, _CharT*);
00435
00436 template<bool _IsMove, typename _II, typename _OI>
00437 inline _OI
00438 __copy_move_a2(_II __first, _II __last, _OI __result)
00439 {
00440 return _OI(std::__copy_move_a<_IsMove>(std::__niter_base(__first),
00441 std::__niter_base(__last),
00442 std::__niter_base(__result)));
00443 }
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462 template<typename _II, typename _OI>
00463 inline _OI
00464 copy(_II __first, _II __last, _OI __result)
00465 {
00466
00467 __glibcxx_function_requires(_InputIteratorConcept<_II>)
00468 __glibcxx_function_requires(_OutputIteratorConcept<_OI,
00469 typename iterator_traits<_II>::value_type>)
00470 __glibcxx_requires_valid_range(__first, __last);
00471
00472 return (std::__copy_move_a2<__is_move_iterator<_II>::__value>
00473 (std::__miter_base(__first), std::__miter_base(__last),
00474 __result));
00475 }
00476
00477 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495 template<typename _II, typename _OI>
00496 inline _OI
00497 move(_II __first, _II __last, _OI __result)
00498 {
00499
00500 __glibcxx_function_requires(_InputIteratorConcept<_II>)
00501 __glibcxx_function_requires(_OutputIteratorConcept<_OI,
00502 typename iterator_traits<_II>::value_type>)
00503 __glibcxx_requires_valid_range(__first, __last);
00504
00505 return std::__copy_move_a2<true>(std::__miter_base(__first),
00506 std::__miter_base(__last), __result);
00507 }
00508
00509 #define _GLIBCXX_MOVE3(_Tp, _Up, _Vp) std::move(_Tp, _Up, _Vp)
00510 #else
00511 #define _GLIBCXX_MOVE3(_Tp, _Up, _Vp) std::copy(_Tp, _Up, _Vp)
00512 #endif
00513
00514 template<bool, bool, typename>
00515 struct __copy_move_backward
00516 {
00517 template<typename _BI1, typename _BI2>
00518 static _BI2
00519 __copy_move_b(_BI1 __first, _BI1 __last, _BI2 __result)
00520 {
00521 while (__first != __last)
00522 *--__result = *--__last;
00523 return __result;
00524 }
00525 };
00526
00527 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00528 template<typename _Category>
00529 struct __copy_move_backward<true, false, _Category>
00530 {
00531 template<typename _BI1, typename _BI2>
00532 static _BI2
00533 __copy_move_b(_BI1 __first, _BI1 __last, _BI2 __result)
00534 {
00535 while (__first != __last)
00536 *--__result = std::move(*--__last);
00537 return __result;
00538 }
00539 };
00540 #endif
00541
00542 template<>
00543 struct __copy_move_backward<false, false, random_access_iterator_tag>
00544 {
00545 template<typename _BI1, typename _BI2>
00546 static _BI2
00547 __copy_move_b(_BI1 __first, _BI1 __last, _BI2 __result)
00548 {
00549 typename iterator_traits<_BI1>::difference_type __n;
00550 for (__n = __last - __first; __n > 0; --__n)
00551 *--__result = *--__last;
00552 return __result;
00553 }
00554 };
00555
00556 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00557 template<>
00558 struct __copy_move_backward<true, false, random_access_iterator_tag>
00559 {
00560 template<typename _BI1, typename _BI2>
00561 static _BI2
00562 __copy_move_b(_BI1 __first, _BI1 __last, _BI2 __result)
00563 {
00564 typename iterator_traits<_BI1>::difference_type __n;
00565 for (__n = __last - __first; __n > 0; --__n)
00566 *--__result = std::move(*--__last);
00567 return __result;
00568 }
00569 };
00570 #endif
00571
00572 template<bool _IsMove>
00573 struct __copy_move_backward<_IsMove, true, random_access_iterator_tag>
00574 {
00575 template<typename _Tp>
00576 static _Tp*
00577 __copy_move_b(const _Tp* __first, const _Tp* __last, _Tp* __result)
00578 {
00579 const ptrdiff_t _Num = __last - __first;
00580 if (_Num)
00581 __builtin_memmove(__result - _Num, __first, sizeof(_Tp) * _Num);
00582 return __result - _Num;
00583 }
00584 };
00585
00586 template<bool _IsMove, typename _BI1, typename _BI2>
00587 inline _BI2
00588 __copy_move_backward_a(_BI1 __first, _BI1 __last, _BI2 __result)
00589 {
00590 typedef typename iterator_traits<_BI1>::value_type _ValueType1;
00591 typedef typename iterator_traits<_BI2>::value_type _ValueType2;
00592 typedef typename iterator_traits<_BI1>::iterator_category _Category;
00593 const bool __simple = (__is_pod(_ValueType1)
00594 && __is_pointer<_BI1>::__value
00595 && __is_pointer<_BI2>::__value
00596 && __are_same<_ValueType1, _ValueType2>::__value);
00597
00598 return std::__copy_move_backward<_IsMove, __simple,
00599 _Category>::__copy_move_b(__first,
00600 __last,
00601 __result);
00602 }
00603
00604 template<bool _IsMove, typename _BI1, typename _BI2>
00605 inline _BI2
00606 __copy_move_backward_a2(_BI1 __first, _BI1 __last, _BI2 __result)
00607 {
00608 return _BI2(std::__copy_move_backward_a<_IsMove>
00609 (std::__niter_base(__first), std::__niter_base(__last),
00610 std::__niter_base(__result)));
00611 }
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631 template<typename _BI1, typename _BI2>
00632 inline _BI2
00633 copy_backward(_BI1 __first, _BI1 __last, _BI2 __result)
00634 {
00635
00636 __glibcxx_function_requires(_BidirectionalIteratorConcept<_BI1>)
00637 __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept<_BI2>)
00638 __glibcxx_function_requires(_ConvertibleConcept<
00639 typename iterator_traits<_BI1>::value_type,
00640 typename iterator_traits<_BI2>::value_type>)
00641 __glibcxx_requires_valid_range(__first, __last);
00642
00643 return (std::__copy_move_backward_a2<__is_move_iterator<_BI1>::__value>
00644 (std::__miter_base(__first), std::__miter_base(__last),
00645 __result));
00646 }
00647
00648 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667 template<typename _BI1, typename _BI2>
00668 inline _BI2
00669 move_backward(_BI1 __first, _BI1 __last, _BI2 __result)
00670 {
00671
00672 __glibcxx_function_requires(_BidirectionalIteratorConcept<_BI1>)
00673 __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept<_BI2>)
00674 __glibcxx_function_requires(_ConvertibleConcept<
00675 typename iterator_traits<_BI1>::value_type,
00676 typename iterator_traits<_BI2>::value_type>)
00677 __glibcxx_requires_valid_range(__first, __last);
00678
00679 return std::__copy_move_backward_a2<true>(std::__miter_base(__first),
00680 std::__miter_base(__last),
00681 __result);
00682 }
00683
00684 #define _GLIBCXX_MOVE_BACKWARD3(_Tp, _Up, _Vp) std::move_backward(_Tp, _Up, _Vp)
00685 #else
00686 #define _GLIBCXX_MOVE_BACKWARD3(_Tp, _Up, _Vp) std::copy_backward(_Tp, _Up, _Vp)
00687 #endif
00688
00689 template<typename _ForwardIterator, typename _Tp>
00690 inline typename
00691 __gnu_cxx::__enable_if<!__is_scalar<_Tp>::__value, void>::__type
00692 __fill_a(_ForwardIterator __first, _ForwardIterator __last,
00693 const _Tp& __value)
00694 {
00695 for (; __first != __last; ++__first)
00696 *__first = __value;
00697 }
00698
00699 template<typename _ForwardIterator, typename _Tp>
00700 inline typename
00701 __gnu_cxx::__enable_if<__is_scalar<_Tp>::__value, void>::__type
00702 __fill_a(_ForwardIterator __first, _ForwardIterator __last,
00703 const _Tp& __value)
00704 {
00705 const _Tp __tmp = __value;
00706 for (; __first != __last; ++__first)
00707 *__first = __tmp;
00708 }
00709
00710
00711 template<typename _Tp>
00712 inline typename
00713 __gnu_cxx::__enable_if<__is_byte<_Tp>::__value, void>::__type
00714 __fill_a(_Tp* __first, _Tp* __last, const _Tp& __c)
00715 {
00716 const _Tp __tmp = __c;
00717 __builtin_memset(__first, static_cast<unsigned char>(__tmp),
00718 __last - __first);
00719 }
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733 template<typename _ForwardIterator, typename _Tp>
00734 inline void
00735 fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value)
00736 {
00737
00738 __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
00739 _ForwardIterator>)
00740 __glibcxx_requires_valid_range(__first, __last);
00741
00742 std::__fill_a(std::__niter_base(__first), std::__niter_base(__last),
00743 __value);
00744 }
00745
00746 template<typename _OutputIterator, typename _Size, typename _Tp>
00747 inline typename
00748 __gnu_cxx::__enable_if<!__is_scalar<_Tp>::__value, _OutputIterator>::__type
00749 __fill_n_a(_OutputIterator __first, _Size __n, const _Tp& __value)
00750 {
00751 for (; __n > 0; --__n, ++__first)
00752 *__first = __value;
00753 return __first;
00754 }
00755
00756 template<typename _OutputIterator, typename _Size, typename _Tp>
00757 inline typename
00758 __gnu_cxx::__enable_if<__is_scalar<_Tp>::__value, _OutputIterator>::__type
00759 __fill_n_a(_OutputIterator __first, _Size __n, const _Tp& __value)
00760 {
00761 const _Tp __tmp = __value;
00762 for (; __n > 0; --__n, ++__first)
00763 *__first = __tmp;
00764 return __first;
00765 }
00766
00767 template<typename _Size, typename _Tp>
00768 inline typename
00769 __gnu_cxx::__enable_if<__is_byte<_Tp>::__value, _Tp*>::__type
00770 __fill_n_a(_Tp* __first, _Size __n, const _Tp& __c)
00771 {
00772 std::__fill_a(__first, __first + __n, __c);
00773 return __first + __n;
00774 }
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791 template<typename _OI, typename _Size, typename _Tp>
00792 inline _OI
00793 fill_n(_OI __first, _Size __n, const _Tp& __value)
00794 {
00795
00796 __glibcxx_function_requires(_OutputIteratorConcept<_OI, _Tp>)
00797
00798 return _OI(std::__fill_n_a(std::__niter_base(__first), __n, __value));
00799 }
00800
00801 template<bool _BoolType>
00802 struct __equal
00803 {
00804 template<typename _II1, typename _II2>
00805 static bool
00806 equal(_II1 __first1, _II1 __last1, _II2 __first2)
00807 {
00808 for (; __first1 != __last1; ++__first1, ++__first2)
00809 if (!(*__first1 == *__first2))
00810 return false;
00811 return true;
00812 }
00813 };
00814
00815 template<>
00816 struct __equal<true>
00817 {
00818 template<typename _Tp>
00819 static bool
00820 equal(const _Tp* __first1, const _Tp* __last1, const _Tp* __first2)
00821 {
00822 return !__builtin_memcmp(__first1, __first2, sizeof(_Tp)
00823 * (__last1 - __first1));
00824 }
00825 };
00826
00827 template<typename _II1, typename _II2>
00828 inline bool
00829 __equal_aux(_II1 __first1, _II1 __last1, _II2 __first2)
00830 {
00831 typedef typename iterator_traits<_II1>::value_type _ValueType1;
00832 typedef typename iterator_traits<_II2>::value_type _ValueType2;
00833 const bool __simple = (__is_integer<_ValueType1>::__value
00834 && __is_pointer<_II1>::__value
00835 && __is_pointer<_II2>::__value
00836 && __are_same<_ValueType1, _ValueType2>::__value);
00837
00838 return std::__equal<__simple>::equal(__first1, __last1, __first2);
00839 }
00840
00841
00842 template<typename, typename>
00843 struct __lc_rai
00844 {
00845 template<typename _II1, typename _II2>
00846 static _II1
00847 __newlast1(_II1, _II1 __last1, _II2, _II2)
00848 { return __last1; }
00849
00850 template<typename _II>
00851 static bool
00852 __cnd2(_II __first, _II __last)
00853 { return __first != __last; }
00854 };
00855
00856 template<>
00857 struct __lc_rai<random_access_iterator_tag, random_access_iterator_tag>
00858 {
00859 template<typename _RAI1, typename _RAI2>
00860 static _RAI1
00861 __newlast1(_RAI1 __first1, _RAI1 __last1,
00862 _RAI2 __first2, _RAI2 __last2)
00863 {
00864 const typename iterator_traits<_RAI1>::difference_type
00865 __diff1 = __last1 - __first1;
00866 const typename iterator_traits<_RAI2>::difference_type
00867 __diff2 = __last2 - __first2;
00868 return __diff2 < __diff1 ? __first1 + __diff2 : __last1;
00869 }
00870
00871 template<typename _RAI>
00872 static bool
00873 __cnd2(_RAI, _RAI)
00874 { return true; }
00875 };
00876
00877 template<bool _BoolType>
00878 struct __lexicographical_compare
00879 {
00880 template<typename _II1, typename _II2>
00881 static bool __lc(_II1, _II1, _II2, _II2);
00882 };
00883
00884 template<bool _BoolType>
00885 template<typename _II1, typename _II2>
00886 bool
00887 __lexicographical_compare<_BoolType>::
00888 __lc(_II1 __first1, _II1 __last1, _II2 __first2, _II2 __last2)
00889 {
00890 typedef typename iterator_traits<_II1>::iterator_category _Category1;
00891 typedef typename iterator_traits<_II2>::iterator_category _Category2;
00892 typedef std::__lc_rai<_Category1, _Category2> __rai_type;
00893
00894 __last1 = __rai_type::__newlast1(__first1, __last1,
00895 __first2, __last2);
00896 for (; __first1 != __last1 && __rai_type::__cnd2(__first2, __last2);
00897 ++__first1, ++__first2)
00898 {
00899 if (*__first1 < *__first2)
00900 return true;
00901 if (*__first2 < *__first1)
00902 return false;
00903 }
00904 return __first1 == __last1 && __first2 != __last2;
00905 }
00906
00907 template<>
00908 struct __lexicographical_compare<true>
00909 {
00910 template<typename _Tp, typename _Up>
00911 static bool
00912 __lc(const _Tp* __first1, const _Tp* __last1,
00913 const _Up* __first2, const _Up* __last2)
00914 {
00915 const size_t __len1 = __last1 - __first1;
00916 const size_t __len2 = __last2 - __first2;
00917 const int __result = __builtin_memcmp(__first1, __first2,
00918 std::min(__len1, __len2));
00919 return __result != 0 ? __result < 0 : __len1 < __len2;
00920 }
00921 };
00922
00923 template<typename _II1, typename _II2>
00924 inline bool
00925 __lexicographical_compare_aux(_II1 __first1, _II1 __last1,
00926 _II2 __first2, _II2 __last2)
00927 {
00928 typedef typename iterator_traits<_II1>::value_type _ValueType1;
00929 typedef typename iterator_traits<_II2>::value_type _ValueType2;
00930 const bool __simple =
00931 (__is_byte<_ValueType1>::__value && __is_byte<_ValueType2>::__value
00932 && !__gnu_cxx::__numeric_traits<_ValueType1>::__is_signed
00933 && !__gnu_cxx::__numeric_traits<_ValueType2>::__is_signed
00934 && __is_pointer<_II1>::__value
00935 && __is_pointer<_II2>::__value);
00936
00937 return std::__lexicographical_compare<__simple>::__lc(__first1, __last1,
00938 __first2, __last2);
00939 }
00940
00941 _GLIBCXX_END_NAMESPACE
00942
00943 _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_P)
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957 template<typename _II1, typename _II2>
00958 inline bool
00959 equal(_II1 __first1, _II1 __last1, _II2 __first2)
00960 {
00961
00962 __glibcxx_function_requires(_InputIteratorConcept<_II1>)
00963 __glibcxx_function_requires(_InputIteratorConcept<_II2>)
00964 __glibcxx_function_requires(_EqualOpConcept<
00965 typename iterator_traits<_II1>::value_type,
00966 typename iterator_traits<_II2>::value_type>)
00967 __glibcxx_requires_valid_range(__first1, __last1);
00968
00969 return std::__equal_aux(std::__niter_base(__first1),
00970 std::__niter_base(__last1),
00971 std::__niter_base(__first2));
00972 }
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989 template<typename _IIter1, typename _IIter2, typename _BinaryPredicate>
00990 inline bool
00991 equal(_IIter1 __first1, _IIter1 __last1,
00992 _IIter2 __first2, _BinaryPredicate __binary_pred)
00993 {
00994
00995 __glibcxx_function_requires(_InputIteratorConcept<_IIter1>)
00996 __glibcxx_function_requires(_InputIteratorConcept<_IIter2>)
00997 __glibcxx_requires_valid_range(__first1, __last1);
00998
00999 for (; __first1 != __last1; ++__first1, ++__first2)
01000 if (!bool(__binary_pred(*__first1, *__first2)))
01001 return false;
01002 return true;
01003 }
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020 template<typename _II1, typename _II2>
01021 inline bool
01022 lexicographical_compare(_II1 __first1, _II1 __last1,
01023 _II2 __first2, _II2 __last2)
01024 {
01025
01026 typedef typename iterator_traits<_II1>::value_type _ValueType1;
01027 typedef typename iterator_traits<_II2>::value_type _ValueType2;
01028 __glibcxx_function_requires(_InputIteratorConcept<_II1>)
01029 __glibcxx_function_requires(_InputIteratorConcept<_II2>)
01030 __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>)
01031 __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>)
01032 __glibcxx_requires_valid_range(__first1, __last1);
01033 __glibcxx_requires_valid_range(__first2, __last2);
01034
01035 return std::__lexicographical_compare_aux(std::__niter_base(__first1),
01036 std::__niter_base(__last1),
01037 std::__niter_base(__first2),
01038 std::__niter_base(__last2));
01039 }
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054 template<typename _II1, typename _II2, typename _Compare>
01055 bool
01056 lexicographical_compare(_II1 __first1, _II1 __last1,
01057 _II2 __first2, _II2 __last2, _Compare __comp)
01058 {
01059 typedef typename iterator_traits<_II1>::iterator_category _Category1;
01060 typedef typename iterator_traits<_II2>::iterator_category _Category2;
01061 typedef std::__lc_rai<_Category1, _Category2> __rai_type;
01062
01063
01064 __glibcxx_function_requires(_InputIteratorConcept<_II1>)
01065 __glibcxx_function_requires(_InputIteratorConcept<_II2>)
01066 __glibcxx_requires_valid_range(__first1, __last1);
01067 __glibcxx_requires_valid_range(__first2, __last2);
01068
01069 __last1 = __rai_type::__newlast1(__first1, __last1, __first2, __last2);
01070 for (; __first1 != __last1 && __rai_type::__cnd2(__first2, __last2);
01071 ++__first1, ++__first2)
01072 {
01073 if (__comp(*__first1, *__first2))
01074 return true;
01075 if (__comp(*__first2, *__first1))
01076 return false;
01077 }
01078 return __first1 == __last1 && __first2 != __last2;
01079 }
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094 template<typename _InputIterator1, typename _InputIterator2>
01095 pair<_InputIterator1, _InputIterator2>
01096 mismatch(_InputIterator1 __first1, _InputIterator1 __last1,
01097 _InputIterator2 __first2)
01098 {
01099
01100 __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
01101 __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
01102 __glibcxx_function_requires(_EqualOpConcept<
01103 typename iterator_traits<_InputIterator1>::value_type,
01104 typename iterator_traits<_InputIterator2>::value_type>)
01105 __glibcxx_requires_valid_range(__first1, __last1);
01106
01107 while (__first1 != __last1 && *__first1 == *__first2)
01108 {
01109 ++__first1;
01110 ++__first2;
01111 }
01112 return pair<_InputIterator1, _InputIterator2>(__first1, __first2);
01113 }
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131 template<typename _InputIterator1, typename _InputIterator2,
01132 typename _BinaryPredicate>
01133 pair<_InputIterator1, _InputIterator2>
01134 mismatch(_InputIterator1 __first1, _InputIterator1 __last1,
01135 _InputIterator2 __first2, _BinaryPredicate __binary_pred)
01136 {
01137
01138 __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
01139 __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
01140 __glibcxx_requires_valid_range(__first1, __last1);
01141
01142 while (__first1 != __last1 && bool(__binary_pred(*__first1, *__first2)))
01143 {
01144 ++__first1;
01145 ++__first2;
01146 }
01147 return pair<_InputIterator1, _InputIterator2>(__first1, __first2);
01148 }
01149
01150 _GLIBCXX_END_NESTED_NAMESPACE
01151
01152
01153
01154
01155 #ifdef _GLIBCXX_PARALLEL
01156 # include <parallel/algobase.h>
01157 #endif
01158
01159 #endif