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,
00265 bool _IsNormal = __is_normal_iterator<_Iterator>::__value>
00266 struct __niter_base
00267 {
00268 static _Iterator
00269 __b(_Iterator __it)
00270 { return __it; }
00271 };
00272
00273 template<typename _Iterator>
00274 struct __niter_base<_Iterator, true>
00275 {
00276 static typename _Iterator::iterator_type
00277 __b(_Iterator __it)
00278 { return __it.base(); }
00279 };
00280
00281
00282 template<typename _Iterator,
00283 bool _IsMove = __is_move_iterator<_Iterator>::__value>
00284 struct __miter_base
00285 {
00286 static _Iterator
00287 __b(_Iterator __it)
00288 { return __it; }
00289 };
00290
00291 template<typename _Iterator>
00292 struct __miter_base<_Iterator, true>
00293 {
00294 static typename _Iterator::iterator_type
00295 __b(_Iterator __it)
00296 { return __it.base(); }
00297 };
00298
00299
00300
00301
00302
00303
00304
00305 template<bool, bool, typename>
00306 struct __copy_move
00307 {
00308 template<typename _II, typename _OI>
00309 static _OI
00310 __copy_m(_II __first, _II __last, _OI __result)
00311 {
00312 for (; __first != __last; ++__result, ++__first)
00313 *__result = *__first;
00314 return __result;
00315 }
00316 };
00317
00318 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00319 template<typename _Category>
00320 struct __copy_move<true, false, _Category>
00321 {
00322 template<typename _II, typename _OI>
00323 static _OI
00324 __copy_m(_II __first, _II __last, _OI __result)
00325 {
00326 for (; __first != __last; ++__result, ++__first)
00327 *__result = std::move(*__first);
00328 return __result;
00329 }
00330 };
00331 #endif
00332
00333 template<>
00334 struct __copy_move<false, false, random_access_iterator_tag>
00335 {
00336 template<typename _II, typename _OI>
00337 static _OI
00338 __copy_m(_II __first, _II __last, _OI __result)
00339 {
00340 typedef typename iterator_traits<_II>::difference_type _Distance;
00341 for(_Distance __n = __last - __first; __n > 0; --__n)
00342 {
00343 *__result = *__first;
00344 ++__first;
00345 ++__result;
00346 }
00347 return __result;
00348 }
00349 };
00350
00351 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00352 template<>
00353 struct __copy_move<true, false, random_access_iterator_tag>
00354 {
00355 template<typename _II, typename _OI>
00356 static _OI
00357 __copy_m(_II __first, _II __last, _OI __result)
00358 {
00359 typedef typename iterator_traits<_II>::difference_type _Distance;
00360 for(_Distance __n = __last - __first; __n > 0; --__n)
00361 {
00362 *__result = std::move(*__first);
00363 ++__first;
00364 ++__result;
00365 }
00366 return __result;
00367 }
00368 };
00369 #endif
00370
00371 template<bool _IsMove>
00372 struct __copy_move<_IsMove, true, random_access_iterator_tag>
00373 {
00374 template<typename _Tp>
00375 static _Tp*
00376 __copy_m(const _Tp* __first, const _Tp* __last, _Tp* __result)
00377 {
00378 const ptrdiff_t _Num = __last - __first;
00379 if (_Num)
00380 __builtin_memmove(__result, __first, sizeof(_Tp) * _Num);
00381 return __result + _Num;
00382 }
00383 };
00384
00385 template<bool _IsMove, typename _II, typename _OI>
00386 inline _OI
00387 __copy_move_a(_II __first, _II __last, _OI __result)
00388 {
00389 typedef typename iterator_traits<_II>::value_type _ValueTypeI;
00390 typedef typename iterator_traits<_OI>::value_type _ValueTypeO;
00391 typedef typename iterator_traits<_II>::iterator_category _Category;
00392 const bool __simple = (__is_pod(_ValueTypeI)
00393 && __is_pointer<_II>::__value
00394 && __is_pointer<_OI>::__value
00395 && __are_same<_ValueTypeI, _ValueTypeO>::__value);
00396
00397 return std::__copy_move<_IsMove, __simple,
00398 _Category>::__copy_m(__first, __last, __result);
00399 }
00400
00401
00402
00403 template<typename _CharT>
00404 struct char_traits;
00405
00406 template<typename _CharT, typename _Traits>
00407 class istreambuf_iterator;
00408
00409 template<typename _CharT, typename _Traits>
00410 class ostreambuf_iterator;
00411
00412 template<bool _IsMove, typename _CharT>
00413 typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
00414 ostreambuf_iterator<_CharT, char_traits<_CharT> > >::__type
00415 __copy_move_a2(_CharT*, _CharT*,
00416 ostreambuf_iterator<_CharT, char_traits<_CharT> >);
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(const _CharT*, const _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 _CharT*>::__type
00427 __copy_move_a2(istreambuf_iterator<_CharT, char_traits<_CharT> >,
00428 istreambuf_iterator<_CharT, char_traits<_CharT> >, _CharT*);
00429
00430 template<bool _IsMove, typename _II, typename _OI>
00431 inline _OI
00432 __copy_move_a2(_II __first, _II __last, _OI __result)
00433 {
00434 return _OI(std::__copy_move_a<_IsMove>
00435 (std::__niter_base<_II>::__b(__first),
00436 std::__niter_base<_II>::__b(__last),
00437 std::__niter_base<_OI>::__b(__result)));
00438 }
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457 template<typename _II, typename _OI>
00458 inline _OI
00459 copy(_II __first, _II __last, _OI __result)
00460 {
00461
00462 __glibcxx_function_requires(_InputIteratorConcept<_II>)
00463 __glibcxx_function_requires(_OutputIteratorConcept<_OI,
00464 typename iterator_traits<_II>::value_type>)
00465 __glibcxx_requires_valid_range(__first, __last);
00466
00467 return (std::__copy_move_a2<__is_move_iterator<_II>::__value>
00468 (std::__miter_base<_II>::__b(__first),
00469 std::__miter_base<_II>::__b(__last), __result));
00470 }
00471
00472 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490 template<typename _II, typename _OI>
00491 inline _OI
00492 move(_II __first, _II __last, _OI __result)
00493 {
00494
00495 __glibcxx_function_requires(_InputIteratorConcept<_II>)
00496 __glibcxx_function_requires(_OutputIteratorConcept<_OI,
00497 typename iterator_traits<_II>::value_type>)
00498 __glibcxx_requires_valid_range(__first, __last);
00499
00500 return (std::__copy_move_a2<true>
00501 (std::__miter_base<_II>::__b(__first),
00502 std::__miter_base<_II>::__b(__last), __result));
00503 }
00504
00505 #define _GLIBCXX_MOVE3(_Tp, _Up, _Vp) std::move(_Tp, _Up, _Vp)
00506 #else
00507 #define _GLIBCXX_MOVE3(_Tp, _Up, _Vp) std::copy(_Tp, _Up, _Vp)
00508 #endif
00509
00510 template<bool, bool, typename>
00511 struct __copy_move_backward
00512 {
00513 template<typename _BI1, typename _BI2>
00514 static _BI2
00515 __copy_move_b(_BI1 __first, _BI1 __last, _BI2 __result)
00516 {
00517 while (__first != __last)
00518 *--__result = *--__last;
00519 return __result;
00520 }
00521 };
00522
00523 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00524 template<typename _Category>
00525 struct __copy_move_backward<true, false, _Category>
00526 {
00527 template<typename _BI1, typename _BI2>
00528 static _BI2
00529 __copy_move_b(_BI1 __first, _BI1 __last, _BI2 __result)
00530 {
00531 while (__first != __last)
00532 *--__result = std::move(*--__last);
00533 return __result;
00534 }
00535 };
00536 #endif
00537
00538 template<>
00539 struct __copy_move_backward<false, false, random_access_iterator_tag>
00540 {
00541 template<typename _BI1, typename _BI2>
00542 static _BI2
00543 __copy_move_b(_BI1 __first, _BI1 __last, _BI2 __result)
00544 {
00545 typename iterator_traits<_BI1>::difference_type __n;
00546 for (__n = __last - __first; __n > 0; --__n)
00547 *--__result = *--__last;
00548 return __result;
00549 }
00550 };
00551
00552 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00553 template<>
00554 struct __copy_move_backward<true, false, random_access_iterator_tag>
00555 {
00556 template<typename _BI1, typename _BI2>
00557 static _BI2
00558 __copy_move_b(_BI1 __first, _BI1 __last, _BI2 __result)
00559 {
00560 typename iterator_traits<_BI1>::difference_type __n;
00561 for (__n = __last - __first; __n > 0; --__n)
00562 *--__result = std::move(*--__last);
00563 return __result;
00564 }
00565 };
00566 #endif
00567
00568 template<bool _IsMove>
00569 struct __copy_move_backward<_IsMove, true, random_access_iterator_tag>
00570 {
00571 template<typename _Tp>
00572 static _Tp*
00573 __copy_move_b(const _Tp* __first, const _Tp* __last, _Tp* __result)
00574 {
00575 const ptrdiff_t _Num = __last - __first;
00576 if (_Num)
00577 __builtin_memmove(__result - _Num, __first, sizeof(_Tp) * _Num);
00578 return __result - _Num;
00579 }
00580 };
00581
00582 template<bool _IsMove, typename _BI1, typename _BI2>
00583 inline _BI2
00584 __copy_move_backward_a(_BI1 __first, _BI1 __last, _BI2 __result)
00585 {
00586 typedef typename iterator_traits<_BI1>::value_type _ValueType1;
00587 typedef typename iterator_traits<_BI2>::value_type _ValueType2;
00588 typedef typename iterator_traits<_BI1>::iterator_category _Category;
00589 const bool __simple = (__is_pod(_ValueType1)
00590 && __is_pointer<_BI1>::__value
00591 && __is_pointer<_BI2>::__value
00592 && __are_same<_ValueType1, _ValueType2>::__value);
00593
00594 return std::__copy_move_backward<_IsMove, __simple,
00595 _Category>::__copy_move_b(__first,
00596 __last,
00597 __result);
00598 }
00599
00600 template<bool _IsMove, typename _BI1, typename _BI2>
00601 inline _BI2
00602 __copy_move_backward_a2(_BI1 __first, _BI1 __last, _BI2 __result)
00603 {
00604 return _BI2(std::__copy_move_backward_a<_IsMove>
00605 (std::__niter_base<_BI1>::__b(__first),
00606 std::__niter_base<_BI1>::__b(__last),
00607 std::__niter_base<_BI2>::__b(__result)));
00608 }
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628 template<typename _BI1, typename _BI2>
00629 inline _BI2
00630 copy_backward(_BI1 __first, _BI1 __last, _BI2 __result)
00631 {
00632
00633 __glibcxx_function_requires(_BidirectionalIteratorConcept<_BI1>)
00634 __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept<_BI2>)
00635 __glibcxx_function_requires(_ConvertibleConcept<
00636 typename iterator_traits<_BI1>::value_type,
00637 typename iterator_traits<_BI2>::value_type>)
00638 __glibcxx_requires_valid_range(__first, __last);
00639
00640 return (std::__copy_move_backward_a2<__is_move_iterator<_BI1>::__value>
00641 (std::__miter_base<_BI1>::__b(__first),
00642 std::__miter_base<_BI1>::__b(__last), __result));
00643 }
00644
00645 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664 template<typename _BI1, typename _BI2>
00665 inline _BI2
00666 move_backward(_BI1 __first, _BI1 __last, _BI2 __result)
00667 {
00668
00669 __glibcxx_function_requires(_BidirectionalIteratorConcept<_BI1>)
00670 __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept<_BI2>)
00671 __glibcxx_function_requires(_ConvertibleConcept<
00672 typename iterator_traits<_BI1>::value_type,
00673 typename iterator_traits<_BI2>::value_type>)
00674 __glibcxx_requires_valid_range(__first, __last);
00675
00676 return (std::__copy_move_backward_a2<true>
00677 (std::__miter_base<_BI1>::__b(__first),
00678 std::__miter_base<_BI1>::__b(__last), __result));
00679 }
00680
00681 #define _GLIBCXX_MOVE_BACKWARD3(_Tp, _Up, _Vp) std::move_backward(_Tp, _Up, _Vp)
00682 #else
00683 #define _GLIBCXX_MOVE_BACKWARD3(_Tp, _Up, _Vp) std::copy_backward(_Tp, _Up, _Vp)
00684 #endif
00685
00686 template<typename _ForwardIterator, typename _Tp>
00687 inline typename
00688 __gnu_cxx::__enable_if<!__is_scalar<_Tp>::__value, void>::__type
00689 __fill_a(_ForwardIterator __first, _ForwardIterator __last,
00690 const _Tp& __value)
00691 {
00692 for (; __first != __last; ++__first)
00693 *__first = __value;
00694 }
00695
00696 template<typename _ForwardIterator, typename _Tp>
00697 inline typename
00698 __gnu_cxx::__enable_if<__is_scalar<_Tp>::__value, void>::__type
00699 __fill_a(_ForwardIterator __first, _ForwardIterator __last,
00700 const _Tp& __value)
00701 {
00702 const _Tp __tmp = __value;
00703 for (; __first != __last; ++__first)
00704 *__first = __tmp;
00705 }
00706
00707
00708 template<typename _Tp>
00709 inline typename
00710 __gnu_cxx::__enable_if<__is_byte<_Tp>::__value, void>::__type
00711 __fill_a(_Tp* __first, _Tp* __last, const _Tp& __c)
00712 {
00713 const _Tp __tmp = __c;
00714 __builtin_memset(__first, static_cast<unsigned char>(__tmp),
00715 __last - __first);
00716 }
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730 template<typename _ForwardIterator, typename _Tp>
00731 inline void
00732 fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value)
00733 {
00734
00735 __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
00736 _ForwardIterator>)
00737 __glibcxx_requires_valid_range(__first, __last);
00738
00739 std::__fill_a(std::__niter_base<_ForwardIterator>::__b(__first),
00740 std::__niter_base<_ForwardIterator>::__b(__last), __value);
00741 }
00742
00743 template<typename _OutputIterator, typename _Size, typename _Tp>
00744 inline typename
00745 __gnu_cxx::__enable_if<!__is_scalar<_Tp>::__value, _OutputIterator>::__type
00746 __fill_n_a(_OutputIterator __first, _Size __n, const _Tp& __value)
00747 {
00748 for (; __n > 0; --__n, ++__first)
00749 *__first = __value;
00750 return __first;
00751 }
00752
00753 template<typename _OutputIterator, typename _Size, typename _Tp>
00754 inline typename
00755 __gnu_cxx::__enable_if<__is_scalar<_Tp>::__value, _OutputIterator>::__type
00756 __fill_n_a(_OutputIterator __first, _Size __n, const _Tp& __value)
00757 {
00758 const _Tp __tmp = __value;
00759 for (; __n > 0; --__n, ++__first)
00760 *__first = __tmp;
00761 return __first;
00762 }
00763
00764 template<typename _Size, typename _Tp>
00765 inline typename
00766 __gnu_cxx::__enable_if<__is_byte<_Tp>::__value, _Tp*>::__type
00767 __fill_n_a(_Tp* __first, _Size __n, const _Tp& __c)
00768 {
00769 std::__fill_a(__first, __first + __n, __c);
00770 return __first + __n;
00771 }
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788 template<typename _OI, typename _Size, typename _Tp>
00789 inline _OI
00790 fill_n(_OI __first, _Size __n, const _Tp& __value)
00791 {
00792
00793 __glibcxx_function_requires(_OutputIteratorConcept<_OI, _Tp>)
00794
00795 return _OI(std::__fill_n_a(std::__niter_base<_OI>::__b(__first),
00796 __n, __value));
00797 }
00798
00799 template<bool _BoolType>
00800 struct __equal
00801 {
00802 template<typename _II1, typename _II2>
00803 static bool
00804 equal(_II1 __first1, _II1 __last1, _II2 __first2)
00805 {
00806 for (; __first1 != __last1; ++__first1, ++__first2)
00807 if (!(*__first1 == *__first2))
00808 return false;
00809 return true;
00810 }
00811 };
00812
00813 template<>
00814 struct __equal<true>
00815 {
00816 template<typename _Tp>
00817 static bool
00818 equal(const _Tp* __first1, const _Tp* __last1, const _Tp* __first2)
00819 {
00820 return !__builtin_memcmp(__first1, __first2, sizeof(_Tp)
00821 * (__last1 - __first1));
00822 }
00823 };
00824
00825 template<typename _II1, typename _II2>
00826 inline bool
00827 __equal_aux(_II1 __first1, _II1 __last1, _II2 __first2)
00828 {
00829 typedef typename iterator_traits<_II1>::value_type _ValueType1;
00830 typedef typename iterator_traits<_II2>::value_type _ValueType2;
00831 const bool __simple = (__is_integer<_ValueType1>::__value
00832 && __is_pointer<_II1>::__value
00833 && __is_pointer<_II2>::__value
00834 && __are_same<_ValueType1, _ValueType2>::__value);
00835
00836 return std::__equal<__simple>::equal(__first1, __last1, __first2);
00837 }
00838
00839
00840 template<typename, typename>
00841 struct __lc_rai
00842 {
00843 template<typename _II1, typename _II2>
00844 static _II1
00845 __newlast1(_II1, _II1 __last1, _II2, _II2)
00846 { return __last1; }
00847
00848 template<typename _II>
00849 static bool
00850 __cnd2(_II __first, _II __last)
00851 { return __first != __last; }
00852 };
00853
00854 template<>
00855 struct __lc_rai<random_access_iterator_tag, random_access_iterator_tag>
00856 {
00857 template<typename _RAI1, typename _RAI2>
00858 static _RAI1
00859 __newlast1(_RAI1 __first1, _RAI1 __last1,
00860 _RAI2 __first2, _RAI2 __last2)
00861 {
00862 const typename iterator_traits<_RAI1>::difference_type
00863 __diff1 = __last1 - __first1;
00864 const typename iterator_traits<_RAI2>::difference_type
00865 __diff2 = __last2 - __first2;
00866 return __diff2 < __diff1 ? __first1 + __diff2 : __last1;
00867 }
00868
00869 template<typename _RAI>
00870 static bool
00871 __cnd2(_RAI, _RAI)
00872 { return true; }
00873 };
00874
00875 template<bool _BoolType>
00876 struct __lexicographical_compare
00877 {
00878 template<typename _II1, typename _II2>
00879 static bool __lc(_II1, _II1, _II2, _II2);
00880 };
00881
00882 template<bool _BoolType>
00883 template<typename _II1, typename _II2>
00884 bool
00885 __lexicographical_compare<_BoolType>::
00886 __lc(_II1 __first1, _II1 __last1, _II2 __first2, _II2 __last2)
00887 {
00888 typedef typename iterator_traits<_II1>::iterator_category _Category1;
00889 typedef typename iterator_traits<_II2>::iterator_category _Category2;
00890 typedef std::__lc_rai<_Category1, _Category2> __rai_type;
00891
00892 __last1 = __rai_type::__newlast1(__first1, __last1,
00893 __first2, __last2);
00894 for (; __first1 != __last1 && __rai_type::__cnd2(__first2, __last2);
00895 ++__first1, ++__first2)
00896 {
00897 if (*__first1 < *__first2)
00898 return true;
00899 if (*__first2 < *__first1)
00900 return false;
00901 }
00902 return __first1 == __last1 && __first2 != __last2;
00903 }
00904
00905 template<>
00906 struct __lexicographical_compare<true>
00907 {
00908 template<typename _Tp, typename _Up>
00909 static bool
00910 __lc(const _Tp* __first1, const _Tp* __last1,
00911 const _Up* __first2, const _Up* __last2)
00912 {
00913 const size_t __len1 = __last1 - __first1;
00914 const size_t __len2 = __last2 - __first2;
00915 const int __result = __builtin_memcmp(__first1, __first2,
00916 std::min(__len1, __len2));
00917 return __result != 0 ? __result < 0 : __len1 < __len2;
00918 }
00919 };
00920
00921 template<typename _II1, typename _II2>
00922 inline bool
00923 __lexicographical_compare_aux(_II1 __first1, _II1 __last1,
00924 _II2 __first2, _II2 __last2)
00925 {
00926 typedef typename iterator_traits<_II1>::value_type _ValueType1;
00927 typedef typename iterator_traits<_II2>::value_type _ValueType2;
00928 const bool __simple =
00929 (__is_byte<_ValueType1>::__value && __is_byte<_ValueType2>::__value
00930 && !__gnu_cxx::__numeric_traits<_ValueType1>::__is_signed
00931 && !__gnu_cxx::__numeric_traits<_ValueType2>::__is_signed
00932 && __is_pointer<_II1>::__value
00933 && __is_pointer<_II2>::__value);
00934
00935 return std::__lexicographical_compare<__simple>::__lc(__first1, __last1,
00936 __first2, __last2);
00937 }
00938
00939 _GLIBCXX_END_NAMESPACE
00940
00941 _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_P)
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955 template<typename _II1, typename _II2>
00956 inline bool
00957 equal(_II1 __first1, _II1 __last1, _II2 __first2)
00958 {
00959
00960 __glibcxx_function_requires(_InputIteratorConcept<_II1>)
00961 __glibcxx_function_requires(_InputIteratorConcept<_II2>)
00962 __glibcxx_function_requires(_EqualOpConcept<
00963 typename iterator_traits<_II1>::value_type,
00964 typename iterator_traits<_II2>::value_type>)
00965 __glibcxx_requires_valid_range(__first1, __last1);
00966
00967 return std::__equal_aux(std::__niter_base<_II1>::__b(__first1),
00968 std::__niter_base<_II1>::__b(__last1),
00969 std::__niter_base<_II2>::__b(__first2));
00970 }
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987 template<typename _IIter1, typename _IIter2, typename _BinaryPredicate>
00988 inline bool
00989 equal(_IIter1 __first1, _IIter1 __last1,
00990 _IIter2 __first2, _BinaryPredicate __binary_pred)
00991 {
00992
00993 __glibcxx_function_requires(_InputIteratorConcept<_IIter1>)
00994 __glibcxx_function_requires(_InputIteratorConcept<_IIter2>)
00995 __glibcxx_requires_valid_range(__first1, __last1);
00996
00997 for (; __first1 != __last1; ++__first1, ++__first2)
00998 if (!bool(__binary_pred(*__first1, *__first2)))
00999 return false;
01000 return true;
01001 }
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018 template<typename _II1, typename _II2>
01019 inline bool
01020 lexicographical_compare(_II1 __first1, _II1 __last1,
01021 _II2 __first2, _II2 __last2)
01022 {
01023
01024 typedef typename iterator_traits<_II1>::value_type _ValueType1;
01025 typedef typename iterator_traits<_II2>::value_type _ValueType2;
01026 __glibcxx_function_requires(_InputIteratorConcept<_II1>)
01027 __glibcxx_function_requires(_InputIteratorConcept<_II2>)
01028 __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>)
01029 __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>)
01030 __glibcxx_requires_valid_range(__first1, __last1);
01031 __glibcxx_requires_valid_range(__first2, __last2);
01032
01033 return std::__lexicographical_compare_aux
01034 (std::__niter_base<_II1>::__b(__first1),
01035 std::__niter_base<_II1>::__b(__last1),
01036 std::__niter_base<_II2>::__b(__first2),
01037 std::__niter_base<_II2>::__b(__last2));
01038 }
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053 template<typename _II1, typename _II2, typename _Compare>
01054 bool
01055 lexicographical_compare(_II1 __first1, _II1 __last1,
01056 _II2 __first2, _II2 __last2, _Compare __comp)
01057 {
01058 typedef typename iterator_traits<_II1>::iterator_category _Category1;
01059 typedef typename iterator_traits<_II2>::iterator_category _Category2;
01060 typedef std::__lc_rai<_Category1, _Category2> __rai_type;
01061
01062
01063 __glibcxx_function_requires(_InputIteratorConcept<_II1>)
01064 __glibcxx_function_requires(_InputIteratorConcept<_II2>)
01065 __glibcxx_requires_valid_range(__first1, __last1);
01066 __glibcxx_requires_valid_range(__first2, __last2);
01067
01068 __last1 = __rai_type::__newlast1(__first1, __last1, __first2, __last2);
01069 for (; __first1 != __last1 && __rai_type::__cnd2(__first2, __last2);
01070 ++__first1, ++__first2)
01071 {
01072 if (__comp(*__first1, *__first2))
01073 return true;
01074 if (__comp(*__first2, *__first1))
01075 return false;
01076 }
01077 return __first1 == __last1 && __first2 != __last2;
01078 }
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093 template<typename _InputIterator1, typename _InputIterator2>
01094 pair<_InputIterator1, _InputIterator2>
01095 mismatch(_InputIterator1 __first1, _InputIterator1 __last1,
01096 _InputIterator2 __first2)
01097 {
01098
01099 __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
01100 __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
01101 __glibcxx_function_requires(_EqualOpConcept<
01102 typename iterator_traits<_InputIterator1>::value_type,
01103 typename iterator_traits<_InputIterator2>::value_type>)
01104 __glibcxx_requires_valid_range(__first1, __last1);
01105
01106 while (__first1 != __last1 && *__first1 == *__first2)
01107 {
01108 ++__first1;
01109 ++__first2;
01110 }
01111 return pair<_InputIterator1, _InputIterator2>(__first1, __first2);
01112 }
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130 template<typename _InputIterator1, typename _InputIterator2,
01131 typename _BinaryPredicate>
01132 pair<_InputIterator1, _InputIterator2>
01133 mismatch(_InputIterator1 __first1, _InputIterator1 __last1,
01134 _InputIterator2 __first2, _BinaryPredicate __binary_pred)
01135 {
01136
01137 __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
01138 __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
01139 __glibcxx_requires_valid_range(__first1, __last1);
01140
01141 while (__first1 != __last1 && bool(__binary_pred(*__first1, *__first2)))
01142 {
01143 ++__first1;
01144 ++__first2;
01145 }
01146 return pair<_InputIterator1, _InputIterator2>(__first1, __first2);
01147 }
01148
01149 _GLIBCXX_END_NESTED_NAMESPACE
01150
01151
01152
01153
01154 #ifdef _GLIBCXX_PARALLEL
01155 # include <parallel/algobase.h>
01156 #endif
01157
01158 #endif