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
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952 template<typename _ForwardIterator, typename _Tp>
00953 _ForwardIterator
00954 lower_bound(_ForwardIterator __first, _ForwardIterator __last,
00955 const _Tp& __val)
00956 {
00957 typedef typename iterator_traits<_ForwardIterator>::value_type
00958 _ValueType;
00959 typedef typename iterator_traits<_ForwardIterator>::difference_type
00960 _DistanceType;
00961
00962
00963 __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
00964 __glibcxx_function_requires(_LessThanOpConcept<_ValueType, _Tp>)
00965 __glibcxx_requires_partitioned_lower(__first, __last, __val);
00966
00967 _DistanceType __len = std::distance(__first, __last);
00968 _DistanceType __half;
00969 _ForwardIterator __middle;
00970
00971 while (__len > 0)
00972 {
00973 __half = __len >> 1;
00974 __middle = __first;
00975 std::advance(__middle, __half);
00976 if (*__middle < __val)
00977 {
00978 __first = __middle;
00979 ++__first;
00980 __len = __len - __half - 1;
00981 }
00982 else
00983 __len = __half;
00984 }
00985 return __first;
00986 }
00987
00988
00989
00990 template<typename _Size>
00991 inline _Size
00992 __lg(_Size __n)
00993 {
00994 _Size __k;
00995 for (__k = 0; __n != 0; __n >>= 1)
00996 ++__k;
00997 return __k - 1;
00998 }
00999
01000 inline int
01001 __lg(int __n)
01002 { return sizeof(int) * __CHAR_BIT__ - 1 - __builtin_clz(__n); }
01003
01004 inline long
01005 __lg(long __n)
01006 { return sizeof(long) * __CHAR_BIT__ - 1 - __builtin_clzl(__n); }
01007
01008 inline long long
01009 __lg(long long __n)
01010 { return sizeof(long long) * __CHAR_BIT__ - 1 - __builtin_clzll(__n); }
01011
01012 _GLIBCXX_END_NAMESPACE
01013
01014 _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_P)
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028 template<typename _II1, typename _II2>
01029 inline bool
01030 equal(_II1 __first1, _II1 __last1, _II2 __first2)
01031 {
01032
01033 __glibcxx_function_requires(_InputIteratorConcept<_II1>)
01034 __glibcxx_function_requires(_InputIteratorConcept<_II2>)
01035 __glibcxx_function_requires(_EqualOpConcept<
01036 typename iterator_traits<_II1>::value_type,
01037 typename iterator_traits<_II2>::value_type>)
01038 __glibcxx_requires_valid_range(__first1, __last1);
01039
01040 return std::__equal_aux(std::__niter_base(__first1),
01041 std::__niter_base(__last1),
01042 std::__niter_base(__first2));
01043 }
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060 template<typename _IIter1, typename _IIter2, typename _BinaryPredicate>
01061 inline bool
01062 equal(_IIter1 __first1, _IIter1 __last1,
01063 _IIter2 __first2, _BinaryPredicate __binary_pred)
01064 {
01065
01066 __glibcxx_function_requires(_InputIteratorConcept<_IIter1>)
01067 __glibcxx_function_requires(_InputIteratorConcept<_IIter2>)
01068 __glibcxx_requires_valid_range(__first1, __last1);
01069
01070 for (; __first1 != __last1; ++__first1, ++__first2)
01071 if (!bool(__binary_pred(*__first1, *__first2)))
01072 return false;
01073 return true;
01074 }
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091 template<typename _II1, typename _II2>
01092 inline bool
01093 lexicographical_compare(_II1 __first1, _II1 __last1,
01094 _II2 __first2, _II2 __last2)
01095 {
01096
01097 typedef typename iterator_traits<_II1>::value_type _ValueType1;
01098 typedef typename iterator_traits<_II2>::value_type _ValueType2;
01099 __glibcxx_function_requires(_InputIteratorConcept<_II1>)
01100 __glibcxx_function_requires(_InputIteratorConcept<_II2>)
01101 __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>)
01102 __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>)
01103 __glibcxx_requires_valid_range(__first1, __last1);
01104 __glibcxx_requires_valid_range(__first2, __last2);
01105
01106 return std::__lexicographical_compare_aux(std::__niter_base(__first1),
01107 std::__niter_base(__last1),
01108 std::__niter_base(__first2),
01109 std::__niter_base(__last2));
01110 }
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125 template<typename _II1, typename _II2, typename _Compare>
01126 bool
01127 lexicographical_compare(_II1 __first1, _II1 __last1,
01128 _II2 __first2, _II2 __last2, _Compare __comp)
01129 {
01130 typedef typename iterator_traits<_II1>::iterator_category _Category1;
01131 typedef typename iterator_traits<_II2>::iterator_category _Category2;
01132 typedef std::__lc_rai<_Category1, _Category2> __rai_type;
01133
01134
01135 __glibcxx_function_requires(_InputIteratorConcept<_II1>)
01136 __glibcxx_function_requires(_InputIteratorConcept<_II2>)
01137 __glibcxx_requires_valid_range(__first1, __last1);
01138 __glibcxx_requires_valid_range(__first2, __last2);
01139
01140 __last1 = __rai_type::__newlast1(__first1, __last1, __first2, __last2);
01141 for (; __first1 != __last1 && __rai_type::__cnd2(__first2, __last2);
01142 ++__first1, ++__first2)
01143 {
01144 if (__comp(*__first1, *__first2))
01145 return true;
01146 if (__comp(*__first2, *__first1))
01147 return false;
01148 }
01149 return __first1 == __last1 && __first2 != __last2;
01150 }
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165 template<typename _InputIterator1, typename _InputIterator2>
01166 pair<_InputIterator1, _InputIterator2>
01167 mismatch(_InputIterator1 __first1, _InputIterator1 __last1,
01168 _InputIterator2 __first2)
01169 {
01170
01171 __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
01172 __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
01173 __glibcxx_function_requires(_EqualOpConcept<
01174 typename iterator_traits<_InputIterator1>::value_type,
01175 typename iterator_traits<_InputIterator2>::value_type>)
01176 __glibcxx_requires_valid_range(__first1, __last1);
01177
01178 while (__first1 != __last1 && *__first1 == *__first2)
01179 {
01180 ++__first1;
01181 ++__first2;
01182 }
01183 return pair<_InputIterator1, _InputIterator2>(__first1, __first2);
01184 }
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202 template<typename _InputIterator1, typename _InputIterator2,
01203 typename _BinaryPredicate>
01204 pair<_InputIterator1, _InputIterator2>
01205 mismatch(_InputIterator1 __first1, _InputIterator1 __last1,
01206 _InputIterator2 __first2, _BinaryPredicate __binary_pred)
01207 {
01208
01209 __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
01210 __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
01211 __glibcxx_requires_valid_range(__first1, __last1);
01212
01213 while (__first1 != __last1 && bool(__binary_pred(*__first1, *__first2)))
01214 {
01215 ++__first1;
01216 ++__first2;
01217 }
01218 return pair<_InputIterator1, _InputIterator2>(__first1, __first2);
01219 }
01220
01221 _GLIBCXX_END_NESTED_NAMESPACE
01222
01223
01224
01225
01226 #ifdef _GLIBCXX_PARALLEL
01227 # include <parallel/algobase.h>
01228 #endif
01229
01230 #endif