This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Remove algo duplication
- From: François Dumont <frs dot dumont at gmail dot com>
- To: "libstdc++ at gcc dot gnu dot org" <libstdc++ at gcc dot gnu dot org>
- Date: Tue, 03 Sep 2013 22:03:00 +0200
- Subject: Remove algo duplication
- Authentication-results: sourceware.org; auth=none
Hi
I still have this patch pending on my side, I don't think we ever
really decided what to do with it. In this version of the patch
everything not Standard has been moved to the std::__detail namespace
for a cleaner design.
Could it go in trunk ?
If so, now or after creation of 4.9 branch ?
If not, should I create a branch to keep it waiting for I don't know why ?
Should I simply forget it ?
Note that it has been tested under Linux x86_64 normal and debug modes.
François
Index: include/std/streambuf
===================================================================
--- include/std/streambuf (revision 202183)
+++ include/std/streambuf (working copy)
@@ -148,10 +148,10 @@
__copy_streambufs_eof<>(basic_streambuf*, basic_streambuf*, bool&);
template<bool _IsMove, typename _CharT2>
- friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value,
+ friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value,
_CharT2*>::__type
- __copy_move_a2(istreambuf_iterator<_CharT2>,
- istreambuf_iterator<_CharT2>, _CharT2*);
+ std::__detail::__copy_move_a2(istreambuf_iterator<_CharT2>,
+ istreambuf_iterator<_CharT2>, _CharT2*);
template<typename _CharT2>
friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value,
Index: include/bits/streambuf_iterator.h
===================================================================
--- include/bits/streambuf_iterator.h (revision 202183)
+++ include/bits/streambuf_iterator.h (working copy)
@@ -77,8 +77,8 @@
template<bool _IsMove, typename _CharT2>
friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value,
_CharT2*>::__type
- __copy_move_a2(istreambuf_iterator<_CharT2>,
- istreambuf_iterator<_CharT2>, _CharT2*);
+ std::__detail::__copy_move_a2(istreambuf_iterator<_CharT2>,
+ istreambuf_iterator<_CharT2>, _CharT2*);
template<typename _CharT2>
friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value,
@@ -304,11 +304,15 @@
return __result;
}
+_GLIBCXX_END_NAMESPACE_VERSION
+
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
+
template<bool _IsMove, typename _CharT>
- typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
- ostreambuf_iterator<_CharT> >::__type
+ typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
+ std::ostreambuf_iterator<_CharT> >::__type
__copy_move_a2(_CharT* __first, _CharT* __last,
- ostreambuf_iterator<_CharT> __result)
+ std::ostreambuf_iterator<_CharT> __result)
{
const streamsize __num = __last - __first;
if (__num > 0)
@@ -318,9 +322,9 @@
template<bool _IsMove, typename _CharT>
typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
- ostreambuf_iterator<_CharT> >::__type
+ std::ostreambuf_iterator<_CharT> >::__type
__copy_move_a2(const _CharT* __first, const _CharT* __last,
- ostreambuf_iterator<_CharT> __result)
+ std::ostreambuf_iterator<_CharT> __result)
{
const streamsize __num = __last - __first;
if (__num > 0)
@@ -331,10 +335,10 @@
template<bool _IsMove, typename _CharT>
typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
_CharT*>::__type
- __copy_move_a2(istreambuf_iterator<_CharT> __first,
- istreambuf_iterator<_CharT> __last, _CharT* __result)
+ __copy_move_a2(std::istreambuf_iterator<_CharT> __first,
+ std::istreambuf_iterator<_CharT> __last, _CharT* __result)
{
- typedef istreambuf_iterator<_CharT> __is_iterator_type;
+ typedef std::istreambuf_iterator<_CharT> __is_iterator_type;
typedef typename __is_iterator_type::traits_type traits_type;
typedef typename __is_iterator_type::streambuf_type streambuf_type;
typedef typename traits_type::int_type int_type;
@@ -363,6 +367,10 @@
return __result;
}
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
template<typename _CharT>
typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
istreambuf_iterator<_CharT> >::__type
Index: include/bits/random.tcc
===================================================================
--- include/bits/random.tcc (revision 202183)
+++ include/bits/random.tcc (working copy)
@@ -136,7 +136,7 @@
seed(_Sseq& __q)
{
const _UIntType __k0 = __m == 0 ? std::numeric_limits<_UIntType>::digits
- : std::__lg(__m);
+ : std::__detail::__lg(__m);
const _UIntType __k = (__k0 + 31) / 32;
uint_least32_t __arr[__k + 3];
__q.generate(__arr + 0, __arr + __k + 3);
@@ -749,7 +749,7 @@
= (_M_b.max() - _M_b.min() < std::numeric_limits<_Eresult_type>::max()
? _M_b.max() - _M_b.min() + 1 : 0);
const unsigned __edig = std::numeric_limits<_Eresult_type>::digits;
- const unsigned __m = __r ? std::__lg(__r) : __edig;
+ const unsigned __m = __r ? std::__detail::__lg(__r) : __edig;
typedef typename std::common_type<_Eresult_type, result_type>::type
__ctype;
Index: include/bits/random.h
===================================================================
--- include/bits/random.h (revision 202183)
+++ include/bits/random.h (working copy)
@@ -113,8 +113,9 @@
bool __schrage_ok = __m % __a < __m / __a>
struct _Mod
{
- typedef typename _Select_uint_least_t<std::__lg(__a)
- + std::__lg(__m) + 2>::type _Tp2;
+ typedef typename _Select_uint_least_t<std::__detail::__lg(__a)
+ + std::__detail::__lg(__m)
+ + 2>::type _Tp2;
static _Tp
__calc(_Tp __x)
{ return static_cast<_Tp>((_Tp2(__a) * __x + __c) % __m); }
Index: include/bits/stl_algobase.h
===================================================================
--- include/bits/stl_algobase.h (revision 202183)
+++ include/bits/stl_algobase.h (working copy)
@@ -68,10 +68,11 @@
#include <bits/concept_check.h>
#include <debug/debug.h>
#include <bits/move.h> // For std::swap and _GLIBCXX_MOVE
+#include <bits/predefined_ops.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
#if __cplusplus < 201103L
// See http://gcc.gnu.org/ml/libstdc++/2004-08/msg00167.html: in a
@@ -104,6 +105,10 @@
};
#endif
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
/**
* @brief Swaps the contents of two iterators.
* @ingroup mutating_algorithms
@@ -139,7 +144,7 @@
_ReferenceType1;
typedef typename iterator_traits<_ForwardIterator2>::reference
_ReferenceType2;
- std::__iter_swap<__are_same<_ValueType1, _ValueType2>::__value
+ std::__detail::__iter_swap<__are_same<_ValueType1, _ValueType2>::__value
&& __are_same<_ValueType1&, _ReferenceType1>::__value
&& __are_same<_ValueType2&, _ReferenceType2>::__value>::
iter_swap(__a, __b);
@@ -265,6 +270,10 @@
return __a;
}
+_GLIBCXX_END_NAMESPACE_VERSION
+
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
+
// If _Iterator is a __normal_iterator return its base (a plain pointer,
// normally) otherwise return it untouched. See copy, fill, ...
template<typename _Iterator>
@@ -275,7 +284,7 @@
template<typename _Iterator>
inline typename _Niter_base<_Iterator>::iterator_type
__niter_base(_Iterator __it)
- { return std::_Niter_base<_Iterator>::_S_base(__it); }
+ { return std::__detail::_Niter_base<_Iterator>::_S_base(__it); }
// Likewise, for move_iterator.
template<typename _Iterator>
@@ -286,7 +295,7 @@
template<typename _Iterator>
inline typename _Miter_base<_Iterator>::iterator_type
__miter_base(_Iterator __it)
- { return std::_Miter_base<_Iterator>::_S_base(__it); }
+ { return std::__detail::_Miter_base<_Iterator>::_S_base(__it); }
// All of these auxiliary structs serve two purposes. (1) Replace
// calls to copy with memmove whenever possible. (Memmove, not memcpy,
@@ -386,10 +395,14 @@
&& __is_pointer<_OI>::__value
&& __are_same<_ValueTypeI, _ValueTypeO>::__value);
- return std::__copy_move<_IsMove, __simple,
+ return std::__detail::__copy_move<_IsMove, __simple,
_Category>::__copy_m(__first, __last, __result);
}
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
// Helpers for streambuf iterators (either istream or ostream).
// NB: avoid including <iosfwd>, relatively large.
template<typename _CharT>
@@ -401,33 +414,53 @@
template<typename _CharT, typename _Traits>
class ostreambuf_iterator;
+_GLIBCXX_END_NAMESPACE_VERSION
+
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
+
template<bool _IsMove, typename _CharT>
typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
- ostreambuf_iterator<_CharT, char_traits<_CharT> > >::__type
+ std::ostreambuf_iterator<_CharT, char_traits<_CharT> > >::__type
__copy_move_a2(_CharT*, _CharT*,
- ostreambuf_iterator<_CharT, char_traits<_CharT> >);
+ std::ostreambuf_iterator<_CharT, char_traits<_CharT> >);
template<bool _IsMove, typename _CharT>
typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
- ostreambuf_iterator<_CharT, char_traits<_CharT> > >::__type
+ std::ostreambuf_iterator<_CharT, char_traits<_CharT> > >::__type
__copy_move_a2(const _CharT*, const _CharT*,
- ostreambuf_iterator<_CharT, char_traits<_CharT> >);
+ std::ostreambuf_iterator<_CharT, char_traits<_CharT> >);
template<bool _IsMove, typename _CharT>
typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
_CharT*>::__type
- __copy_move_a2(istreambuf_iterator<_CharT, char_traits<_CharT> >,
- istreambuf_iterator<_CharT, char_traits<_CharT> >, _CharT*);
+ __copy_move_a2(std::istreambuf_iterator<_CharT, char_traits<_CharT> >,
+ std::istreambuf_iterator<_CharT, char_traits<_CharT> >,
+ _CharT*);
template<bool _IsMove, typename _II, typename _OI>
inline _OI
__copy_move_a2(_II __first, _II __last, _OI __result)
{
- return _OI(std::__copy_move_a<_IsMove>(std::__niter_base(__first),
- std::__niter_base(__last),
- std::__niter_base(__result)));
+ return _OI(std::__detail::__copy_move_a<_IsMove>
+ (std::__detail::__niter_base(__first),
+ std::__detail::__niter_base(__last),
+ std::__detail::__niter_base(__result)));
}
+ template<typename _II, typename _OI>
+ inline _OI
+ __copy(_II __first, _II __last, _OI __result)
+ {
+ return std::__detail::__copy_move_a2<__is_move_iterator<_II>::__value>
+ (std::__detail::__miter_base(__first),
+ std::__detail::__miter_base(__last),
+ __result);
+ }
+
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
/**
* @brief Copies the range [first,last) into result.
* @ingroup mutating_algorithms
@@ -455,12 +488,29 @@
typename iterator_traits<_II>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- return (std::__copy_move_a2<__is_move_iterator<_II>::__value>
- (std::__miter_base(__first), std::__miter_base(__last),
- __result));
+ return std::__detail::__copy(__first, __last, __result);
}
#if __cplusplus >= 201103L
+
+_GLIBCXX_END_NAMESPACE_VERSION
+
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
+
+ template<typename _II, typename _OI>
+ inline _OI
+ __move(_II __first, _II __last, _OI __result)
+ {
+ return std::__detail::__copy_move_a2<true>
+ (std::__detail::__miter_base(__first),
+ std::__detail::__miter_base(__last),
+ __result);
+ }
+
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
/**
* @brief Moves the range [first,last) into result.
* @ingroup mutating_algorithms
@@ -488,15 +538,18 @@
typename iterator_traits<_II>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- return std::__copy_move_a2<true>(std::__miter_base(__first),
- std::__miter_base(__last), __result);
+ return std::__detail::__move(__first, __last, __result);
}
-#define _GLIBCXX_MOVE3(_Tp, _Up, _Vp) std::move(_Tp, _Up, _Vp)
+#define _GLIBCXX_MOVE3(_Tp, _Up, _Vp) std::__detail::__move(_Tp, _Up, _Vp)
#else
-#define _GLIBCXX_MOVE3(_Tp, _Up, _Vp) std::copy(_Tp, _Up, _Vp)
+#define _GLIBCXX_MOVE3(_Tp, _Up, _Vp) std::__detail::__copy(_Tp, _Up, _Vp)
#endif
+_GLIBCXX_END_NAMESPACE_VERSION
+
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
+
template<bool, bool, typename>
struct __copy_move_backward
{
@@ -581,7 +634,7 @@
&& __is_pointer<_BI2>::__value
&& __are_same<_ValueType1, _ValueType2>::__value);
- return std::__copy_move_backward<_IsMove, __simple,
+ return std::__detail::__copy_move_backward<_IsMove, __simple,
_Category>::__copy_move_b(__first,
__last,
__result);
@@ -591,11 +644,26 @@
inline _BI2
__copy_move_backward_a2(_BI1 __first, _BI1 __last, _BI2 __result)
{
- return _BI2(std::__copy_move_backward_a<_IsMove>
- (std::__niter_base(__first), std::__niter_base(__last),
- std::__niter_base(__result)));
+ return _BI2(std::__detail::__copy_move_backward_a<_IsMove>
+ (std::__detail::__niter_base(__first),
+ std::__detail::__niter_base(__last),
+ std::__detail::__niter_base(__result)));
}
+ template<typename _BI1, typename _BI2>
+ inline _BI2
+ __copy_backward(_BI1 __first, _BI1 __last, _BI2 __result)
+ {
+ return std::__detail::__copy_move_backward_a2<
+ __is_move_iterator<_BI1>::__value>(std::__detail::__miter_base(__first),
+ std::__detail::__miter_base(__last),
+ __result);
+ }
+
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
/**
* @brief Copies the range [first,last) into result.
* @ingroup mutating_algorithms
@@ -626,12 +694,29 @@
typename iterator_traits<_BI2>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- return (std::__copy_move_backward_a2<__is_move_iterator<_BI1>::__value>
- (std::__miter_base(__first), std::__miter_base(__last),
- __result));
+ return std::__detail::__copy_backward(__first, __last, __result);
}
#if __cplusplus >= 201103L
+
+_GLIBCXX_END_NAMESPACE_VERSION
+
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
+
+ template<typename _BI1, typename _BI2>
+ inline _BI2
+ __move_backward(_BI1 __first, _BI1 __last, _BI2 __result)
+ {
+ return std::__detail::__copy_move_backward_a2<true>
+ (std::__detail::__miter_base(__first),
+ std::__detail::__miter_base(__last),
+ __result);
+ }
+
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
/**
* @brief Moves the range [first,last) into result.
* @ingroup mutating_algorithms
@@ -662,16 +747,20 @@
typename iterator_traits<_BI2>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- return std::__copy_move_backward_a2<true>(std::__miter_base(__first),
- std::__miter_base(__last),
- __result);
+ return std::__detail::__move_backward(__first, __last, __result);
}
-#define _GLIBCXX_MOVE_BACKWARD3(_Tp, _Up, _Vp) std::move_backward(_Tp, _Up, _Vp)
+#define _GLIBCXX_MOVE_BACKWARD3(_Tp, _Up, _Vp) \
+ std::__detail::__move_backward(_Tp, _Up, _Vp)
#else
-#define _GLIBCXX_MOVE_BACKWARD3(_Tp, _Up, _Vp) std::copy_backward(_Tp, _Up, _Vp)
+#define _GLIBCXX_MOVE_BACKWARD3(_Tp, _Up, _Vp) \
+ std::__detail::__copy_backward(_Tp, _Up, _Vp)
#endif
+_GLIBCXX_END_NAMESPACE_VERSION
+
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
+
template<typename _ForwardIterator, typename _Tp>
inline typename
__gnu_cxx::__enable_if<!__is_scalar<_Tp>::__value, void>::__type
@@ -704,6 +793,10 @@
__last - __first);
}
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
/**
* @brief Fills the range [first,last) with copies of value.
* @ingroup mutating_algorithms
@@ -725,10 +818,15 @@
_ForwardIterator>)
__glibcxx_requires_valid_range(__first, __last);
- std::__fill_a(std::__niter_base(__first), std::__niter_base(__last),
- __value);
+ std::__detail::__fill_a(std::__detail::__niter_base(__first),
+ std::__detail::__niter_base(__last),
+ __value);
}
+_GLIBCXX_END_NAMESPACE_VERSION
+
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
+
template<typename _OutputIterator, typename _Size, typename _Tp>
inline typename
__gnu_cxx::__enable_if<!__is_scalar<_Tp>::__value, _OutputIterator>::__type
@@ -757,10 +855,14 @@
__gnu_cxx::__enable_if<__is_byte<_Tp>::__value, _Tp*>::__type
__fill_n_a(_Tp* __first, _Size __n, const _Tp& __c)
{
- std::__fill_a(__first, __first + __n, __c);
+ std::__detail::__fill_a(__first, __first + __n, __c);
return __first + __n;
}
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
/**
* @brief Fills the range [first,first+n) with copies of value.
* @ingroup mutating_algorithms
@@ -782,10 +884,15 @@
{
// concept requirements
__glibcxx_function_requires(_OutputIteratorConcept<_OI, _Tp>)
-
- return _OI(std::__fill_n_a(std::__niter_base(__first), __n, __value));
+
+ return _OI(std::__detail::__fill_n_a(std::__detail::__niter_base(__first),
+ __n, __value));
}
+_GLIBCXX_END_NAMESPACE_VERSION
+
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
+
template<bool _BoolType>
struct __equal
{
@@ -824,7 +931,8 @@
&& __is_pointer<_II2>::__value
&& __are_same<_ValueType1, _ValueType2>::__value);
- return std::__equal<__simple>::equal(__first1, __last1, __first2);
+ return std::__detail::__equal<__simple>::equal(__first1, __last1,
+ __first2);
}
template<typename, typename>
@@ -862,6 +970,29 @@
{ return true; }
};
+ template<typename _II1, typename _II2,
+ typename _Compare12, typename _Compare21>
+ bool
+ __lexicographical_compare_impl(_II1 __first1, _II1 __last1,
+ _II2 __first2, _II2 __last2,
+ _Compare12 __comp12, _Compare21 __comp21)
+ {
+ typedef typename iterator_traits<_II1>::iterator_category _Category1;
+ typedef typename iterator_traits<_II2>::iterator_category _Category2;
+ typedef std::__detail::__lc_rai<_Category1, _Category2> __rai_type;
+
+ __last1 = __rai_type::__newlast1(__first1, __last1, __first2, __last2);
+ for (; __first1 != __last1 && __rai_type::__cnd2(__first2, __last2);
+ ++__first1, ++__first2)
+ {
+ if (__comp12(__first1, __first2))
+ return true;
+ if (__comp21(__first2, __first1))
+ return false;
+ }
+ return __first1 == __last1 && __first2 != __last2;
+ }
+
template<bool _BoolType>
struct __lexicographical_compare
{
@@ -875,21 +1006,10 @@
__lexicographical_compare<_BoolType>::
__lc(_II1 __first1, _II1 __last1, _II2 __first2, _II2 __last2)
{
- typedef typename iterator_traits<_II1>::iterator_category _Category1;
- typedef typename iterator_traits<_II2>::iterator_category _Category2;
- typedef std::__lc_rai<_Category1, _Category2> __rai_type;
-
- __last1 = __rai_type::__newlast1(__first1, __last1,
- __first2, __last2);
- for (; __first1 != __last1 && __rai_type::__cnd2(__first2, __last2);
- ++__first1, ++__first2)
- {
- if (*__first1 < *__first2)
- return true;
- if (*__first2 < *__first1)
- return false;
- }
- return __first1 == __last1 && __first2 != __last2;
+ return std::__detail::__lexicographical_compare_impl(
+ __first1, __last1, __first2, __last2,
+ __gnu_cxx::__ops::__iter_less_iter(__first1, __first2),
+ __gnu_cxx::__ops::__iter_less_iter(__first2, __first1));
}
template<>
@@ -922,38 +1042,18 @@
&& __is_pointer<_II1>::__value
&& __is_pointer<_II2>::__value);
- return std::__lexicographical_compare<__simple>::__lc(__first1, __last1,
- __first2, __last2);
+ return std::__detail::__lexicographical_compare<__simple>
+ ::__lc(__first1, __last1, __first2, __last2);
}
- /**
- * @brief Finds the first position in which @a val could be inserted
- * without changing the ordering.
- * @param __first An iterator.
- * @param __last Another iterator.
- * @param __val The search term.
- * @return An iterator pointing to the first element <em>not less
- * than</em> @a val, or end() if every element is less than
- * @a val.
- * @ingroup binary_search_algorithms
- */
- template<typename _ForwardIterator, typename _Tp>
+ template<typename _ForwardIterator, typename _Tp, typename _Compare>
_ForwardIterator
- lower_bound(_ForwardIterator __first, _ForwardIterator __last,
- const _Tp& __val)
+ __lower_bound(_ForwardIterator __first, _ForwardIterator __last,
+ const _Tp& __val, _Compare __comp)
{
-#ifdef _GLIBCXX_CONCEPT_CHECKS
- typedef typename iterator_traits<_ForwardIterator>::value_type
- _ValueType;
-#endif
typedef typename iterator_traits<_ForwardIterator>::difference_type
_DistanceType;
- // concept requirements
- __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
- __glibcxx_function_requires(_LessThanOpConcept<_ValueType, _Tp>)
- __glibcxx_requires_partitioned_lower(__first, __last, __val);
-
_DistanceType __len = std::distance(__first, __last);
while (__len > 0)
@@ -961,7 +1061,7 @@
_DistanceType __half = __len >> 1;
_ForwardIterator __middle = __first;
std::advance(__middle, __half);
- if (*__middle < __val)
+ if (__comp(__middle, __val))
{
__first = __middle;
++__first;
@@ -973,6 +1073,40 @@
return __first;
}
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+ /**
+ * @brief Finds the first position in which @a val could be inserted
+ * without changing the ordering.
+ * @param __first An iterator.
+ * @param __last Another iterator.
+ * @param __val The search term.
+ * @return An iterator pointing to the first element <em>not less
+ * than</em> @a val, or end() if every element is less than
+ * @a val.
+ * @ingroup binary_search_algorithms
+ */
+ template<typename _ForwardIterator, typename _Tp>
+ _ForwardIterator
+ lower_bound(_ForwardIterator __first, _ForwardIterator __last,
+ const _Tp& __val)
+ {
+ // concept requirements
+ __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
+ __glibcxx_function_requires(_LessThanOpConcept<
+ typename iterator_traits<_ForwardIterator>::value_type, _Tp>)
+ __glibcxx_requires_partitioned_lower(__first, __last, __val);
+
+ return std::__detail::__lower_bound(__first, __last, __val,
+ __gnu_cxx::__ops::__iter_less_cval(__first, __val));
+ }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
+
/// This is a helper function for the sort routines and for random.tcc.
// Precondition: __n > 0.
inline _GLIBCXX_CONSTEXPR int
@@ -999,7 +1133,7 @@
__lg(unsigned long long __n)
{ return sizeof(long long) * __CHAR_BIT__ - 1 - __builtin_clzll(__n); }
-_GLIBCXX_END_NAMESPACE_VERSION
+_GLIBCXX_END_NAMESPACE_DETAIL
_GLIBCXX_BEGIN_NAMESPACE_ALGO
@@ -1027,9 +1161,9 @@
typename iterator_traits<_II2>::value_type>)
__glibcxx_requires_valid_range(__first1, __last1);
- return std::__equal_aux(std::__niter_base(__first1),
- std::__niter_base(__last1),
- std::__niter_base(__first2));
+ return std::__detail::__equal_aux(std::__detail::__niter_base(__first1),
+ std::__detail::__niter_base(__last1),
+ std::__detail::__niter_base(__first2));
}
/**
@@ -1188,10 +1322,11 @@
__glibcxx_requires_valid_range(__first1, __last1);
__glibcxx_requires_valid_range(__first2, __last2);
- return std::__lexicographical_compare_aux(std::__niter_base(__first1),
- std::__niter_base(__last1),
- std::__niter_base(__first2),
- std::__niter_base(__last2));
+ return std::__detail::__lexicographical_compare_aux
+ (std::__detail::__niter_base(__first1),
+ std::__detail::__niter_base(__last1),
+ std::__detail::__niter_base(__first2),
+ std::__detail::__niter_base(__last2));
}
/**
@@ -1212,28 +1347,40 @@
lexicographical_compare(_II1 __first1, _II1 __last1,
_II2 __first2, _II2 __last2, _Compare __comp)
{
- typedef typename iterator_traits<_II1>::iterator_category _Category1;
- typedef typename iterator_traits<_II2>::iterator_category _Category2;
- typedef std::__lc_rai<_Category1, _Category2> __rai_type;
-
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_II1>)
__glibcxx_function_requires(_InputIteratorConcept<_II2>)
__glibcxx_requires_valid_range(__first1, __last1);
__glibcxx_requires_valid_range(__first2, __last2);
- __last1 = __rai_type::__newlast1(__first1, __last1, __first2, __last2);
- for (; __first1 != __last1 && __rai_type::__cnd2(__first2, __last2);
- ++__first1, ++__first2)
- {
- if (__comp(*__first1, *__first2))
- return true;
- if (__comp(*__first2, *__first1))
- return false;
- }
- return __first1 == __last1 && __first2 != __last2;
+ return std::__detail::__lexicographical_compare_impl
+ (__first1, __last1, __first2, __last2,
+ __gnu_cxx::__ops::__iter_comp_iter(__comp, __first1, __first2),
+ __gnu_cxx::__ops::__iter_comp_iter(__comp, __first2, __first1));
}
+_GLIBCXX_END_NAMESPACE_ALGO
+
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
+
+ template<typename _InputIterator1, typename _InputIterator2,
+ typename _BinaryPredicate>
+ pair<_InputIterator1, _InputIterator2>
+ __mismatch(_InputIterator1 __first1, _InputIterator1 __last1,
+ _InputIterator2 __first2, _BinaryPredicate __binary_pred)
+ {
+ while (__first1 != __last1 && __binary_pred(__first1, __first2))
+ {
+ ++__first1;
+ ++__first2;
+ }
+ return pair<_InputIterator1, _InputIterator2>(__first1, __first2);
+ }
+
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_ALGO
+
/**
* @brief Finds the places in ranges which don't match.
* @ingroup non_mutating_algorithms
@@ -1260,12 +1407,8 @@
typename iterator_traits<_InputIterator2>::value_type>)
__glibcxx_requires_valid_range(__first1, __last1);
- while (__first1 != __last1 && *__first1 == *__first2)
- {
- ++__first1;
- ++__first2;
- }
- return pair<_InputIterator1, _InputIterator2>(__first1, __first2);
+ return std::__detail::__mismatch(__first1, __last1, __first2,
+ __gnu_cxx::__ops::__iter_equal_to_iter(__first1, __first2));
}
/**
@@ -1295,12 +1438,8 @@
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
__glibcxx_requires_valid_range(__first1, __last1);
- while (__first1 != __last1 && bool(__binary_pred(*__first1, *__first2)))
- {
- ++__first1;
- ++__first2;
- }
- return pair<_InputIterator1, _InputIterator2>(__first1, __first2);
+ return std::__detail::__mismatch(__first1, __last1, __first2,
+ __gnu_cxx::__ops::__iter_comp_iter(__binary_pred, __first1, __first2));
}
#if __cplusplus > 201103L
Index: include/bits/c++config
===================================================================
--- include/bits/c++config (revision 202183)
+++ include/bits/c++config (working copy)
@@ -337,6 +337,11 @@
# define _GLIBCXX_END_NAMESPACE_CONTAINER
#endif
+#define _GLIBCXX_BEGIN_NAMESPACE_DETAIL \
+ namespace __detail { _GLIBCXX_BEGIN_NAMESPACE_VERSION
+#define _GLIBCXX_END_NAMESPACE_DETAIL \
+ _GLIBCXX_END_NAMESPACE_VERSION }
+
// GLIBCXX_ABI Deprecated
// Define if compatibility should be provided for -mlong-double-64.
#undef _GLIBCXX_LONG_DOUBLE_COMPAT
Index: include/bits/stl_heap.h
===================================================================
--- include/bits/stl_heap.h (revision 202183)
+++ include/bits/stl_heap.h (working copy)
@@ -57,31 +57,17 @@
#include <debug/debug.h>
#include <bits/move.h>
+#include <bits/predefined_ops.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
/**
* @defgroup heap_algorithms Heap
* @ingroup sorting_algorithms
*/
- template<typename _RandomAccessIterator, typename _Distance>
- _Distance
- __is_heap_until(_RandomAccessIterator __first, _Distance __n)
- {
- _Distance __parent = 0;
- for (_Distance __child = 1; __child < __n; ++__child)
- {
- if (__first[__parent] < __first[__child])
- return __child;
- if ((__child & 1) == 0)
- ++__parent;
- }
- return __n;
- }
-
template<typename _RandomAccessIterator, typename _Distance,
typename _Compare>
_Distance
@@ -91,7 +77,7 @@
_Distance __parent = 0;
for (_Distance __child = 1; __child < __n; ++__child)
{
- if (__comp(__first[__parent], __first[__child]))
+ if (__comp(__first + __parent, __first + __child))
return __child;
if ((__child & 1) == 0)
++__parent;
@@ -99,18 +85,28 @@
return __n;
}
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
// __is_heap, a predicate testing whether or not a range is a heap.
// This function is an extension, not part of the C++ standard.
template<typename _RandomAccessIterator, typename _Distance>
inline bool
__is_heap(_RandomAccessIterator __first, _Distance __n)
- { return std::__is_heap_until(__first, __n) == __n; }
+ {
+ return std::__detail::__is_heap_until(__first, __n,
+ __gnu_cxx::__ops::__iter_less_iter(__first)) == __n;
+ }
template<typename _RandomAccessIterator, typename _Compare,
typename _Distance>
inline bool
__is_heap(_RandomAccessIterator __first, _Compare __comp, _Distance __n)
- { return std::__is_heap_until(__first, __n, __comp) == __n; }
+ {
+ return std::__detail::__is_heap_until(__first, __n,
+ __gnu_cxx::__ops::__iter_comp_iter(__comp, __first)) == __n;
+ }
template<typename _RandomAccessIterator>
inline bool
@@ -123,16 +119,22 @@
_Compare __comp)
{ return std::__is_heap(__first, __comp, std::distance(__first, __last)); }
+_GLIBCXX_END_NAMESPACE_VERSION
+
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
+
// Heap-manipulation functions: push_heap, pop_heap, make_heap, sort_heap,
// + is_heap and is_heap_until in C++0x.
- template<typename _RandomAccessIterator, typename _Distance, typename _Tp>
+ template<typename _RandomAccessIterator, typename _Distance, typename _Tp,
+ typename _Compare>
void
- __push_heap(_RandomAccessIterator __first,
- _Distance __holeIndex, _Distance __topIndex, _Tp __value)
+ __push_heap(_RandomAccessIterator __first, _Distance __holeIndex,
+ _Distance __topIndex, _Tp __value, _Compare __comp)
{
_Distance __parent = (__holeIndex - 1) / 2;
- while (__holeIndex > __topIndex && *(__first + __parent) < __value)
+ while (__holeIndex > __topIndex
+ && __comp(__first + __parent, __value))
{
*(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __parent));
__holeIndex = __parent;
@@ -141,6 +143,10 @@
*(__first + __holeIndex) = _GLIBCXX_MOVE(__value);
}
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
/**
* @brief Push an element onto a heap.
* @param __first Start of heap.
@@ -168,27 +174,12 @@
__glibcxx_requires_heap(__first, __last - 1);
_ValueType __value = _GLIBCXX_MOVE(*(__last - 1));
- std::__push_heap(__first, _DistanceType((__last - __first) - 1),
- _DistanceType(0), _GLIBCXX_MOVE(__value));
+ std::__detail::__push_heap(__first, _DistanceType((__last - __first) - 1),
+ _DistanceType(0), _GLIBCXX_MOVE(__value),
+ __gnu_cxx::__ops
+ ::__iter_less_val(__first, __value));
}
- template<typename _RandomAccessIterator, typename _Distance, typename _Tp,
- typename _Compare>
- void
- __push_heap(_RandomAccessIterator __first, _Distance __holeIndex,
- _Distance __topIndex, _Tp __value, _Compare __comp)
- {
- _Distance __parent = (__holeIndex - 1) / 2;
- while (__holeIndex > __topIndex
- && __comp(*(__first + __parent), __value))
- {
- *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __parent));
- __holeIndex = __parent;
- __parent = (__holeIndex - 1) / 2;
- }
- *(__first + __holeIndex) = _GLIBCXX_MOVE(__value);
- }
-
/**
* @brief Push an element onto a heap using comparison functor.
* @param __first Start of heap.
@@ -218,21 +209,29 @@
__glibcxx_requires_heap_pred(__first, __last - 1, __comp);
_ValueType __value = _GLIBCXX_MOVE(*(__last - 1));
- std::__push_heap(__first, _DistanceType((__last - __first) - 1),
- _DistanceType(0), _GLIBCXX_MOVE(__value), __comp);
+ std::__detail::__push_heap(__first, _DistanceType((__last - __first) - 1),
+ _DistanceType(0), _GLIBCXX_MOVE(__value),
+ __gnu_cxx::__ops
+ ::__iter_comp_val(__comp, __first, __value));
}
- template<typename _RandomAccessIterator, typename _Distance, typename _Tp>
+_GLIBCXX_END_NAMESPACE_VERSION
+
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
+
+ template<typename _RandomAccessIterator, typename _Distance,
+ typename _Tp, typename _Compare>
void
__adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex,
- _Distance __len, _Tp __value)
+ _Distance __len, _Tp __value, _Compare __comp)
{
const _Distance __topIndex = __holeIndex;
_Distance __secondChild = __holeIndex;
while (__secondChild < (__len - 1) / 2)
{
__secondChild = 2 * (__secondChild + 1);
- if (*(__first + __secondChild) < *(__first + (__secondChild - 1)))
+ if (__comp(__first + __secondChild,
+ __first + (__secondChild - 1)))
__secondChild--;
*(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __secondChild));
__holeIndex = __secondChild;
@@ -244,14 +243,16 @@
+ (__secondChild - 1)));
__holeIndex = __secondChild - 1;
}
- std::__push_heap(__first, __holeIndex, __topIndex,
- _GLIBCXX_MOVE(__value));
+ std::__detail::__push_heap(__first, __holeIndex, __topIndex,
+ _GLIBCXX_MOVE(__value),
+ __gnu_cxx::__ops
+ ::__rebind_iter_comp_val(__comp, __value));
}
- template<typename _RandomAccessIterator>
+ template<typename _RandomAccessIterator, typename _Compare>
inline void
__pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
- _RandomAccessIterator __result)
+ _RandomAccessIterator __result, _Compare __comp)
{
typedef typename iterator_traits<_RandomAccessIterator>::value_type
_ValueType;
@@ -260,11 +261,15 @@
_ValueType __value = _GLIBCXX_MOVE(*__result);
*__result = _GLIBCXX_MOVE(*__first);
- std::__adjust_heap(__first, _DistanceType(0),
- _DistanceType(__last - __first),
- _GLIBCXX_MOVE(__value));
+ std::__detail::__adjust_heap(__first, _DistanceType(0),
+ _DistanceType(__last - __first),
+ _GLIBCXX_MOVE(__value), __comp);
}
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
/**
* @brief Pop an element off a heap.
* @param __first Start of heap.
@@ -280,13 +285,11 @@
inline void
pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
{
- typedef typename iterator_traits<_RandomAccessIterator>::value_type
- _ValueType;
-
// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIterator>)
- __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
+ __glibcxx_function_requires(_LessThanComparableConcept<
+ typename iterator_traits<_RandomAccessIterator>::value_type>)
__glibcxx_requires_non_empty_range(__first, __last);
__glibcxx_requires_valid_range(__first, __last);
__glibcxx_requires_heap(__first, __last);
@@ -294,55 +297,11 @@
if (__last - __first > 1)
{
--__last;
- std::__pop_heap(__first, __last, __last);
+ std::__detail::__pop_heap(__first, __last, __last,
+ __gnu_cxx::__ops::__iter_less_iter(__first));
}
}
- template<typename _RandomAccessIterator, typename _Distance,
- typename _Tp, typename _Compare>
- void
- __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex,
- _Distance __len, _Tp __value, _Compare __comp)
- {
- const _Distance __topIndex = __holeIndex;
- _Distance __secondChild = __holeIndex;
- while (__secondChild < (__len - 1) / 2)
- {
- __secondChild = 2 * (__secondChild + 1);
- if (__comp(*(__first + __secondChild),
- *(__first + (__secondChild - 1))))
- __secondChild--;
- *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __secondChild));
- __holeIndex = __secondChild;
- }
- if ((__len & 1) == 0 && __secondChild == (__len - 2) / 2)
- {
- __secondChild = 2 * (__secondChild + 1);
- *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first
- + (__secondChild - 1)));
- __holeIndex = __secondChild - 1;
- }
- std::__push_heap(__first, __holeIndex, __topIndex,
- _GLIBCXX_MOVE(__value), __comp);
- }
-
- template<typename _RandomAccessIterator, typename _Compare>
- inline void
- __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
- _RandomAccessIterator __result, _Compare __comp)
- {
- typedef typename iterator_traits<_RandomAccessIterator>::value_type
- _ValueType;
- typedef typename iterator_traits<_RandomAccessIterator>::difference_type
- _DistanceType;
-
- _ValueType __value = _GLIBCXX_MOVE(*__result);
- *__result = _GLIBCXX_MOVE(*__first);
- std::__adjust_heap(__first, _DistanceType(0),
- _DistanceType(__last - __first),
- _GLIBCXX_MOVE(__value), __comp);
- }
-
/**
* @brief Pop an element off a heap using comparison functor.
* @param __first Start of heap.
@@ -369,33 +328,26 @@
if (__last - __first > 1)
{
--__last;
- std::__pop_heap(__first, __last, __last, __comp);
+ std::__detail::__pop_heap(__first, __last, __last,
+ __gnu_cxx::__ops
+ ::__iter_comp_iter(__comp, __first));
}
}
- /**
- * @brief Construct a heap over a range.
- * @param __first Start of heap.
- * @param __last End of heap.
- * @ingroup heap_algorithms
- *
- * This operation makes the elements in [__first,__last) into a heap.
- */
- template<typename _RandomAccessIterator>
+_GLIBCXX_END_NAMESPACE_VERSION
+
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
+
+ template<typename _RandomAccessIterator, typename _Compare>
void
- make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
+ __make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
+ _Compare __comp)
{
typedef typename iterator_traits<_RandomAccessIterator>::value_type
_ValueType;
typedef typename iterator_traits<_RandomAccessIterator>::difference_type
_DistanceType;
- // concept requirements
- __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
- _RandomAccessIterator>)
- __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
- __glibcxx_requires_valid_range(__first, __last);
-
if (__last - __first < 2)
return;
@@ -404,14 +356,43 @@
while (true)
{
_ValueType __value = _GLIBCXX_MOVE(*(__first + __parent));
- std::__adjust_heap(__first, __parent, __len, _GLIBCXX_MOVE(__value));
+ std::__detail::__adjust_heap(__first, __parent, __len,
+ _GLIBCXX_MOVE(__value), __comp);
if (__parent == 0)
return;
__parent--;
}
}
+
+_GLIBCXX_END_NAMESPACE_DETAIL
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
/**
+ * @brief Construct a heap over a range.
+ * @param __first Start of heap.
+ * @param __last End of heap.
+ * @ingroup heap_algorithms
+ *
+ * This operation makes the elements in [__first,__last) into a heap.
+ */
+ template<typename _RandomAccessIterator>
+ void
+ make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
+ {
+ // concept requirements
+ __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
+ _RandomAccessIterator>)
+ __glibcxx_function_requires(_LessThanComparableConcept<
+ typename iterator_traits<_RandomAccessIterator>::value_type>)
+ __glibcxx_requires_valid_range(__first, __last);
+
+ std::__detail::__make_heap(__first, __last,
+ __gnu_cxx::__ops
+ ::__iter_less_iter(__first));
+ }
+
+ /**
* @brief Construct a heap over a range using comparison functor.
* @param __first Start of heap.
* @param __last End of heap.
@@ -426,32 +407,36 @@
make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
_Compare __comp)
{
- typedef typename iterator_traits<_RandomAccessIterator>::value_type
- _ValueType;
- typedef typename iterator_traits<_RandomAccessIterator>::difference_type
- _DistanceType;
-
// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIterator>)
__glibcxx_requires_valid_range(__first, __last);
- if (__last - __first < 2)
- return;
+ std::__detail::__make_heap(__first, __last,
+ __gnu_cxx::__ops
+ ::__iter_comp_iter(__comp, __first));
+ }
- const _DistanceType __len = __last - __first;
- _DistanceType __parent = (__len - 2) / 2;
- while (true)
+_GLIBCXX_END_NAMESPACE_VERSION
+
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
+
+ template<typename _RandomAccessIterator, typename _Compare>
+ void
+ __sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
+ _Compare __comp)
+ {
+ while (__last - __first > 1)
{
- _ValueType __value = _GLIBCXX_MOVE(*(__first + __parent));
- std::__adjust_heap(__first, __parent, __len, _GLIBCXX_MOVE(__value),
- __comp);
- if (__parent == 0)
- return;
- __parent--;
+ --__last;
+ std::__detail::__pop_heap(__first, __last, __last, __comp);
}
}
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
/**
* @brief Sort a heap.
* @param __first Start of heap.
@@ -472,11 +457,9 @@
__glibcxx_requires_valid_range(__first, __last);
__glibcxx_requires_heap(__first, __last);
- while (__last - __first > 1)
- {
- --__last;
- std::__pop_heap(__first, __last, __last);
- }
+ std::__detail::__sort_heap(__first, __last,
+ __gnu_cxx::__ops
+ ::__iter_less_iter(__first));
}
/**
@@ -500,11 +483,9 @@
__glibcxx_requires_valid_range(__first, __last);
__glibcxx_requires_heap_pred(__first, __last, __comp);
- while (__last - __first > 1)
- {
- --__last;
- std::__pop_heap(__first, __last, __last, __comp);
- }
+ std::__detail::__sort_heap(__first, __last,
+ __gnu_cxx::__ops
+ ::__iter_comp_iter(__comp, __first));
}
#if __cplusplus >= 201103L
@@ -529,8 +510,10 @@
typename iterator_traits<_RandomAccessIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- return __first + std::__is_heap_until(__first, std::distance(__first,
- __last));
+ return __first +
+ std::__detail::__is_heap_until(__first, std::distance(__first, __last),
+ __gnu_cxx::__ops
+ ::__iter_less_iter(__first));
}
/**
@@ -554,9 +537,10 @@
_RandomAccessIterator>)
__glibcxx_requires_valid_range(__first, __last);
- return __first + std::__is_heap_until(__first, std::distance(__first,
- __last),
- __comp);
+ return __first
+ + std::__detail::__is_heap_until(__first, std::distance(__first, __last),
+ __gnu_cxx::__ops
+ ::__iter_comp_iter(__comp, __first));
}
/**
Index: include/bits/predefined_ops.h
===================================================================
--- include/bits/predefined_ops.h (revision 0)
+++ include/bits/predefined_ops.h (revision 0)
@@ -0,0 +1,537 @@
+// Default predicates for internal use -*- C++ -*-
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file predefined_ops.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef _GLIBCXX_PREDEFINED_OPS_H
+#define _GLIBCXX_PREDEFINED_OPS_H 1
+
+namespace __gnu_cxx
+{
+namespace __ops
+{
+ template<typename _Iterator1, typename _Iterator2 = _Iterator1>
+ struct _Iter_less_iter
+ {
+ bool
+ operator()(_Iterator1 __it1, _Iterator2 __it2)
+ { return *__it1 < *__it2; }
+ };
+
+ template<typename _Iterator>
+ inline _Iter_less_iter<_Iterator>
+ __iter_less_iter(_Iterator)
+ { return _Iter_less_iter<_Iterator>(); }
+
+ template<typename _Iterator1, typename _Iterator2>
+ inline _Iter_less_iter<_Iterator1, _Iterator2>
+ __iter_less_iter(_Iterator1, _Iterator2)
+ { return _Iter_less_iter<_Iterator1, _Iterator2>(); }
+
+ template<typename _Iterator, typename _Value>
+ struct _Iter_less_val
+ {
+ bool
+ operator()(_Iterator __it, _Value& __val)
+ { return *__it < __val; }
+ };
+
+ template<typename _Iterator, typename _Value>
+ inline _Iter_less_val<_Iterator, _Value>
+ __iter_less_val(_Iterator, const _Value&)
+ { return _Iter_less_val<_Iterator, _Value>(); }
+
+ template<typename _Iterator, typename _Value>
+ inline _Iter_less_val<_Iterator, _Value const>
+ __iter_less_cval(_Iterator, const _Value&)
+ { return _Iter_less_val<_Iterator, _Value const>(); }
+
+ template<typename _Value, typename _Iterator>
+ struct _Val_less_iter
+ {
+ bool
+ operator()(_Value& __val, _Iterator __it)
+ { return __val < *__it; }
+ };
+
+ template<typename _Value, typename _Iterator>
+ inline _Val_less_iter<_Value const, _Iterator>
+ __cval_less_iter(const _Value&, _Iterator)
+ { return _Val_less_iter<_Value const, _Iterator>(); }
+
+ template<typename _Iterator1, typename _Iterator2 = _Iterator1>
+ struct _Iter_equal_to_iter
+ {
+ bool
+ operator()(_Iterator1 __it1, _Iterator2 __it2)
+ { return *__it1 == *__it2; }
+ };
+
+ template<typename _Iterator>
+ inline _Iter_equal_to_iter<_Iterator>
+ __iter_equal_to_iter(_Iterator)
+ { return _Iter_equal_to_iter<_Iterator>(); }
+
+ template<typename _Iterator1, typename _Iterator2>
+ inline _Iter_equal_to_iter<_Iterator1, _Iterator2>
+ __iter_equal_to_iter(_Iterator1, _Iterator2)
+ { return _Iter_equal_to_iter<_Iterator1, _Iterator2>(); }
+
+ template<typename _Iterator, typename _Value>
+ struct _Iter_equal_to_val
+ {
+ bool
+ operator()(_Iterator __it, _Value& __val)
+ { return *__it == __val; }
+ };
+
+ template<typename _Iterator, typename _Value>
+ inline _Iter_equal_to_val<_Iterator, _Value const>
+ __iter_equal_to_cval(_Iterator, const _Value&)
+ { return _Iter_equal_to_val<_Iterator, _Value const>(); }
+
+ template<typename _Iterator1, typename _Iterator2,
+ typename _Compare>
+ struct _Iter_comp_iter
+ {
+ _Compare _M_comp;
+
+ _Iter_comp_iter(_Compare __comp)
+ : _M_comp(__comp)
+ {}
+
+ bool
+ operator()(_Iterator1 __it1, _Iterator2 __it2)
+ { return bool(_M_comp(*__it1, *__it2)); }
+ };
+
+ template<typename _Iterator, typename _Compare>
+ inline _Iter_comp_iter<_Iterator, _Iterator, _Compare>
+ __iter_comp_iter(_Compare __comp, _Iterator)
+ { return _Iter_comp_iter<_Iterator, _Iterator, _Compare>(__comp); }
+
+ template<typename _Iterator1, typename _Iterator2, typename _Compare>
+ inline _Iter_comp_iter<_Iterator1, _Iterator2, _Compare>
+ __iter_comp_iter(_Compare __comp, _Iterator1, _Iterator2)
+ { return _Iter_comp_iter<_Iterator1, _Iterator2, _Compare>(__comp); }
+
+ template<typename _Iterator, typename _Value,
+ typename _Compare>
+ struct _Iter_comp_val
+ {
+ _Compare _M_comp;
+
+ _Iter_comp_val(_Compare __comp)
+ : _M_comp(__comp)
+ {}
+
+ bool
+ operator()(_Iterator __it, _Value& __val)
+ { return bool(_M_comp(*__it, __val)); }
+ };
+
+ template<typename _Iterator, typename _Value, typename _Compare>
+ inline _Iter_comp_val<_Iterator, _Value, _Compare>
+ __iter_comp_val(_Compare __comp, _Iterator, _Value&)
+ { return _Iter_comp_val<_Iterator, _Value, _Compare>(__comp); }
+
+ template<typename _Iterator, typename _Value, typename _Compare>
+ inline _Iter_comp_val<_Iterator, const _Value, _Compare>
+ __iter_comp_cval(_Compare __comp, _Iterator, const _Value&)
+ { return _Iter_comp_val<_Iterator, const _Value, _Compare>(__comp); }
+
+ template<typename _Value, typename _Iterator,
+ typename _Compare>
+ struct _Val_comp_iter
+ {
+ _Compare _M_comp;
+
+ _Val_comp_iter(_Compare __comp)
+ : _M_comp(__comp)
+ {}
+
+ bool
+ operator()(_Value& __val, _Iterator __it)
+ { return bool(_M_comp(__val, *__it)); }
+ };
+
+ template<typename _Value, typename _Iterator, typename _Compare>
+ inline _Val_comp_iter<const _Value, _Iterator, _Compare>
+ __cval_comp_iter(_Compare __comp, const _Value&, _Iterator)
+ { return _Val_comp_iter<const _Value, _Iterator, _Compare>(__comp); }
+
+ template<typename _Iterator, typename _Value>
+ struct _Iter_equals_val
+ {
+ _Value& _M_value;
+
+ _Iter_equals_val(_Value& __value)
+ : _M_value(__value)
+ {}
+
+ bool
+ operator()(_Iterator __it)
+ { return *__it == _M_value; }
+ };
+
+ template<typename _Iterator1, typename _Iterator2,
+ bool = false>
+ struct _Iter_less_than_iter
+ {
+ typename std::iterator_traits<_Iterator2>::reference _M_value;
+
+ _Iter_less_than_iter(_Iterator2 __it2)
+ : _M_value(*__it2)
+ {}
+
+ bool
+ operator()(_Iterator1 __it1)
+ { return *__it1 < _M_value; }
+ };
+
+ template<typename _Iterator1, typename _Iterator2>
+ struct _Iter_less_than_iter<_Iterator1, _Iterator2, true>
+ {
+ typename std::iterator_traits<_Iterator1>::reference _M_value;
+
+ _Iter_less_than_iter(_Iterator1 __it1)
+ : _M_value(*__it1)
+ {}
+
+ bool
+ operator()(_Iterator2 __it2)
+ { return _M_value < *__it2; }
+ };
+
+ template<typename _Iterator1, typename _Iterator2,
+ bool = false>
+ struct _Iter_equals_iter
+ {
+ typename std::iterator_traits<_Iterator2>::reference _M_value;
+
+ _Iter_equals_iter(_Iterator2 __it2)
+ : _M_value(*__it2)
+ { }
+
+ bool
+ operator()(_Iterator1 __it1)
+ { return *__it1 == _M_value; }
+ };
+
+ template<typename _Iterator1, typename _Iterator2>
+ struct _Iter_equals_iter<_Iterator1, _Iterator2, true>
+ {
+ typename std::iterator_traits<_Iterator1>::reference _M_value;
+
+ _Iter_equals_iter(_Iterator1 __it1)
+ : _M_value(*__it1)
+ {}
+
+ bool
+ operator()(_Iterator2 __it2)
+ { return _M_value == *__it2; }
+ };
+
+ template<typename _Iterator, typename _Predicate>
+ struct _Iter_pred
+ {
+ _Predicate _M_pred;
+
+ _Iter_pred(_Predicate __pred)
+ : _M_pred(__pred)
+ { }
+
+ bool
+ operator()(_Iterator __it)
+ { return bool(_M_pred(*__it)); }
+ };
+
+ template<typename _Predicate, typename _Iterator>
+ inline _Iter_pred<_Iterator, _Predicate>
+ __pred_iter(_Predicate __pred, _Iterator)
+ { return _Iter_pred<_Iterator, _Predicate>(__pred); }
+
+ template<typename _Iterator, typename _Value,
+ typename _Compare>
+ struct _Iter_bind2nd_val
+ {
+ _Compare _M_comp;
+ _Value& _M_value;
+
+ _Iter_bind2nd_val(_Compare __comp, _Value& __value)
+ : _M_comp(__comp), _M_value(__value)
+ { }
+
+ bool
+ operator()(_Iterator __it)
+ { return bool(_M_comp(*__it, _M_value)); }
+ };
+
+ template<typename _Iterator1, typename _Iterator2,
+ typename _Compare>
+ struct _Iter_bind2nd_iter
+ {
+ _Compare _M_comp;
+ typename std::iterator_traits<_Iterator2>::reference _M_value;
+
+ _Iter_bind2nd_iter(_Compare __comp, _Iterator2 __it2)
+ : _M_comp(__comp), _M_value(*__it2)
+ { }
+
+ bool
+ operator()(_Iterator1 __it1)
+ { return bool(_M_comp(*__it1, _M_value)); }
+ };
+
+ template<typename _Iterator>
+ inline _Iter_less_than_iter<_Iterator, _Iterator>
+ __bind2nd(_Iter_less_iter<_Iterator, _Iterator>,
+ _Iterator __it)
+ { return _Iter_less_than_iter<_Iterator, _Iterator>(__it); }
+
+ template<typename _Iterator1, typename _Iterator2,
+ typename _Iterator>
+ inline _Iter_equals_iter<_Iterator1, _Iterator>
+ __bind2nd(_Iter_equal_to_iter<_Iterator1, _Iterator2>,
+ _Iterator __it)
+ { return _Iter_equals_iter<_Iterator1, _Iterator>(__it); }
+
+ template<typename _Iterator1, typename _Iterator2,
+ typename _Iterator, typename _Compare>
+ inline _Iter_bind2nd_iter<_Iterator1, _Iterator, _Compare>
+ __bind2nd(_Iter_comp_iter<_Iterator1, _Iterator2, _Compare> __comp,
+ _Iterator __it)
+ {
+ return _Iter_bind2nd_iter<_Iterator1, _Iterator,
+ _Compare>(__comp._M_comp, __it);
+ }
+
+ template<typename _Iterator, typename _Value>
+ inline _Iter_equals_val<_Iterator, _Value>
+ __bind2nd(_Iter_equal_to_val<_Iterator, _Value>, _Value& __value)
+ { return _Iter_equals_val<_Iterator, _Value>(__value); }
+
+ template<typename _Iterator, typename _Value, typename _Compare>
+ inline _Iter_bind2nd_val<_Iterator, _Value, _Compare>
+ __bind2nd(_Iter_comp_val<_Iterator, _Value, _Compare> __comp,
+ _Value& __value)
+ {
+ return _Iter_bind2nd_val<_Iterator, _Value, _Compare>(__comp._M_comp,
+ __value);
+ }
+
+ template<typename _Iterator, typename _Value>
+ inline _Iter_equals_val<_Iterator, _Value const>
+ __iter_equal_to_bound_cval(_Iterator __iter, const _Value& __val)
+ { return __bind2nd(__iter_equal_to_cval(__iter, __val), __val); }
+
+ template<typename _Iterator1, typename _Iterator2,
+ typename _Compare>
+ struct _Iter_bind1st_iter
+ {
+ _Compare _M_comp;
+ typename std::iterator_traits<_Iterator1>::reference _M_value;
+
+ _Iter_bind1st_iter(_Compare __comp, _Iterator1 __it1)
+ : _M_comp(__comp), _M_value(*__it1)
+ {}
+
+ bool
+ operator()(_Iterator2 __it2)
+ { return bool(_M_comp(_M_value, *__it2)); }
+ };
+
+ template<typename _Iterator>
+ inline _Iter_less_than_iter<_Iterator, _Iterator, true>
+ __bind1st(_Iter_less_iter<_Iterator, _Iterator>,
+ _Iterator __it)
+ { return _Iter_less_than_iter<_Iterator, _Iterator, true>(__it); }
+
+ template<typename _Iterator1, typename _Iterator2>
+ inline _Iter_equals_iter<_Iterator1, _Iterator2, true>
+ __bind1st(_Iter_equal_to_iter<_Iterator1, _Iterator2>,
+ _Iterator1 __it1)
+ { return _Iter_equals_iter<_Iterator1, _Iterator2, true>(__it1); }
+
+ template<typename _Iterator1, typename _Iterator2, typename _Compare>
+ inline _Iter_bind1st_iter<_Iterator1, _Iterator2, _Compare>
+ __bind1st(_Iter_comp_iter<_Iterator1, _Iterator2, _Compare> __comp,
+ _Iterator1 __it1)
+ {
+ return _Iter_bind1st_iter<_Iterator1, _Iterator2,
+ _Compare>(__comp._M_comp, __it1);
+ }
+
+ template<typename _Iterator, typename _Predicate>
+ struct _Iter_negate
+ {
+ _Predicate _M_pred;
+
+ _Iter_negate(_Predicate __pred)
+ : _M_pred(__pred)
+ {}
+
+ bool
+ operator()(_Iterator __it)
+ { return !bool(_M_pred(*__it)); }
+ };
+
+ template<typename _Iterator, typename _Predicate>
+ inline _Iter_negate<_Iterator, _Predicate>
+ __negate(_Iter_pred<_Iterator, _Predicate> __pred)
+ { return _Iter_negate<_Iterator, _Predicate>(__pred._M_pred); }
+
+ template<typename _Iterator,
+ typename _OtherIt1, typename _OtherIt2>
+ inline _Iter_less_iter<_Iterator>
+ __rebind(_Iter_less_iter<_OtherIt1, _OtherIt2>, _Iterator)
+ { return _Iter_less_iter<_Iterator>(); }
+
+ template<typename _Iterator1, typename _Iterator2,
+ typename _OtherIt1, typename _OtherIt2>
+ inline _Iter_less_iter<_Iterator1, _Iterator2>
+ __rebind(_Iter_less_iter<_OtherIt1, _OtherIt2>, _Iterator1, _Iterator2)
+ { return _Iter_less_iter<_Iterator1, _Iterator2>(); }
+
+ template<typename _Iterator,
+ typename _OtherIt1, typename _OtherIt2>
+ inline _Iter_equal_to_iter<_Iterator>
+ __rebind(_Iter_equal_to_iter<_OtherIt1, _OtherIt2>, _Iterator)
+ { return _Iter_equal_to_iter<_Iterator>(); }
+
+ template<typename _Iterator1, typename _Iterator2,
+ typename _OtherIt1, typename _OtherIt2>
+ inline _Iter_equal_to_iter<_Iterator1, _Iterator2>
+ __rebind(_Iter_equal_to_iter<_OtherIt1, _OtherIt2>, _Iterator1, _Iterator2)
+ { return _Iter_equal_to_iter<_Iterator1, _Iterator2>(); }
+
+ template<typename _Iterator,
+ typename _OtherIt1, typename _OtherIt2, typename _Compare>
+ inline _Iter_comp_iter<_Iterator, _Iterator, _Compare>
+ __rebind(_Iter_comp_iter<_OtherIt1, _OtherIt2, _Compare> __comp,
+ _Iterator)
+ { return _Iter_comp_iter<_Iterator, _Iterator, _Compare>(__comp._M_comp); }
+
+ template<typename _Iterator1, typename _Iterator2,
+ typename _OtherIt1, typename _OtherIt2, typename _Compare>
+ inline _Iter_comp_iter<_Iterator1, _Iterator2, _Compare>
+ __rebind(_Iter_comp_iter<_OtherIt1, _OtherIt2, _Compare> __comp,
+ _Iterator1, _Iterator2)
+ {
+ return _Iter_comp_iter<_Iterator1, _Iterator2, _Compare>(__comp._M_comp);
+ }
+
+ template<typename _Iterator1, typename _Iterator2,
+ typename _Value, typename _Compare>
+ inline _Iter_comp_val<_Iterator1, _Value, _Compare>
+ __rebind_iter_comp_val(_Iter_comp_iter<_Iterator1, _Iterator2,
+ _Compare> __comp,
+ const _Value&)
+ { return _Iter_comp_val<_Iterator1, _Value, _Compare>(__comp._M_comp); }
+
+ template<typename _Iterator1, typename _Iterator2, typename _Value>
+ inline _Iter_less_val<_Iterator1, _Value>
+ __rebind_iter_comp_val(_Iter_less_iter<_Iterator1, _Iterator2>,
+ const _Value&)
+ { return _Iter_less_val<_Iterator1, _Value>(); }
+
+ template<typename _Iterator1, typename _Iterator2, typename _Value>
+ inline _Iter_equal_to_val<_Iterator1, _Value>
+ __rebind_iter_comp_val(_Iter_equal_to_iter<_Iterator1, _Iterator2>,
+ const _Value&)
+ { return _Iter_equal_to_val<_Iterator1, _Value>(); }
+
+ template<typename _Iterator1, typename _Iterator2, typename _Compare>
+ inline _Iter_comp_val<_Iterator1,
+ typename std::iterator_traits<_Iterator1>::value_type const,
+ _Compare>
+ __rebind_iter_cval(_Iter_comp_iter<_Iterator1, _Iterator2, _Compare> __comp,
+ _Iterator1)
+ {
+ typedef typename std::iterator_traits<_Iterator1>::value_type _ValType;
+ return _Iter_comp_val<_Iterator1, _ValType const,
+ _Compare>(__comp._M_comp);
+ }
+
+ template<typename _Iterator1, typename _Iterator2>
+ inline _Iter_less_val<_Iterator1,
+ typename std::iterator_traits<_Iterator1>::value_type const>
+ __rebind_iter_cval(_Iter_less_iter<_Iterator1, _Iterator2>, _Iterator1)
+ {
+ typedef typename std::iterator_traits<_Iterator1>::value_type _ValType;
+ return _Iter_less_val<_Iterator1, _ValType const>();
+ }
+
+ template<typename _Iterator1, typename _Iterator2, typename _Compare>
+ inline _Val_comp_iter<typename std::iterator_traits<_Iterator1>::value_type,
+ _Iterator1, _Compare>
+ __rebind_val_comp_iter(_Iter_comp_iter<_Iterator1, _Iterator2,
+ _Compare> __comp,
+ _Iterator1)
+ {
+ typedef typename std::iterator_traits<_Iterator1>::value_type _ValType;
+ return _Val_comp_iter<_ValType, _Iterator1, _Compare>(__comp._M_comp);
+ }
+
+ template<typename _Iterator1, typename _Iterator2>
+ inline _Val_less_iter<typename std::iterator_traits<_Iterator1>::value_type,
+ _Iterator1>
+ __rebind_val_comp_iter(_Iter_less_iter<_Iterator1, _Iterator2>,
+ _Iterator1)
+ {
+ typedef typename std::iterator_traits<_Iterator1>::value_type _ValType;
+ return _Val_less_iter<_ValType, _Iterator1>();
+ }
+
+ template<typename _Iterator1, typename _Iterator2, typename _Compare>
+ inline _Val_comp_iter<
+ typename std::iterator_traits<_Iterator1>::value_type const,
+ _Iterator1, _Compare>
+ __rebind_cval_comp_iter(_Iter_comp_iter<_Iterator1, _Iterator2,
+ _Compare> __comp,
+ _Iterator1)
+ {
+ typedef typename std::iterator_traits<_Iterator1>::value_type _ValType;
+ return _Val_comp_iter<const _ValType, _Iterator1,
+ _Compare>(__comp._M_comp);
+ }
+
+ template<typename _Iterator1, typename _Iterator2>
+ inline _Val_less_iter<
+ typename std::iterator_traits<_Iterator1>::value_type const,
+ _Iterator1>
+ __rebind_cval_comp_iter(_Iter_less_iter<_Iterator1, _Iterator2>,
+ _Iterator1)
+ {
+ typedef typename std::iterator_traits<_Iterator1>::value_type _ValType;
+ return _Val_less_iter<const _ValType, _Iterator1>();
+ }
+
+} // namespace __ops
+} // namespace __gnu_cxx
+
+#endif
Property changes on: include/bits/predefined_ops.h
___________________________________________________________________
Added: svn:eol-style
+ native
Index: include/bits/stl_algo.h
===================================================================
--- include/bits/stl_algo.h (revision 202183)
+++ include/bits/stl_algo.h (working copy)
@@ -60,141 +60,51 @@
#include <bits/algorithmfwd.h>
#include <bits/stl_heap.h>
#include <bits/stl_tempbuf.h> // for _Temporary_buffer
+#include <bits/predefined_ops.h>
#if __cplusplus >= 201103L
#include <random> // for std::uniform_int_distribution
-#include <functional> // for std::bind
#endif
// See concept_check.h for the __glibcxx_*_requires macros.
namespace std _GLIBCXX_VISIBILITY(default)
{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
- /// Swaps the median value of *__a, *__b and *__c to *__a
- template<typename _Iterator>
- void
- __move_median_first(_Iterator __a, _Iterator __b, _Iterator __c)
- {
- // concept requirements
- __glibcxx_function_requires(_LessThanComparableConcept<
- typename iterator_traits<_Iterator>::value_type>)
-
- if (*__a < *__b)
- {
- if (*__b < *__c)
- std::iter_swap(__a, __b);
- else if (*__a < *__c)
- std::iter_swap(__a, __c);
- }
- else if (*__a < *__c)
- return;
- else if (*__b < *__c)
- std::iter_swap(__a, __c);
- else
- std::iter_swap(__a, __b);
- }
-
/// Swaps the median value of *__a, *__b and *__c under __comp to *__a
template<typename _Iterator, typename _Compare>
void
__move_median_first(_Iterator __a, _Iterator __b, _Iterator __c,
_Compare __comp)
{
- // concept requirements
- __glibcxx_function_requires(_BinaryFunctionConcept<_Compare, bool,
- typename iterator_traits<_Iterator>::value_type,
- typename iterator_traits<_Iterator>::value_type>)
-
- if (__comp(*__a, *__b))
+ if (__comp(__a, __b))
{
- if (__comp(*__b, *__c))
+ if (__comp(__b, __c))
std::iter_swap(__a, __b);
- else if (__comp(*__a, *__c))
+ else if (__comp(__a, __c))
std::iter_swap(__a, __c);
}
- else if (__comp(*__a, *__c))
+ else if (__comp(__a, __c))
return;
- else if (__comp(*__b, *__c))
+ else if (__comp(__b, __c))
std::iter_swap(__a, __c);
else
std::iter_swap(__a, __b);
}
- // for_each
-
- /// This is an overload used by find() for the Input Iterator case.
- template<typename _InputIterator, typename _Tp>
- inline _InputIterator
- __find(_InputIterator __first, _InputIterator __last,
- const _Tp& __val, input_iterator_tag)
- {
- while (__first != __last && !(*__first == __val))
- ++__first;
- return __first;
- }
-
- /// This is an overload used by find_if() for the Input Iterator case.
+ /// This is an overload used by find algos for the Input Iterator case.
template<typename _InputIterator, typename _Predicate>
inline _InputIterator
__find_if(_InputIterator __first, _InputIterator __last,
_Predicate __pred, input_iterator_tag)
{
- while (__first != __last && !bool(__pred(*__first)))
+ while (__first != __last && !__pred(__first))
++__first;
return __first;
}
- /// This is an overload used by find() for the RAI case.
- template<typename _RandomAccessIterator, typename _Tp>
- _RandomAccessIterator
- __find(_RandomAccessIterator __first, _RandomAccessIterator __last,
- const _Tp& __val, random_access_iterator_tag)
- {
- typename iterator_traits<_RandomAccessIterator>::difference_type
- __trip_count = (__last - __first) >> 2;
-
- for (; __trip_count > 0; --__trip_count)
- {
- if (*__first == __val)
- return __first;
- ++__first;
-
- if (*__first == __val)
- return __first;
- ++__first;
-
- if (*__first == __val)
- return __first;
- ++__first;
-
- if (*__first == __val)
- return __first;
- ++__first;
- }
-
- switch (__last - __first)
- {
- case 3:
- if (*__first == __val)
- return __first;
- ++__first;
- case 2:
- if (*__first == __val)
- return __first;
- ++__first;
- case 1:
- if (*__first == __val)
- return __first;
- ++__first;
- case 0:
- default:
- return __last;
- }
- }
-
- /// This is an overload used by find_if() for the RAI case.
+ /// This is an overload used by find algos for the RAI case.
template<typename _RandomAccessIterator, typename _Predicate>
_RandomAccessIterator
__find_if(_RandomAccessIterator __first, _RandomAccessIterator __last,
@@ -205,19 +115,19 @@
for (; __trip_count > 0; --__trip_count)
{
- if (__pred(*__first))
+ if (__pred(__first))
return __first;
++__first;
- if (__pred(*__first))
+ if (__pred(__first))
return __first;
++__first;
- if (__pred(*__first))
+ if (__pred(__first))
return __first;
++__first;
- if (__pred(*__first))
+ if (__pred(__first))
return __first;
++__first;
}
@@ -225,15 +135,15 @@
switch (__last - __first)
{
case 3:
- if (__pred(*__first))
+ if (__pred(__first))
return __first;
++__first;
case 2:
- if (__pred(*__first))
+ if (__pred(__first))
return __first;
++__first;
case 1:
- if (__pred(*__first))
+ if (__pred(__first))
return __first;
++__first;
case 0:
@@ -242,73 +152,23 @@
}
}
- /// This is an overload used by find_if_not() for the Input Iterator case.
- template<typename _InputIterator, typename _Predicate>
- inline _InputIterator
- __find_if_not(_InputIterator __first, _InputIterator __last,
- _Predicate __pred, input_iterator_tag)
+ template<typename _Iterator, typename _Predicate>
+ inline _Iterator
+ __find_if(_Iterator __first, _Iterator __last, _Predicate __pred)
{
- while (__first != __last && bool(__pred(*__first)))
- ++__first;
- return __first;
+ return __find_if(__first, __last, __pred,
+ std::__iterator_category(__first));
}
- /// This is an overload used by find_if_not() for the RAI case.
- template<typename _RandomAccessIterator, typename _Predicate>
- _RandomAccessIterator
- __find_if_not(_RandomAccessIterator __first, _RandomAccessIterator __last,
- _Predicate __pred, random_access_iterator_tag)
- {
- typename iterator_traits<_RandomAccessIterator>::difference_type
- __trip_count = (__last - __first) >> 2;
-
- for (; __trip_count > 0; --__trip_count)
- {
- if (!bool(__pred(*__first)))
- return __first;
- ++__first;
-
- if (!bool(__pred(*__first)))
- return __first;
- ++__first;
-
- if (!bool(__pred(*__first)))
- return __first;
- ++__first;
-
- if (!bool(__pred(*__first)))
- return __first;
- ++__first;
- }
-
- switch (__last - __first)
- {
- case 3:
- if (!bool(__pred(*__first)))
- return __first;
- ++__first;
- case 2:
- if (!bool(__pred(*__first)))
- return __first;
- ++__first;
- case 1:
- if (!bool(__pred(*__first)))
- return __first;
- ++__first;
- case 0:
- default:
- return __last;
- }
- }
-
/// Provided for stable_partition to use.
template<typename _InputIterator, typename _Predicate>
inline _InputIterator
__find_if_not(_InputIterator __first, _InputIterator __last,
_Predicate __pred)
{
- return std::__find_if_not(__first, __last, __pred,
- std::__iterator_category(__first));
+ return __find_if(__first, __last,
+ __gnu_cxx::__ops::__negate(__pred),
+ std::__iterator_category(__first));
}
/// Like find_if_not(), but uses and updates a count of the
@@ -319,7 +179,7 @@
__find_if_not_n(_InputIterator __first, _Distance& __len, _Predicate __pred)
{
for (; __len; --__len, ++__first)
- if (!bool(__pred(*__first)))
+ if (!__pred(__first))
break;
return __first;
}
@@ -337,113 +197,75 @@
// count_if
// search
- /**
- * This is an uglified
- * search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&)
- * overloaded for forward iterators.
- */
- template<typename _ForwardIterator, typename _Integer, typename _Tp>
- _ForwardIterator
- __search_n(_ForwardIterator __first, _ForwardIterator __last,
- _Integer __count, const _Tp& __val,
- std::forward_iterator_tag)
+ template<typename _ForwardIterator1, typename _ForwardIterator2,
+ typename _BinaryPredicate>
+ _ForwardIterator1
+ __search(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
+ _ForwardIterator2 __first2, _ForwardIterator2 __last2,
+ _BinaryPredicate __predicate)
{
- __first = _GLIBCXX_STD_A::find(__first, __last, __val);
- while (__first != __last)
- {
- typename iterator_traits<_ForwardIterator>::difference_type
- __n = __count;
- _ForwardIterator __i = __first;
- ++__i;
- while (__i != __last && __n != 1 && *__i == __val)
- {
- ++__i;
- --__n;
- }
- if (__n == 1)
- return __first;
- if (__i == __last)
- return __last;
- __first = _GLIBCXX_STD_A::find(++__i, __last, __val);
- }
- return __last;
- }
+ // Test for empty ranges
+ if (__first1 == __last1 || __first2 == __last2)
+ return __first1;
- /**
- * This is an uglified
- * search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&)
- * overloaded for random access iterators.
- */
- template<typename _RandomAccessIter, typename _Integer, typename _Tp>
- _RandomAccessIter
- __search_n(_RandomAccessIter __first, _RandomAccessIter __last,
- _Integer __count, const _Tp& __val,
- std::random_access_iterator_tag)
- {
-
- typedef typename std::iterator_traits<_RandomAccessIter>::difference_type
- _DistanceType;
+ // Test for a pattern of length 1.
+ _ForwardIterator2 __p1(__first2);
+ if (++__p1 == __last2)
+ return std::__detail::__find_if(__first1, __last1,
+ __gnu_cxx::__ops
+ ::__bind2nd(__predicate, __first2));
- _DistanceType __tailSize = __last - __first;
- const _DistanceType __pattSize = __count;
+ // General case.
+ _ForwardIterator2 __p;
+ _ForwardIterator1 __current = __first1;
- if (__tailSize < __pattSize)
- return __last;
+ for (;;)
+ {
+ __first1 =
+ std::__detail::__find_if(__first1, __last1,
+ __gnu_cxx::__ops
+ ::__bind2nd(__predicate, __first2));
- const _DistanceType __skipOffset = __pattSize - 1;
- _RandomAccessIter __lookAhead = __first + __skipOffset;
- __tailSize -= __pattSize;
+ if (__first1 == __last1)
+ return __last1;
- while (1) // the main loop...
- {
- // __lookAhead here is always pointing to the last element of next
- // possible match.
- while (!(*__lookAhead == __val)) // the skip loop...
+ __p = __p1;
+ __current = __first1;
+ if (++__current == __last1)
+ return __last1;
+
+ while (__predicate(__current, __p))
{
- if (__tailSize < __pattSize)
- return __last; // Failure
- __lookAhead += __pattSize;
- __tailSize -= __pattSize;
+ if (++__p == __last2)
+ return __first1;
+ if (++__current == __last1)
+ return __last1;
}
- _DistanceType __remainder = __skipOffset;
- for (_RandomAccessIter __backTrack = __lookAhead - 1;
- *__backTrack == __val; --__backTrack)
- {
- if (--__remainder == 0)
- return (__lookAhead - __skipOffset); // Success
- }
- if (__remainder > __tailSize)
- return __last; // Failure
- __lookAhead += __remainder;
- __tailSize -= __remainder;
+ ++__first1;
}
+ return __first1;
}
// search_n
/**
- * This is an uglified
- * search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&,
- * _BinaryPredicate)
- * overloaded for forward iterators.
+ * This is an helper function for search_n overloaded for forward iterators.
*/
- template<typename _ForwardIterator, typename _Integer, typename _Tp,
- typename _BinaryPredicate>
+ template<typename _ForwardIterator, typename _Integer,
+ typename _UnaryPredicate>
_ForwardIterator
- __search_n(_ForwardIterator __first, _ForwardIterator __last,
- _Integer __count, const _Tp& __val,
- _BinaryPredicate __binary_pred, std::forward_iterator_tag)
+ __search_n_aux(_ForwardIterator __first, _ForwardIterator __last,
+ _Integer __count,
+ _UnaryPredicate __unary_pred, std::forward_iterator_tag)
{
- while (__first != __last && !bool(__binary_pred(*__first, __val)))
- ++__first;
-
+ __first = std::__detail::__find_if(__first, __last, __unary_pred);
while (__first != __last)
{
typename iterator_traits<_ForwardIterator>::difference_type
__n = __count;
_ForwardIterator __i = __first;
++__i;
- while (__i != __last && __n != 1 && bool(__binary_pred(*__i, __val)))
+ while (__i != __last && __n != 1 && __unary_pred(__i))
{
++__i;
--__n;
@@ -452,29 +274,25 @@
return __first;
if (__i == __last)
return __last;
- __first = ++__i;
- while (__first != __last
- && !bool(__binary_pred(*__first, __val)))
- ++__first;
+ __first
+ = std::__detail::__find_if(++__i, __last, __unary_pred);
}
return __last;
}
/**
- * This is an uglified
- * search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&,
- * _BinaryPredicate)
- * overloaded for random access iterators.
+ * This is an helper function for search_n overloaded for random access
+ * iterators.
*/
- template<typename _RandomAccessIter, typename _Integer, typename _Tp,
- typename _BinaryPredicate>
+ template<typename _RandomAccessIter, typename _Integer,
+ typename _UnaryPredicate>
_RandomAccessIter
- __search_n(_RandomAccessIter __first, _RandomAccessIter __last,
- _Integer __count, const _Tp& __val,
- _BinaryPredicate __binary_pred, std::random_access_iterator_tag)
+ __search_n_aux(_RandomAccessIter __first, _RandomAccessIter __last,
+ _Integer __count,
+ _UnaryPredicate __unary_pred,
+ std::random_access_iterator_tag)
{
-
- typedef typename std::iterator_traits<_RandomAccessIter>::difference_type
+ typedef typename iterator_traits<_RandomAccessIter>::difference_type
_DistanceType;
_DistanceType __tailSize = __last - __first;
@@ -491,7 +309,7 @@
{
// __lookAhead here is always pointing to the last element of next
// possible match.
- while (!bool(__binary_pred(*__lookAhead, __val))) // the skip loop...
+ while (!__unary_pred(__lookAhead)) // the skip loop...
{
if (__tailSize < __pattSize)
return __last; // Failure
@@ -500,7 +318,7 @@
}
_DistanceType __remainder = __skipOffset;
for (_RandomAccessIter __backTrack = __lookAhead - 1;
- __binary_pred(*__backTrack, __val); --__backTrack)
+ __unary_pred(__backTrack); --__backTrack)
{
if (--__remainder == 0)
return (__lookAhead - __skipOffset); // Success
@@ -512,34 +330,26 @@
}
}
- // find_end for forward iterators.
- template<typename _ForwardIterator1, typename _ForwardIterator2>
- _ForwardIterator1
- __find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
- _ForwardIterator2 __first2, _ForwardIterator2 __last2,
- forward_iterator_tag, forward_iterator_tag)
+ template<typename _ForwardIterator, typename _Integer,
+ typename _UnaryPredicate>
+ _ForwardIterator
+ __search_n(_ForwardIterator __first, _ForwardIterator __last,
+ _Integer __count,
+ _UnaryPredicate __unary_pred)
{
- if (__first2 == __last2)
- return __last1;
- else
- {
- _ForwardIterator1 __result = __last1;
- while (1)
- {
- _ForwardIterator1 __new_result
- = _GLIBCXX_STD_A::search(__first1, __last1, __first2, __last2);
- if (__new_result == __last1)
- return __result;
- else
- {
- __result = __new_result;
- __first1 = __new_result;
- ++__first1;
- }
- }
- }
+ if (__count <= 0)
+ return __first;
+
+ if (__count == 1)
+ return
+ std::__detail::__find_if(__first, __last, __unary_pred);
+
+ return std::__detail::__search_n_aux(__first, __last, __count,
+ __unary_pred,
+ std::__iterator_category(__first));
}
+ // find_end for forward iterators.
template<typename _ForwardIterator1, typename _ForwardIterator2,
typename _BinaryPredicate>
_ForwardIterator1
@@ -550,61 +360,25 @@
{
if (__first2 == __last2)
return __last1;
- else
+
+ _ForwardIterator1 __result = __last1;
+ while (1)
{
- _ForwardIterator1 __result = __last1;
- while (1)
+ _ForwardIterator1 __new_result
+ = std::__detail::__search(__first1, __last1,
+ __first2, __last2, __comp);
+ if (__new_result == __last1)
+ return __result;
+ else
{
- _ForwardIterator1 __new_result
- = _GLIBCXX_STD_A::search(__first1, __last1, __first2,
- __last2, __comp);
- if (__new_result == __last1)
- return __result;
- else
- {
- __result = __new_result;
- __first1 = __new_result;
- ++__first1;
- }
+ __result = __new_result;
+ __first1 = __new_result;
+ ++__first1;
}
}
}
// find_end for bidirectional iterators (much faster).
- template<typename _BidirectionalIterator1, typename _BidirectionalIterator2>
- _BidirectionalIterator1
- __find_end(_BidirectionalIterator1 __first1,
- _BidirectionalIterator1 __last1,
- _BidirectionalIterator2 __first2,
- _BidirectionalIterator2 __last2,
- bidirectional_iterator_tag, bidirectional_iterator_tag)
- {
- // concept requirements
- __glibcxx_function_requires(_BidirectionalIteratorConcept<
- _BidirectionalIterator1>)
- __glibcxx_function_requires(_BidirectionalIteratorConcept<
- _BidirectionalIterator2>)
-
- typedef reverse_iterator<_BidirectionalIterator1> _RevIterator1;
- typedef reverse_iterator<_BidirectionalIterator2> _RevIterator2;
-
- _RevIterator1 __rlast1(__first1);
- _RevIterator2 __rlast2(__first2);
- _RevIterator1 __rresult = _GLIBCXX_STD_A::search(_RevIterator1(__last1),
- __rlast1,
- _RevIterator2(__last2),
- __rlast2);
-
- if (__rresult == __rlast1)
- return __last1;
- else
- {
- _BidirectionalIterator1 __result = __rresult.base();
- std::advance(__result, -std::distance(__first2, __last2));
- return __result;
- }
- }
-
template<typename _BidirectionalIterator1, typename _BidirectionalIterator2,
typename _BinaryPredicate>
_BidirectionalIterator1
@@ -626,20 +400,23 @@
_RevIterator1 __rlast1(__first1);
_RevIterator2 __rlast2(__first2);
- _RevIterator1 __rresult = std::search(_RevIterator1(__last1), __rlast1,
- _RevIterator2(__last2), __rlast2,
- __comp);
+ _RevIterator1 __rresult =
+ std::__detail::__search
+ (_RevIterator1(__last1), __rlast1, _RevIterator2(__last2), __rlast2,
+ __gnu_cxx::__ops::__rebind(__comp, __rlast1, __rlast2));
if (__rresult == __rlast1)
return __last1;
- else
- {
- _BidirectionalIterator1 __result = __rresult.base();
- std::advance(__result, -std::distance(__first2, __last2));
- return __result;
- }
+
+ _BidirectionalIterator1 __result = __rresult.base();
+ std::advance(__result, -std::distance(__first2, __last2));
+ return __result;
}
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
/**
* @brief Find last matching subsequence in a sequence.
* @ingroup non_mutating_algorithms
@@ -680,9 +457,9 @@
__glibcxx_requires_valid_range(__first1, __last1);
__glibcxx_requires_valid_range(__first2, __last2);
- return std::__find_end(__first1, __last1, __first2, __last2,
- std::__iterator_category(__first1),
- std::__iterator_category(__first2));
+ return std::__detail::__find_end(__first1, __last1, __first2, __last2,
+ std::__iterator_category(__first1), std::__iterator_category(__first2),
+ __gnu_cxx::__ops::__iter_equal_to_iter(__first1, __first2));
}
/**
@@ -729,10 +506,9 @@
__glibcxx_requires_valid_range(__first1, __last1);
__glibcxx_requires_valid_range(__first2, __last2);
- return std::__find_end(__first1, __last1, __first2, __last2,
- std::__iterator_category(__first1),
- std::__iterator_category(__first2),
- __comp);
+ return std::__detail::__find_end(__first1, __last1, __first2, __last2,
+ std::__iterator_category(__first1), std::__iterator_category(__first2),
+ __gnu_cxx::__ops::__iter_comp_iter(__comp, __first1, __first2));
}
#if __cplusplus >= 201103L
@@ -808,7 +584,8 @@
__glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
typename iterator_traits<_InputIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- return std::__find_if_not(__first, __last, __pred);
+ return std::__detail::__find_if_not(__first, __last,
+ __gnu_cxx::__ops::__pred_iter(__pred, __first));
}
/**
@@ -877,7 +654,29 @@
}
#endif
+_GLIBCXX_END_NAMESPACE_VERSION
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
+
+ template<typename _InputIterator, typename _OutputIterator,
+ typename _Predicate>
+ _OutputIterator
+ __remove_copy_if(_InputIterator __first, _InputIterator __last,
+ _OutputIterator __result, _Predicate __pred)
+ {
+ for (; __first != __last; ++__first)
+ if (!__pred(__first))
+ {
+ *__result = *__first;
+ ++__result;
+ }
+ return __result;
+ }
+
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
/**
* @brief Copy a sequence, removing elements of a given value.
* @ingroup mutating_algorithms
@@ -905,13 +704,8 @@
typename iterator_traits<_InputIterator>::value_type, _Tp>)
__glibcxx_requires_valid_range(__first, __last);
- for (; __first != __last; ++__first)
- if (!(*__first == __value))
- {
- *__result = *__first;
- ++__result;
- }
- return __result;
+ return std::__detail::__remove_copy_if(__first, __last, __result,
+ __gnu_cxx::__ops::__iter_equal_to_bound_cval(__first, __value));
}
/**
@@ -943,13 +737,8 @@
typename iterator_traits<_InputIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- for (; __first != __last; ++__first)
- if (!bool(__pred(*__first)))
- {
- *__result = *__first;
- ++__result;
- }
- return __result;
+ return std::__detail::__remove_copy_if(__first, __last, __result,
+ __gnu_cxx::__ops::__pred_iter(__pred, __first));
}
#if __cplusplus >= 201103L
@@ -991,7 +780,10 @@
return __result;
}
+_GLIBCXX_END_NAMESPACE_VERSION
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
+
template<typename _InputIterator, typename _Size, typename _OutputIterator>
_OutputIterator
__copy_n(_InputIterator __first, _Size __n,
@@ -1019,6 +811,10 @@
_OutputIterator __result, random_access_iterator_tag)
{ return std::copy(__first, __first + __n, __result); }
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
/**
* @brief Copies the range [first,first+n) into [result,result+n).
* @ingroup mutating_algorithms
@@ -1041,7 +837,7 @@
__glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
typename iterator_traits<_InputIterator>::value_type>)
- return std::__copy_n(__first, __n, __result,
+ return std::__detail::__copy_n(__first, __n, __result,
std::__iterator_category(__first));
}
@@ -1093,6 +889,33 @@
}
#endif
+_GLIBCXX_END_NAMESPACE_VERSION
+
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
+
+ template<typename _ForwardIterator, typename _Predicate>
+ _ForwardIterator
+ __remove_if(_ForwardIterator __first, _ForwardIterator __last,
+ _Predicate __pred)
+ {
+ __first = std::__detail::__find_if(__first, __last, __pred);
+ if (__first == __last)
+ return __first;
+ _ForwardIterator __result = __first;
+ ++__first;
+ for (; __first != __last; ++__first)
+ if (!__pred(__first))
+ {
+ *__result = _GLIBCXX_MOVE(*__first);
+ ++__result;
+ }
+ return __result;
+ }
+
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
/**
* @brief Remove elements from a sequence.
* @ingroup mutating_algorithms
@@ -1122,18 +945,8 @@
typename iterator_traits<_ForwardIterator>::value_type, _Tp>)
__glibcxx_requires_valid_range(__first, __last);
- __first = _GLIBCXX_STD_A::find(__first, __last, __value);
- if(__first == __last)
- return __first;
- _ForwardIterator __result = __first;
- ++__first;
- for(; __first != __last; ++__first)
- if(!(*__first == __value))
- {
- *__result = _GLIBCXX_MOVE(*__first);
- ++__result;
- }
- return __result;
+ return std::__detail::__remove_if(__first, __last,
+ __gnu_cxx::__ops::__iter_equal_to_bound_cval(__first, __value));
}
/**
@@ -1165,20 +978,54 @@
typename iterator_traits<_ForwardIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- __first = _GLIBCXX_STD_A::find_if(__first, __last, __pred);
- if(__first == __last)
- return __first;
- _ForwardIterator __result = __first;
+ return std::__detail::__remove_if(__first, __last,
+ __gnu_cxx::__ops::__pred_iter(__pred, __first));
+ }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
+
+ template<typename _ForwardIterator, typename _BinaryPredicate>
+ _ForwardIterator
+ __adjacent_find(_ForwardIterator __first, _ForwardIterator __last,
+ _BinaryPredicate __binary_pred)
+ {
+ if (__first == __last)
+ return __last;
+ _ForwardIterator __next = __first;
+ while (++__next != __last)
+ {
+ if (__binary_pred(__first, __next))
+ return __first;
+ __first = __next;
+ }
+ return __last;
+ }
+
+ template<typename _ForwardIterator, typename _BinaryPredicate>
+ _ForwardIterator
+ __unique(_ForwardIterator __first, _ForwardIterator __last,
+ _BinaryPredicate __binary_pred)
+ {
+ // Skip the beginning, if already unique.
+ __first = std::__detail::__adjacent_find(__first, __last, __binary_pred);
+ if (__first == __last)
+ return __last;
+
+ // Do the real copy work.
+ _ForwardIterator __dest = __first;
++__first;
- for(; __first != __last; ++__first)
- if(!bool(__pred(*__first)))
- {
- *__result = _GLIBCXX_MOVE(*__first);
- ++__result;
- }
- return __result;
+ while (++__first != __last)
+ if (!__binary_pred(__dest, __first))
+ *++__dest = _GLIBCXX_MOVE(*__first);
+ return ++__dest;
}
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
/**
* @brief Remove consecutive duplicate values from a sequence.
* @ingroup mutating_algorithms
@@ -1204,18 +1051,8 @@
typename iterator_traits<_ForwardIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- // Skip the beginning, if already unique.
- __first = _GLIBCXX_STD_A::adjacent_find(__first, __last);
- if (__first == __last)
- return __last;
-
- // Do the real copy work.
- _ForwardIterator __dest = __first;
- ++__first;
- while (++__first != __last)
- if (!(*__dest == *__first))
- *++__dest = _GLIBCXX_MOVE(*__first);
- return ++__dest;
+ return std::__detail::__unique(__first, __last,
+ __gnu_cxx::__ops::__iter_equal_to_iter(__first));
}
/**
@@ -1246,86 +1083,15 @@
typename iterator_traits<_ForwardIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- // Skip the beginning, if already unique.
- __first = _GLIBCXX_STD_A::adjacent_find(__first, __last, __binary_pred);
- if (__first == __last)
- return __last;
-
- // Do the real copy work.
- _ForwardIterator __dest = __first;
- ++__first;
- while (++__first != __last)
- if (!bool(__binary_pred(*__dest, *__first)))
- *++__dest = _GLIBCXX_MOVE(*__first);
- return ++__dest;
+ return std::__detail::__unique(__first, __last,
+ __gnu_cxx::__ops::__iter_comp_iter(__binary_pred, __first));
}
- /**
- * This is an uglified unique_copy(_InputIterator, _InputIterator,
- * _OutputIterator)
- * overloaded for forward iterators and output iterator as result.
- */
- template<typename _ForwardIterator, typename _OutputIterator>
- _OutputIterator
- __unique_copy(_ForwardIterator __first, _ForwardIterator __last,
- _OutputIterator __result,
- forward_iterator_tag, output_iterator_tag)
- {
- // concept requirements -- taken care of in dispatching function
- _ForwardIterator __next = __first;
- *__result = *__first;
- while (++__next != __last)
- if (!(*__first == *__next))
- {
- __first = __next;
- *++__result = *__first;
- }
- return ++__result;
- }
+_GLIBCXX_END_NAMESPACE_VERSION
- /**
- * This is an uglified unique_copy(_InputIterator, _InputIterator,
- * _OutputIterator)
- * overloaded for input iterators and output iterator as result.
- */
- template<typename _InputIterator, typename _OutputIterator>
- _OutputIterator
- __unique_copy(_InputIterator __first, _InputIterator __last,
- _OutputIterator __result,
- input_iterator_tag, output_iterator_tag)
- {
- // concept requirements -- taken care of in dispatching function
- typename iterator_traits<_InputIterator>::value_type __value = *__first;
- *__result = __value;
- while (++__first != __last)
- if (!(__value == *__first))
- {
- __value = *__first;
- *++__result = __value;
- }
- return ++__result;
- }
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
/**
- * This is an uglified unique_copy(_InputIterator, _InputIterator,
- * _OutputIterator)
- * overloaded for input iterators and forward iterator as result.
- */
- template<typename _InputIterator, typename _ForwardIterator>
- _ForwardIterator
- __unique_copy(_InputIterator __first, _InputIterator __last,
- _ForwardIterator __result,
- input_iterator_tag, forward_iterator_tag)
- {
- // concept requirements -- taken care of in dispatching function
- *__result = *__first;
- while (++__first != __last)
- if (!(*__result == *__first))
- *++__result = *__first;
- return ++__result;
- }
-
- /**
* This is an uglified
* unique_copy(_InputIterator, _InputIterator, _OutputIterator,
* _BinaryPredicate)
@@ -1338,15 +1104,11 @@
_OutputIterator __result, _BinaryPredicate __binary_pred,
forward_iterator_tag, output_iterator_tag)
{
- // concept requirements -- iterators already checked
- __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
- typename iterator_traits<_ForwardIterator>::value_type,
- typename iterator_traits<_ForwardIterator>::value_type>)
-
+ // concept requirements -- taken care of in dispatching function
_ForwardIterator __next = __first;
*__result = *__first;
while (++__next != __last)
- if (!bool(__binary_pred(*__first, *__next)))
+ if (!__binary_pred(__first, __next))
{
__first = __next;
*++__result = *__first;
@@ -1367,15 +1129,15 @@
_OutputIterator __result, _BinaryPredicate __binary_pred,
input_iterator_tag, output_iterator_tag)
{
- // concept requirements -- iterators already checked
- __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
- typename iterator_traits<_InputIterator>::value_type,
- typename iterator_traits<_InputIterator>::value_type>)
-
+ // concept requirements -- taken care of in dispatching function
typename iterator_traits<_InputIterator>::value_type __value = *__first;
+ __decltype(__gnu_cxx::__ops::__rebind_iter_comp_val(__binary_pred,
+ __value))
+ __rebound_pred
+ = __gnu_cxx::__ops::__rebind_iter_comp_val(__binary_pred, __value);
*__result = __value;
while (++__first != __last)
- if (!bool(__binary_pred(__value, *__first)))
+ if (!__rebound_pred(__first, __value))
{
__value = *__first;
*++__result = __value;
@@ -1396,14 +1158,13 @@
_ForwardIterator __result, _BinaryPredicate __binary_pred,
input_iterator_tag, forward_iterator_tag)
{
- // concept requirements -- iterators already checked
- __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
- typename iterator_traits<_ForwardIterator>::value_type,
- typename iterator_traits<_InputIterator>::value_type>)
-
+ // concept requirements -- taken care of in dispatching function
+ __decltype(__gnu_cxx::__ops::__rebind(__binary_pred, __result, __first))
+ __rebound_pred
+ = __gnu_cxx::__ops::__rebind(__binary_pred, __result, __first);
*__result = *__first;
while (++__first != __last)
- if (!bool(__binary_pred(*__result, *__first)))
+ if (!__rebound_pred(__result, __first))
*++__result = *__first;
return ++__result;
}
@@ -1449,6 +1210,10 @@
}
}
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
/**
* @brief Reverse a sequence.
* @ingroup mutating_algorithms
@@ -1469,7 +1234,9 @@
__glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept<
_BidirectionalIterator>)
__glibcxx_requires_valid_range(__first, __last);
- std::__reverse(__first, __last, std::__iterator_category(__first));
+
+ std::__detail::__reverse(__first, __last,
+ std::__iterator_category(__first));
}
/**
@@ -1509,6 +1276,10 @@
return __result;
}
+_GLIBCXX_END_NAMESPACE_VERSION
+
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
+
/**
* This is a helper function for the rotate algorithm specialized on RAIs.
* It returns the greatest common divisor of two integer values.
@@ -1568,7 +1339,7 @@
__rotate(_BidirectionalIterator __first,
_BidirectionalIterator __middle,
_BidirectionalIterator __last,
- bidirectional_iterator_tag)
+ bidirectional_iterator_tag __tag)
{
// concept requirements
__glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept<
@@ -1577,8 +1348,8 @@
if (__first == __middle || __last == __middle)
return;
- std::__reverse(__first, __middle, bidirectional_iterator_tag());
- std::__reverse(__middle, __last, bidirectional_iterator_tag());
+ std::__detail::__reverse(__first, __middle, __tag);
+ std::__detail::__reverse(__middle, __last, __tag);
while (__first != __middle && __middle != __last)
{
@@ -1587,9 +1358,9 @@
}
if (__first == __middle)
- std::__reverse(__middle, __last, bidirectional_iterator_tag());
+ std::__detail::__reverse(__middle, __last, __tag);
else
- std::__reverse(__first, __middle, bidirectional_iterator_tag());
+ std::__detail::__reverse(__first, __middle, __tag);
}
/// This is a helper function for the rotate algorithm.
@@ -1673,6 +1444,10 @@
}
}
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
/**
* @brief Rotate the elements of a sequence.
* @ingroup mutating_algorithms
@@ -1705,9 +1480,8 @@
__glibcxx_requires_valid_range(__first, __middle);
__glibcxx_requires_valid_range(__middle, __last);
- typedef typename iterator_traits<_ForwardIterator>::iterator_category
- _IterType;
- std::__rotate(__first, __middle, __last, _IterType());
+ std::__detail::__rotate(__first, __middle, __last,
+ std::__iterator_category(__first));
}
/**
@@ -1742,10 +1516,14 @@
__glibcxx_requires_valid_range(__first, __middle);
__glibcxx_requires_valid_range(__middle, __last);
- return std::copy(__first, __middle,
- std::copy(__middle, __last, __result));
+ return std::__detail::__copy(__first, __middle,
+ std::__detail::__copy(__middle, __last, __result));
}
+_GLIBCXX_END_NAMESPACE_VERSION
+
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
+
/// This is a helper function...
template<typename _ForwardIterator, typename _Predicate>
_ForwardIterator
@@ -1814,16 +1592,16 @@
_ForwardIterator __middle = __first;
std::advance(__middle, __len / 2);
_ForwardIterator __left_split =
- std::__inplace_stable_partition(__first, __pred, __len / 2);
+ std::__detail::__inplace_stable_partition(__first, __pred, __len / 2);
// Advance past true-predicate values to satisfy this
// function's preconditions.
_Distance __right_len = __len - __len / 2;
_ForwardIterator __right_split =
- std::__find_if_not_n(__middle, __right_len, __pred);
+ std::__detail::__find_if_not_n(__middle, __right_len, __pred);
if (__right_len)
- __right_split = std::__inplace_stable_partition(__middle,
- __pred,
- __right_len);
+ __right_split
+ = std::__detail::__inplace_stable_partition(__middle, __pred,
+ __right_len);
std::rotate(__left_split, __middle, __right_split);
std::advance(__left_split, std::distance(__middle, __right_split));
return __left_split;
@@ -1848,14 +1626,14 @@
{
_ForwardIterator __result1 = __first;
_Pointer __result2 = __buffer;
- // The precondition guarantees that !__pred(*__first), so
+ // The precondition guarantees that !__pred(__first), so
// move that element to the buffer before starting the loop.
// This ensures that we only call __pred once per element.
*__result2 = _GLIBCXX_MOVE(*__first);
++__result2;
++__first;
for (; __first != __last; ++__first)
- if (__pred(*__first))
+ if (__pred(__first))
{
*__result1 = _GLIBCXX_MOVE(*__first);
++__result1;
@@ -1872,26 +1650,63 @@
{
_ForwardIterator __middle = __first;
std::advance(__middle, __len / 2);
- _ForwardIterator __left_split =
- std::__stable_partition_adaptive(__first, __middle, __pred,
- __len / 2, __buffer,
- __buffer_size);
+ _ForwardIterator __left_split
+ = std::__detail::__stable_partition_adaptive(__first, __middle,
+ __pred, __len / 2,
+ __buffer,
+ __buffer_size);
// Advance past true-predicate values to satisfy this
// function's preconditions.
_Distance __right_len = __len - __len / 2;
_ForwardIterator __right_split =
- std::__find_if_not_n(__middle, __right_len, __pred);
+ std::__detail::__find_if_not_n(__middle, __right_len, __pred);
if (__right_len)
- __right_split =
- std::__stable_partition_adaptive(__right_split, __last, __pred,
- __right_len,
- __buffer, __buffer_size);
+ __right_split
+ = std::__detail::__stable_partition_adaptive(__right_split,
+ __last, __pred,
+ __right_len,
+ __buffer,
+ __buffer_size);
std::rotate(__left_split, __middle, __right_split);
std::advance(__left_split, std::distance(__middle, __right_split));
return __left_split;
}
}
+ template<typename _ForwardIterator, typename _Predicate>
+ _ForwardIterator
+ __stable_partition(_ForwardIterator __first, _ForwardIterator __last,
+ _Predicate __pred)
+ {
+ __first = std::__detail::__find_if_not(__first, __last, __pred);
+
+ if (__first == __last)
+ return __first;
+ else
+ {
+ typedef typename iterator_traits<_ForwardIterator>::value_type
+ _ValueType;
+ typedef typename iterator_traits<_ForwardIterator>::difference_type
+ _DistanceType;
+
+ _Temporary_buffer<_ForwardIterator, _ValueType> __buf(__first,
+ __last);
+ if (__buf.size() > 0)
+ return
+ std::__detail::__stable_partition_adaptive
+ (__first, __last, __pred, _DistanceType(__buf.requested_size()),
+ __buf.begin(), _DistanceType(__buf.size()));
+ else
+ return
+ std::__detail::__inplace_stable_partition(__first, __pred,
+ _DistanceType(__buf.requested_size()));
+ }
+ }
+
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
/**
* @brief Move elements for which a predicate is true to the beginning
* of a sequence, preserving relative ordering.
@@ -1921,60 +1736,74 @@
typename iterator_traits<_ForwardIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- __first = std::__find_if_not(__first, __last, __pred);
+ return std::__detail::__stable_partition(__first, __last,
+ __gnu_cxx::__ops::__pred_iter(__pred, __first));
+ }
- if (__first == __last)
- return __first;
- else
- {
- typedef typename iterator_traits<_ForwardIterator>::value_type
- _ValueType;
- typedef typename iterator_traits<_ForwardIterator>::difference_type
- _DistanceType;
+_GLIBCXX_END_NAMESPACE_VERSION
- _Temporary_buffer<_ForwardIterator, _ValueType> __buf(__first,
- __last);
- if (__buf.size() > 0)
- return
- std::__stable_partition_adaptive(__first, __last, __pred,
- _DistanceType(__buf.requested_size()),
- __buf.begin(),
- _DistanceType(__buf.size()));
- else
- return
- std::__inplace_stable_partition(__first, __pred,
- _DistanceType(__buf.requested_size()));
- }
- }
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
/// This is a helper function for the sort routines.
- template<typename _RandomAccessIterator>
- void
- __heap_select(_RandomAccessIterator __first,
- _RandomAccessIterator __middle,
- _RandomAccessIterator __last)
- {
- std::make_heap(__first, __middle);
- for (_RandomAccessIterator __i = __middle; __i < __last; ++__i)
- if (*__i < *__first)
- std::__pop_heap(__first, __middle, __i);
- }
-
- /// This is a helper function for the sort routines.
template<typename _RandomAccessIterator, typename _Compare>
void
__heap_select(_RandomAccessIterator __first,
_RandomAccessIterator __middle,
_RandomAccessIterator __last, _Compare __comp)
{
- std::make_heap(__first, __middle, __comp);
+ std::__detail::__make_heap(__first, __middle, __comp);
for (_RandomAccessIterator __i = __middle; __i < __last; ++__i)
- if (__comp(*__i, *__first))
- std::__pop_heap(__first, __middle, __i, __comp);
+ if (__comp(__i, __first))
+ std::__detail::__pop_heap(__first, __middle, __i, __comp);
}
// partial_sort
+ template<typename _InputIterator, typename _RandomAccessIterator,
+ typename _Compare>
+ _RandomAccessIterator
+ __partial_sort_copy(_InputIterator __first, _InputIterator __last,
+ _RandomAccessIterator __result_first,
+ _RandomAccessIterator __result_last,
+ _Compare __comp)
+ {
+ typedef typename iterator_traits<_InputIterator>::value_type
+ _InputValueType;
+ typedef iterator_traits<_RandomAccessIterator> _RItTraits;
+ typedef typename _RItTraits::difference_type _DistanceType;
+
+ if (__result_first == __result_last)
+ return __result_last;
+ _RandomAccessIterator __result_real_last = __result_first;
+ while (__first != __last && __result_real_last != __result_last)
+ {
+ *__result_real_last = *__first;
+ ++__result_real_last;
+ ++__first;
+ }
+
+ std::__detail::__make_heap(__result_first, __result_real_last,
+ __gnu_cxx::__ops::__rebind(__comp, __result_first));
+ while (__first != __last)
+ {
+ if (__comp(__first, __result_first))
+ std::__detail::__adjust_heap(__result_first, _DistanceType(0),
+ _DistanceType(__result_real_last
+ - __result_first),
+ _InputValueType(*__first),
+ __gnu_cxx::__ops::__rebind(__comp,
+ __result_first));
+ ++__first;
+ }
+ std::__detail::__sort_heap(__result_first, __result_real_last,
+ __gnu_cxx::__ops::__rebind(__comp, __result_first));
+ return __result_real_last;
+ }
+
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
/**
* @brief Copy the smallest elements of a sequence.
* @ingroup sorting_algorithms
@@ -2009,34 +1838,16 @@
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
__glibcxx_function_requires(_ConvertibleConcept<_InputValueType,
- _OutputValueType>)
+ _OutputValueType>)
__glibcxx_function_requires(_LessThanOpConcept<_InputValueType,
- _OutputValueType>)
+ _OutputValueType>)
__glibcxx_function_requires(_LessThanComparableConcept<_OutputValueType>)
__glibcxx_requires_valid_range(__first, __last);
__glibcxx_requires_valid_range(__result_first, __result_last);
- if (__result_first == __result_last)
- return __result_last;
- _RandomAccessIterator __result_real_last = __result_first;
- while(__first != __last && __result_real_last != __result_last)
- {
- *__result_real_last = *__first;
- ++__result_real_last;
- ++__first;
- }
- std::make_heap(__result_first, __result_real_last);
- while (__first != __last)
- {
- if (*__first < *__result_first)
- std::__adjust_heap(__result_first, _DistanceType(0),
- _DistanceType(__result_real_last
- - __result_first),
- _InputValueType(*__first));
- ++__first;
- }
- std::sort_heap(__result_first, __result_real_last);
- return __result_real_last;
+ return std::__detail::__partial_sort_copy(__first, __last,
+ __result_first, __result_last,
+ __gnu_cxx::__ops::__iter_less_iter(__first, __result_first));
}
/**
@@ -2059,7 +1870,8 @@
* @p __comp(*j,*i) is false.
* The value returned is @p __result_first+N.
*/
- template<typename _InputIterator, typename _RandomAccessIterator, typename _Compare>
+ template<typename _InputIterator, typename _RandomAccessIterator,
+ typename _Compare>
_RandomAccessIterator
partial_sort_copy(_InputIterator __first, _InputIterator __last,
_RandomAccessIterator __result_first,
@@ -2086,48 +1898,15 @@
__glibcxx_requires_valid_range(__first, __last);
__glibcxx_requires_valid_range(__result_first, __result_last);
- if (__result_first == __result_last)
- return __result_last;
- _RandomAccessIterator __result_real_last = __result_first;
- while(__first != __last && __result_real_last != __result_last)
- {
- *__result_real_last = *__first;
- ++__result_real_last;
- ++__first;
- }
- std::make_heap(__result_first, __result_real_last, __comp);
- while (__first != __last)
- {
- if (__comp(*__first, *__result_first))
- std::__adjust_heap(__result_first, _DistanceType(0),
- _DistanceType(__result_real_last
- - __result_first),
- _InputValueType(*__first),
- __comp);
- ++__first;
- }
- std::sort_heap(__result_first, __result_real_last, __comp);
- return __result_real_last;
+ return std::__detail::__partial_sort_copy(__first, __last,
+ __result_first, __result_last,
+ __gnu_cxx::__ops::__iter_comp_iter(__comp, __first, __result_first));
}
- /// This is a helper function for the sort routine.
- template<typename _RandomAccessIterator>
- void
- __unguarded_linear_insert(_RandomAccessIterator __last)
- {
- typename iterator_traits<_RandomAccessIterator>::value_type
- __val = _GLIBCXX_MOVE(*__last);
- _RandomAccessIterator __next = __last;
- --__next;
- while (__val < *__next)
- {
- *__last = _GLIBCXX_MOVE(*__next);
- __last = __next;
- --__next;
- }
- *__last = _GLIBCXX_MOVE(__val);
- }
+_GLIBCXX_END_NAMESPACE_VERSION
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
+
/// This is a helper function for the sort routine.
template<typename _RandomAccessIterator, typename _Compare>
void
@@ -2138,7 +1917,7 @@
__val = _GLIBCXX_MOVE(*__last);
_RandomAccessIterator __next = __last;
--__next;
- while (__comp(__val, *__next))
+ while (__comp(__val, __next))
{
*__last = _GLIBCXX_MOVE(*__next);
__last = __next;
@@ -2148,74 +1927,38 @@
}
/// This is a helper function for the sort routine.
- template<typename _RandomAccessIterator>
- void
- __insertion_sort(_RandomAccessIterator __first,
- _RandomAccessIterator __last)
- {
- if (__first == __last)
- return;
-
- for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)
- {
- if (*__i < *__first)
- {
- typename iterator_traits<_RandomAccessIterator>::value_type
- __val = _GLIBCXX_MOVE(*__i);
- _GLIBCXX_MOVE_BACKWARD3(__first, __i, __i + 1);
- *__first = _GLIBCXX_MOVE(__val);
- }
- else
- std::__unguarded_linear_insert(__i);
- }
- }
-
- /// This is a helper function for the sort routine.
template<typename _RandomAccessIterator, typename _Compare>
void
__insertion_sort(_RandomAccessIterator __first,
_RandomAccessIterator __last, _Compare __comp)
{
+ typedef iterator_traits<_RandomAccessIterator> _ItTraits;
+
if (__first == __last) return;
for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)
{
- if (__comp(*__i, *__first))
+ if (__comp(__i, __first))
{
- typename iterator_traits<_RandomAccessIterator>::value_type
- __val = _GLIBCXX_MOVE(*__i);
+ typename _ItTraits::value_type __val = _GLIBCXX_MOVE(*__i);
_GLIBCXX_MOVE_BACKWARD3(__first, __i, __i + 1);
*__first = _GLIBCXX_MOVE(__val);
}
else
- std::__unguarded_linear_insert(__i, __comp);
+ std::__detail::__unguarded_linear_insert(__i,
+ __gnu_cxx::__ops::__rebind_val_comp_iter(__comp, __first));
}
}
/// This is a helper function for the sort routine.
- template<typename _RandomAccessIterator>
- inline void
- __unguarded_insertion_sort(_RandomAccessIterator __first,
- _RandomAccessIterator __last)
- {
- typedef typename iterator_traits<_RandomAccessIterator>::value_type
- _ValueType;
-
- for (_RandomAccessIterator __i = __first; __i != __last; ++__i)
- std::__unguarded_linear_insert(__i);
- }
-
- /// This is a helper function for the sort routine.
template<typename _RandomAccessIterator, typename _Compare>
inline void
__unguarded_insertion_sort(_RandomAccessIterator __first,
_RandomAccessIterator __last, _Compare __comp)
{
- typedef typename iterator_traits<_RandomAccessIterator>::value_type
- _ValueType;
-
for (_RandomAccessIterator __i = __first; __i != __last; ++__i)
- std::__unguarded_linear_insert(__i, __comp);
+ std::__detail::__unguarded_linear_insert(__i,
+ __gnu_cxx::__ops::__rebind_val_comp_iter(__comp, __first));
}
/**
@@ -2225,21 +1968,6 @@
enum { _S_threshold = 16 };
/// This is a helper function for the sort routine.
- template<typename _RandomAccessIterator>
- void
- __final_insertion_sort(_RandomAccessIterator __first,
- _RandomAccessIterator __last)
- {
- if (__last - __first > int(_S_threshold))
- {
- std::__insertion_sort(__first, __first + int(_S_threshold));
- std::__unguarded_insertion_sort(__first + int(_S_threshold), __last);
- }
- else
- std::__insertion_sort(__first, __last);
- }
-
- /// This is a helper function for the sort routine.
template<typename _RandomAccessIterator, typename _Compare>
void
__final_insertion_sort(_RandomAccessIterator __first,
@@ -2247,47 +1975,30 @@
{
if (__last - __first > int(_S_threshold))
{
- std::__insertion_sort(__first, __first + int(_S_threshold), __comp);
- std::__unguarded_insertion_sort(__first + int(_S_threshold), __last,
+ std::__detail::__insertion_sort(__first, __first + int(_S_threshold),
__comp);
+ std::__detail::__unguarded_insertion_sort(__first + int(_S_threshold),
+ __last, __comp);
}
else
- std::__insertion_sort(__first, __last, __comp);
+ std::__detail::__insertion_sort(__first, __last, __comp);
}
/// This is a helper function...
- template<typename _RandomAccessIterator, typename _Tp>
+ template<typename _RandomAccessIterator,
+ typename _Pred1, typename _Pred2>
_RandomAccessIterator
__unguarded_partition(_RandomAccessIterator __first,
- _RandomAccessIterator __last, const _Tp& __pivot)
- {
- while (true)
- {
- while (*__first < __pivot)
- ++__first;
- --__last;
- while (__pivot < *__last)
- --__last;
- if (!(__first < __last))
- return __first;
- std::iter_swap(__first, __last);
- ++__first;
- }
- }
-
- /// This is a helper function...
- template<typename _RandomAccessIterator, typename _Tp, typename _Compare>
- _RandomAccessIterator
- __unguarded_partition(_RandomAccessIterator __first,
_RandomAccessIterator __last,
- const _Tp& __pivot, _Compare __comp)
+ _Pred1 __less_than_pivot,
+ _Pred2 __pivot_less_than)
{
while (true)
{
- while (__comp(*__first, __pivot))
+ while (__less_than_pivot(__first))
++__first;
--__last;
- while (__comp(__pivot, *__last))
+ while (__pivot_less_than(__last))
--__last;
if (!(__first < __last))
return __first;
@@ -2297,48 +2008,27 @@
}
/// This is a helper function...
- template<typename _RandomAccessIterator>
- inline _RandomAccessIterator
- __unguarded_partition_pivot(_RandomAccessIterator __first,
- _RandomAccessIterator __last)
- {
- _RandomAccessIterator __mid = __first + (__last - __first) / 2;
- std::__move_median_first(__first, __mid, (__last - 1));
- return std::__unguarded_partition(__first + 1, __last, *__first);
- }
-
-
- /// This is a helper function...
template<typename _RandomAccessIterator, typename _Compare>
inline _RandomAccessIterator
__unguarded_partition_pivot(_RandomAccessIterator __first,
_RandomAccessIterator __last, _Compare __comp)
{
_RandomAccessIterator __mid = __first + (__last - __first) / 2;
- std::__move_median_first(__first, __mid, (__last - 1), __comp);
- return std::__unguarded_partition(__first + 1, __last, *__first, __comp);
+ std::__detail::__move_median_first(__first, __mid, (__last - 1), __comp);
+ return std::__detail::__unguarded_partition(__first + 1, __last,
+ __gnu_cxx::__ops::__bind2nd(__comp, __first),
+ __gnu_cxx::__ops::__bind1st(__comp, __first));
}
- /// This is a helper function for the sort routine.
- template<typename _RandomAccessIterator, typename _Size>
- void
- __introsort_loop(_RandomAccessIterator __first,
- _RandomAccessIterator __last,
- _Size __depth_limit)
+ template<typename _RandomAccessIterator, typename _Compare>
+ inline void
+ __partial_sort(_RandomAccessIterator __first,
+ _RandomAccessIterator __middle,
+ _RandomAccessIterator __last,
+ _Compare __comp)
{
- while (__last - __first > int(_S_threshold))
- {
- if (__depth_limit == 0)
- {
- _GLIBCXX_STD_A::partial_sort(__first, __last, __last);
- return;
- }
- --__depth_limit;
- _RandomAccessIterator __cut =
- std::__unguarded_partition_pivot(__first, __last);
- std::__introsort_loop(__cut, __last, __depth_limit);
- __last = __cut;
- }
+ std::__detail::__heap_select(__first, __middle, __last, __comp);
+ std::__detail::__sort_heap(__first, __middle, __comp);
}
/// This is a helper function for the sort routine.
@@ -2352,46 +2042,31 @@
{
if (__depth_limit == 0)
{
- _GLIBCXX_STD_A::partial_sort(__first, __last, __last, __comp);
+ std::__detail::__partial_sort(__first, __last, __last, __comp);
return;
}
--__depth_limit;
_RandomAccessIterator __cut =
- std::__unguarded_partition_pivot(__first, __last, __comp);
- std::__introsort_loop(__cut, __last, __depth_limit, __comp);
+ std::__detail::__unguarded_partition_pivot(__first, __last, __comp);
+ std::__detail::__introsort_loop(__cut, __last, __depth_limit, __comp);
__last = __cut;
}
}
// sort
- template<typename _RandomAccessIterator, typename _Size>
- void
- __introselect(_RandomAccessIterator __first, _RandomAccessIterator __nth,
- _RandomAccessIterator __last, _Size __depth_limit)
+ template<typename _RandomAccessIterator, typename _Compare>
+ inline void
+ __sort(_RandomAccessIterator __first, _RandomAccessIterator __last,
+ _Compare __comp)
{
- typedef typename iterator_traits<_RandomAccessIterator>::value_type
- _ValueType;
-
- while (__last - __first > 3)
+ if (__first != __last)
{
- if (__depth_limit == 0)
- {
- std::__heap_select(__first, __nth + 1, __last);
-
- // Place the nth largest element in its final position.
- std::iter_swap(__first, __nth);
- return;
- }
- --__depth_limit;
- _RandomAccessIterator __cut =
- std::__unguarded_partition_pivot(__first, __last);
- if (__cut <= __nth)
- __first = __cut;
- else
- __last = __cut;
+ std::__detail::__introsort_loop(__first, __last,
+ std::__detail::__lg(__last - __first) * 2,
+ __comp);
+ std::__detail::__final_insertion_sort(__first, __last, __comp);
}
- std::__insertion_sort(__first, __last);
}
template<typename _RandomAccessIterator, typename _Size, typename _Compare>
@@ -2400,29 +2075,30 @@
_RandomAccessIterator __last, _Size __depth_limit,
_Compare __comp)
{
- typedef typename iterator_traits<_RandomAccessIterator>::value_type
- _ValueType;
-
while (__last - __first > 3)
{
if (__depth_limit == 0)
{
- std::__heap_select(__first, __nth + 1, __last, __comp);
+ std::__detail::__heap_select(__first, __nth + 1, __last, __comp);
// Place the nth largest element in its final position.
std::iter_swap(__first, __nth);
return;
}
--__depth_limit;
_RandomAccessIterator __cut =
- std::__unguarded_partition_pivot(__first, __last, __comp);
+ std::__detail::__unguarded_partition_pivot(__first, __last, __comp);
if (__cut <= __nth)
__first = __cut;
else
__last = __cut;
}
- std::__insertion_sort(__first, __last, __comp);
+ std::__detail::__insertion_sort(__first, __last, __comp);
}
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
// nth_element
// lower_bound moved to stl_algobase.h
@@ -2450,8 +2126,6 @@
{
typedef typename iterator_traits<_ForwardIterator>::value_type
_ValueType;
- typedef typename iterator_traits<_ForwardIterator>::difference_type
- _DistanceType;
// concept requirements
__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
@@ -2460,6 +2134,22 @@
__glibcxx_requires_partitioned_lower_pred(__first, __last,
__val, __comp);
+ return std::__detail::__lower_bound(__first, __last, __val,
+ __gnu_cxx::__ops::__iter_comp_cval(__comp, __first, __val));
+ }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
+
+ template<typename _ForwardIterator, typename _Tp, typename _Compare>
+ _ForwardIterator
+ __upper_bound(_ForwardIterator __first, _ForwardIterator __last,
+ const _Tp& __val, _Compare __comp)
+ {
+ typedef typename iterator_traits<_ForwardIterator>::difference_type
+ _DistanceType;
+
_DistanceType __len = std::distance(__first, __last);
while (__len > 0)
@@ -2467,18 +2157,22 @@
_DistanceType __half = __len >> 1;
_ForwardIterator __middle = __first;
std::advance(__middle, __half);
- if (__comp(*__middle, __val))
+ if (__comp(__val, __middle))
+ __len = __half;
+ else
{
__first = __middle;
++__first;
__len = __len - __half - 1;
}
- else
- __len = __half;
}
return __first;
}
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
/**
* @brief Finds the last position in which @p __val could be inserted
* without changing the ordering.
@@ -2497,31 +2191,14 @@
{
typedef typename iterator_traits<_ForwardIterator>::value_type
_ValueType;
- typedef typename iterator_traits<_ForwardIterator>::difference_type
- _DistanceType;
// concept requirements
__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
__glibcxx_function_requires(_LessThanOpConcept<_Tp, _ValueType>)
__glibcxx_requires_partitioned_upper(__first, __last, __val);
- _DistanceType __len = std::distance(__first, __last);
-
- while (__len > 0)
- {
- _DistanceType __half = __len >> 1;
- _ForwardIterator __middle = __first;
- std::advance(__middle, __half);
- if (__val < *__middle)
- __len = __half;
- else
- {
- __first = __middle;
- ++__first;
- __len = __len - __half - 1;
- }
- }
- return __first;
+ return std::__detail::__upper_bound(__first, __last, __val,
+ __gnu_cxx::__ops::__cval_less_iter(__val, __first));
}
/**
@@ -2546,8 +2223,6 @@
{
typedef typename iterator_traits<_ForwardIterator>::value_type
_ValueType;
- typedef typename iterator_traits<_ForwardIterator>::difference_type
- _DistanceType;
// concept requirements
__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
@@ -2556,6 +2231,24 @@
__glibcxx_requires_partitioned_upper_pred(__first, __last,
__val, __comp);
+ return std::__detail::__upper_bound(__first, __last, __val,
+ __gnu_cxx::__ops::__cval_comp_iter(__comp, __val, __first));
+ }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
+
+ template<typename _ForwardIterator, typename _Tp,
+ typename _CompareItTp, typename _CompareTpIt>
+ pair<_ForwardIterator, _ForwardIterator>
+ __equal_range(_ForwardIterator __first, _ForwardIterator __last,
+ const _Tp& __val,
+ _CompareItTp __comp_it_val, _CompareTpIt __comp_val_it)
+ {
+ typedef typename iterator_traits<_ForwardIterator>::difference_type
+ _DistanceType;
+
_DistanceType __len = std::distance(__first, __last);
while (__len > 0)
@@ -2563,18 +2256,33 @@
_DistanceType __half = __len >> 1;
_ForwardIterator __middle = __first;
std::advance(__middle, __half);
- if (__comp(__val, *__middle))
- __len = __half;
- else
+ if (__comp_it_val(__middle, __val))
{
__first = __middle;
++__first;
__len = __len - __half - 1;
}
+ else if (__comp_val_it(__val, __middle))
+ __len = __half;
+ else
+ {
+ _ForwardIterator __left
+ = std::__detail::__lower_bound(__first, __middle, __val,
+ __comp_it_val);
+ std::advance(__first, __len);
+ _ForwardIterator __right
+ = std::__detail::__upper_bound(++__middle, __first, __val,
+ __comp_val_it);
+ return pair<_ForwardIterator, _ForwardIterator>(__left, __right);
+ }
}
- return __first;
+ return pair<_ForwardIterator, _ForwardIterator>(__first, __first);
}
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
/**
* @brief Finds the largest subrange in which @p __val could be inserted
* at any place in it without changing the ordering.
@@ -2599,42 +2307,17 @@
{
typedef typename iterator_traits<_ForwardIterator>::value_type
_ValueType;
- typedef typename iterator_traits<_ForwardIterator>::difference_type
- _DistanceType;
// concept requirements
__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
__glibcxx_function_requires(_LessThanOpConcept<_ValueType, _Tp>)
- __glibcxx_function_requires(_LessThanOpConcept<_Tp, _ValueType>)
+ __glibcxx_function_requires(_LessThanOpConcept<_Tp, _ValueType>)
__glibcxx_requires_partitioned_lower(__first, __last, __val);
__glibcxx_requires_partitioned_upper(__first, __last, __val);
- _DistanceType __len = std::distance(__first, __last);
-
- while (__len > 0)
- {
- _DistanceType __half = __len >> 1;
- _ForwardIterator __middle = __first;
- std::advance(__middle, __half);
- if (*__middle < __val)
- {
- __first = __middle;
- ++__first;
- __len = __len - __half - 1;
- }
- else if (__val < *__middle)
- __len = __half;
- else
- {
- _ForwardIterator __left = std::lower_bound(__first, __middle,
- __val);
- std::advance(__first, __len);
- _ForwardIterator __right = std::upper_bound(++__middle, __first,
- __val);
- return pair<_ForwardIterator, _ForwardIterator>(__left, __right);
- }
- }
- return pair<_ForwardIterator, _ForwardIterator>(__first, __first);
+ return std::__detail::__equal_range(__first, __last, __val,
+ __gnu_cxx::__ops::__iter_less_cval(__first, __val),
+ __gnu_cxx::__ops::__cval_less_iter(__val, __first));
}
/**
@@ -2661,8 +2344,6 @@
{
typedef typename iterator_traits<_ForwardIterator>::value_type
_ValueType;
- typedef typename iterator_traits<_ForwardIterator>::difference_type
- _DistanceType;
// concept requirements
__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
@@ -2675,32 +2356,9 @@
__glibcxx_requires_partitioned_upper_pred(__first, __last,
__val, __comp);
- _DistanceType __len = std::distance(__first, __last);
-
- while (__len > 0)
- {
- _DistanceType __half = __len >> 1;
- _ForwardIterator __middle = __first;
- std::advance(__middle, __half);
- if (__comp(*__middle, __val))
- {
- __first = __middle;
- ++__first;
- __len = __len - __half - 1;
- }
- else if (__comp(__val, *__middle))
- __len = __half;
- else
- {
- _ForwardIterator __left = std::lower_bound(__first, __middle,
- __val, __comp);
- std::advance(__first, __len);
- _ForwardIterator __right = std::upper_bound(++__middle, __first,
- __val, __comp);
- return pair<_ForwardIterator, _ForwardIterator>(__left, __right);
- }
- }
- return pair<_ForwardIterator, _ForwardIterator>(__first, __first);
+ return std::__detail::__equal_range(__first, __last, __val,
+ __gnu_cxx::__ops::__iter_comp_cval(__comp, __first, __val),
+ __gnu_cxx::__ops::__cval_comp_iter(__comp, __val, __first));
}
/**
@@ -2729,7 +2387,9 @@
__glibcxx_requires_partitioned_lower(__first, __last, __val);
__glibcxx_requires_partitioned_upper(__first, __last, __val);
- _ForwardIterator __i = std::lower_bound(__first, __last, __val);
+ _ForwardIterator __i
+ = std::__detail::__lower_bound(__first, __last, __val,
+ __gnu_cxx::__ops::__iter_less_cval(__first, __val));
return __i != __last && !(__val < *__i);
}
@@ -2765,37 +2425,17 @@
__glibcxx_requires_partitioned_upper_pred(__first, __last,
__val, __comp);
- _ForwardIterator __i = std::lower_bound(__first, __last, __val, __comp);
+ _ForwardIterator __i
+ = std::__detail::__lower_bound(__first, __last, __val,
+ __gnu_cxx::__ops::__iter_comp_cval(__comp, __first, __val));
return __i != __last && !bool(__comp(__val, *__i));
}
+_GLIBCXX_END_NAMESPACE_VERSION
+
// merge
- /// This is a helper function for the __merge_adaptive routines.
- template<typename _InputIterator1, typename _InputIterator2,
- typename _OutputIterator>
- void
- __move_merge_adaptive(_InputIterator1 __first1, _InputIterator1 __last1,
- _InputIterator2 __first2, _InputIterator2 __last2,
- _OutputIterator __result)
- {
- while (__first1 != __last1 && __first2 != __last2)
- {
- if (*__first2 < *__first1)
- {
- *__result = _GLIBCXX_MOVE(*__first2);
- ++__first2;
- }
- else
- {
- *__result = _GLIBCXX_MOVE(*__first1);
- ++__first1;
- }
- ++__result;
- }
- if (__first1 != __last1)
- _GLIBCXX_MOVE3(__first1, __last1, __result);
- }
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
/// This is a helper function for the __merge_adaptive routines.
template<typename _InputIterator1, typename _InputIterator2,
@@ -2807,7 +2447,7 @@
{
while (__first1 != __last1 && __first2 != __last2)
{
- if (__comp(*__first2, *__first1))
+ if (__comp(__first2, __first1))
{
*__result = _GLIBCXX_MOVE(*__first2);
++__first2;
@@ -2825,48 +2465,6 @@
/// This is a helper function for the __merge_adaptive routines.
template<typename _BidirectionalIterator1, typename _BidirectionalIterator2,
- typename _BidirectionalIterator3>
- void
- __move_merge_adaptive_backward(_BidirectionalIterator1 __first1,
- _BidirectionalIterator1 __last1,
- _BidirectionalIterator2 __first2,
- _BidirectionalIterator2 __last2,
- _BidirectionalIterator3 __result)
- {
- if (__first1 == __last1)
- {
- _GLIBCXX_MOVE_BACKWARD3(__first2, __last2, __result);
- return;
- }
- else if (__first2 == __last2)
- return;
-
- --__last1;
- --__last2;
- while (true)
- {
- if (*__last2 < *__last1)
- {
- *--__result = _GLIBCXX_MOVE(*__last1);
- if (__first1 == __last1)
- {
- _GLIBCXX_MOVE_BACKWARD3(__first2, ++__last2, __result);
- return;
- }
- --__last1;
- }
- else
- {
- *--__result = _GLIBCXX_MOVE(*__last2);
- if (__first2 == __last2)
- return;
- --__last2;
- }
- }
- }
-
- /// This is a helper function for the __merge_adaptive routines.
- template<typename _BidirectionalIterator1, typename _BidirectionalIterator2,
typename _BidirectionalIterator3, typename _Compare>
void
__move_merge_adaptive_backward(_BidirectionalIterator1 __first1,
@@ -2888,7 +2486,7 @@
--__last2;
while (true)
{
- if (__comp(*__last2, *__last1))
+ if (__comp(__last2, __last1))
{
*--__result = _GLIBCXX_MOVE(*__last1);
if (__first1 == __last1)
@@ -2951,62 +2549,6 @@
}
/// This is a helper function for the merge routines.
- template<typename _BidirectionalIterator, typename _Distance,
- typename _Pointer>
- void
- __merge_adaptive(_BidirectionalIterator __first,
- _BidirectionalIterator __middle,
- _BidirectionalIterator __last,
- _Distance __len1, _Distance __len2,
- _Pointer __buffer, _Distance __buffer_size)
- {
- if (__len1 <= __len2 && __len1 <= __buffer_size)
- {
- _Pointer __buffer_end = _GLIBCXX_MOVE3(__first, __middle, __buffer);
- std::__move_merge_adaptive(__buffer, __buffer_end, __middle, __last,
- __first);
- }
- else if (__len2 <= __buffer_size)
- {
- _Pointer __buffer_end = _GLIBCXX_MOVE3(__middle, __last, __buffer);
- std::__move_merge_adaptive_backward(__first, __middle, __buffer,
- __buffer_end, __last);
- }
- else
- {
- _BidirectionalIterator __first_cut = __first;
- _BidirectionalIterator __second_cut = __middle;
- _Distance __len11 = 0;
- _Distance __len22 = 0;
- if (__len1 > __len2)
- {
- __len11 = __len1 / 2;
- std::advance(__first_cut, __len11);
- __second_cut = std::lower_bound(__middle, __last,
- *__first_cut);
- __len22 = std::distance(__middle, __second_cut);
- }
- else
- {
- __len22 = __len2 / 2;
- std::advance(__second_cut, __len22);
- __first_cut = std::upper_bound(__first, __middle,
- *__second_cut);
- __len11 = std::distance(__first, __first_cut);
- }
- _BidirectionalIterator __new_middle =
- std::__rotate_adaptive(__first_cut, __middle, __second_cut,
- __len1 - __len11, __len22, __buffer,
- __buffer_size);
- std::__merge_adaptive(__first, __first_cut, __new_middle, __len11,
- __len22, __buffer, __buffer_size);
- std::__merge_adaptive(__new_middle, __second_cut, __last,
- __len1 - __len11,
- __len2 - __len22, __buffer, __buffer_size);
- }
- }
-
- /// This is a helper function for the merge routines.
template<typename _BidirectionalIterator, typename _Distance,
typename _Pointer, typename _Compare>
void
@@ -3020,14 +2562,16 @@
if (__len1 <= __len2 && __len1 <= __buffer_size)
{
_Pointer __buffer_end = _GLIBCXX_MOVE3(__first, __middle, __buffer);
- std::__move_merge_adaptive(__buffer, __buffer_end, __middle, __last,
- __first, __comp);
+ std::__detail::__move_merge_adaptive(
+ __buffer, __buffer_end, __middle, __last, __first,
+ __gnu_cxx::__ops::__rebind(__comp, __first, __buffer));
}
else if (__len2 <= __buffer_size)
{
_Pointer __buffer_end = _GLIBCXX_MOVE3(__middle, __last, __buffer);
- std::__move_merge_adaptive_backward(__first, __middle, __buffer,
- __buffer_end, __last, __comp);
+ std::__detail::__move_merge_adaptive_backward(
+ __first, __middle, __buffer, __buffer_end, __last,
+ __gnu_cxx::__ops::__rebind(__comp, __buffer, __first));
}
else
{
@@ -3039,75 +2583,34 @@
{
__len11 = __len1 / 2;
std::advance(__first_cut, __len11);
- __second_cut = std::lower_bound(__middle, __last, *__first_cut,
- __comp);
+ __second_cut
+ = std::__detail::__lower_bound(__middle, __last, *__first_cut,
+ __gnu_cxx::__ops::__rebind_iter_cval(__comp, __first));
__len22 = std::distance(__middle, __second_cut);
}
else
{
__len22 = __len2 / 2;
std::advance(__second_cut, __len22);
- __first_cut = std::upper_bound(__first, __middle, *__second_cut,
- __comp);
+ __first_cut
+ = std::__detail::__upper_bound(__first, __middle, *__second_cut,
+ __gnu_cxx::__ops::__rebind_cval_comp_iter(__comp, __first));
__len11 = std::distance(__first, __first_cut);
}
- _BidirectionalIterator __new_middle =
- std::__rotate_adaptive(__first_cut, __middle, __second_cut,
- __len1 - __len11, __len22, __buffer,
- __buffer_size);
- std::__merge_adaptive(__first, __first_cut, __new_middle, __len11,
- __len22, __buffer, __buffer_size, __comp);
- std::__merge_adaptive(__new_middle, __second_cut, __last,
- __len1 - __len11,
- __len2 - __len22, __buffer,
- __buffer_size, __comp);
+ _BidirectionalIterator __new_middle
+ = std::__detail::__rotate_adaptive(__first_cut, __middle,
+ __second_cut, __len1 - __len11,
+ __len22, __buffer, __buffer_size);
+ std::__detail::__merge_adaptive(__first, __first_cut, __new_middle,
+ __len11, __len22,
+ __buffer, __buffer_size, __comp);
+ std::__detail::__merge_adaptive(__new_middle, __second_cut, __last,
+ __len1 - __len11, __len2 - __len22,
+ __buffer, __buffer_size, __comp);
}
}
/// This is a helper function for the merge routines.
- template<typename _BidirectionalIterator, typename _Distance>
- void
- __merge_without_buffer(_BidirectionalIterator __first,
- _BidirectionalIterator __middle,
- _BidirectionalIterator __last,
- _Distance __len1, _Distance __len2)
- {
- if (__len1 == 0 || __len2 == 0)
- return;
- if (__len1 + __len2 == 2)
- {
- if (*__middle < *__first)
- std::iter_swap(__first, __middle);
- return;
- }
- _BidirectionalIterator __first_cut = __first;
- _BidirectionalIterator __second_cut = __middle;
- _Distance __len11 = 0;
- _Distance __len22 = 0;
- if (__len1 > __len2)
- {
- __len11 = __len1 / 2;
- std::advance(__first_cut, __len11);
- __second_cut = std::lower_bound(__middle, __last, *__first_cut);
- __len22 = std::distance(__middle, __second_cut);
- }
- else
- {
- __len22 = __len2 / 2;
- std::advance(__second_cut, __len22);
- __first_cut = std::upper_bound(__first, __middle, *__second_cut);
- __len11 = std::distance(__first, __first_cut);
- }
- std::rotate(__first_cut, __middle, __second_cut);
- _BidirectionalIterator __new_middle = __first_cut;
- std::advance(__new_middle, std::distance(__middle, __second_cut));
- std::__merge_without_buffer(__first, __first_cut, __new_middle,
- __len11, __len22);
- std::__merge_without_buffer(__new_middle, __second_cut, __last,
- __len1 - __len11, __len2 - __len22);
- }
-
- /// This is a helper function for the merge routines.
template<typename _BidirectionalIterator, typename _Distance,
typename _Compare>
void
@@ -3121,7 +2624,7 @@
return;
if (__len1 + __len2 == 2)
{
- if (__comp(*__middle, *__first))
+ if (__comp(__middle, __first))
std::iter_swap(__first, __middle);
return;
}
@@ -3133,27 +2636,64 @@
{
__len11 = __len1 / 2;
std::advance(__first_cut, __len11);
- __second_cut = std::lower_bound(__middle, __last, *__first_cut,
- __comp);
+ __second_cut
+ = std::__detail::__lower_bound(__middle, __last, *__first_cut,
+ __gnu_cxx::__ops::__rebind_iter_cval(__comp, __first));
__len22 = std::distance(__middle, __second_cut);
}
else
{
__len22 = __len2 / 2;
std::advance(__second_cut, __len22);
- __first_cut = std::upper_bound(__first, __middle, *__second_cut,
- __comp);
+ __first_cut
+ = std::__detail::__upper_bound(__first, __middle, *__second_cut,
+ __gnu_cxx::__ops::__rebind_cval_comp_iter(__comp, __first));
__len11 = std::distance(__first, __first_cut);
}
std::rotate(__first_cut, __middle, __second_cut);
_BidirectionalIterator __new_middle = __first_cut;
std::advance(__new_middle, std::distance(__middle, __second_cut));
- std::__merge_without_buffer(__first, __first_cut, __new_middle,
+ std::__detail::__merge_without_buffer(__first, __first_cut, __new_middle,
__len11, __len22, __comp);
- std::__merge_without_buffer(__new_middle, __second_cut, __last,
+ std::__detail::__merge_without_buffer(__new_middle, __second_cut, __last,
__len1 - __len11, __len2 - __len22, __comp);
}
+ template<typename _BidirectionalIterator, typename _Compare>
+ void
+ __inplace_merge(_BidirectionalIterator __first,
+ _BidirectionalIterator __middle,
+ _BidirectionalIterator __last,
+ _Compare __comp)
+ {
+ typedef typename iterator_traits<_BidirectionalIterator>::value_type
+ _ValueType;
+ typedef typename iterator_traits<_BidirectionalIterator>::difference_type
+ _DistanceType;
+
+ if (__first == __middle || __middle == __last)
+ return;
+
+ const _DistanceType __len1 = std::distance(__first, __middle);
+ const _DistanceType __len2 = std::distance(__middle, __last);
+
+ typedef _Temporary_buffer<_BidirectionalIterator, _ValueType> _TmpBuf;
+ _TmpBuf __buf(__first, __last);
+
+ if (__buf.begin() == 0)
+ std::__detail::__merge_without_buffer
+ (__first, __middle, __last, __len1, __len2, __comp);
+ else
+ std::__detail::__merge_adaptive
+ (__first, __middle, __last, __len1, __len2, __buf.begin(),
+ _DistanceType(__buf.size()),
+ __gnu_cxx::__ops::__rebind(__comp, __first, __buf.begin()));
+ }
+
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
/**
* @brief Merges two sorted ranges in place.
* @ingroup sorting_algorithms
@@ -3178,31 +2718,16 @@
_BidirectionalIterator __middle,
_BidirectionalIterator __last)
{
- typedef typename iterator_traits<_BidirectionalIterator>::value_type
- _ValueType;
- typedef typename iterator_traits<_BidirectionalIterator>::difference_type
- _DistanceType;
-
// concept requirements
__glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept<
_BidirectionalIterator>)
- __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
+ __glibcxx_function_requires(_LessThanComparableConcept<
+ typename iterator_traits<_BidirectionalIterator>::value_type>)
__glibcxx_requires_sorted(__first, __middle);
__glibcxx_requires_sorted(__middle, __last);
- if (__first == __middle || __middle == __last)
- return;
-
- _DistanceType __len1 = std::distance(__first, __middle);
- _DistanceType __len2 = std::distance(__middle, __last);
-
- _Temporary_buffer<_BidirectionalIterator, _ValueType> __buf(__first,
- __last);
- if (__buf.begin() == 0)
- std::__merge_without_buffer(__first, __middle, __last, __len1, __len2);
- else
- std::__merge_adaptive(__first, __middle, __last, __len1, __len2,
- __buf.begin(), _DistanceType(__buf.size()));
+ std::__detail::__inplace_merge(__first, __middle, __last,
+ __gnu_cxx::__ops::__iter_less_iter(__first));
}
/**
@@ -3234,75 +2759,35 @@
_BidirectionalIterator __last,
_Compare __comp)
{
- typedef typename iterator_traits<_BidirectionalIterator>::value_type
- _ValueType;
- typedef typename iterator_traits<_BidirectionalIterator>::difference_type
- _DistanceType;
-
// concept requirements
__glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept<
_BidirectionalIterator>)
__glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
- _ValueType, _ValueType>)
+ typename iterator_traits<_BidirectionalIterator>::value_type,
+ typename iterator_traits<_BidirectionalIterator>::value_type>)
__glibcxx_requires_sorted_pred(__first, __middle, __comp);
__glibcxx_requires_sorted_pred(__middle, __last, __comp);
- if (__first == __middle || __middle == __last)
- return;
+ std::__detail::__inplace_merge(__first, __middle, __last,
+ __gnu_cxx::__ops::__iter_comp_iter(__comp, __first));
+ }
- const _DistanceType __len1 = std::distance(__first, __middle);
- const _DistanceType __len2 = std::distance(__middle, __last);
- _Temporary_buffer<_BidirectionalIterator, _ValueType> __buf(__first,
- __last);
- if (__buf.begin() == 0)
- std::__merge_without_buffer(__first, __middle, __last, __len1,
- __len2, __comp);
- else
- std::__merge_adaptive(__first, __middle, __last, __len1, __len2,
- __buf.begin(), _DistanceType(__buf.size()),
- __comp);
- }
+_GLIBCXX_END_NAMESPACE_VERSION
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
/// This is a helper function for the __merge_sort_loop routines.
- template<typename _InputIterator1, typename _InputIterator2,
- typename _OutputIterator>
+ template<typename _InputIterator, typename _OutputIterator,
+ typename _Compare>
_OutputIterator
- __move_merge(_InputIterator1 __first1, _InputIterator1 __last1,
- _InputIterator2 __first2, _InputIterator2 __last2,
- _OutputIterator __result)
- {
- while (__first1 != __last1 && __first2 != __last2)
- {
- if (*__first2 < *__first1)
- {
- *__result = _GLIBCXX_MOVE(*__first2);
- ++__first2;
- }
- else
- {
- *__result = _GLIBCXX_MOVE(*__first1);
- ++__first1;
- }
- ++__result;
- }
- return _GLIBCXX_MOVE3(__first2, __last2,
- _GLIBCXX_MOVE3(__first1, __last1,
- __result));
- }
-
- /// This is a helper function for the __merge_sort_loop routines.
- template<typename _InputIterator1, typename _InputIterator2,
- typename _OutputIterator, typename _Compare>
- _OutputIterator
- __move_merge(_InputIterator1 __first1, _InputIterator1 __last1,
- _InputIterator2 __first2, _InputIterator2 __last2,
+ __move_merge(_InputIterator __first1, _InputIterator __last1,
+ _InputIterator __first2, _InputIterator __last2,
_OutputIterator __result, _Compare __comp)
{
while (__first1 != __last1 && __first2 != __last2)
{
- if (__comp(*__first2, *__first1))
+ if (__comp(__first2, __first1))
{
*__result = _GLIBCXX_MOVE(*__first2);
++__first2;
@@ -3320,29 +2805,6 @@
}
template<typename _RandomAccessIterator1, typename _RandomAccessIterator2,
- typename _Distance>
- void
- __merge_sort_loop(_RandomAccessIterator1 __first,
- _RandomAccessIterator1 __last,
- _RandomAccessIterator2 __result,
- _Distance __step_size)
- {
- const _Distance __two_step = 2 * __step_size;
-
- while (__last - __first >= __two_step)
- {
- __result = std::__move_merge(__first, __first + __step_size,
- __first + __step_size,
- __first + __two_step, __result);
- __first += __two_step;
- }
-
- __step_size = std::min(_Distance(__last - __first), __step_size);
- std::__move_merge(__first, __first + __step_size,
- __first + __step_size, __last, __result);
- }
-
- template<typename _RandomAccessIterator1, typename _RandomAccessIterator2,
typename _Distance, typename _Compare>
void
__merge_sort_loop(_RandomAccessIterator1 __first,
@@ -3354,7 +2816,7 @@
while (__last - __first >= __two_step)
{
- __result = std::__move_merge(__first, __first + __step_size,
+ __result = std::__detail::__move_merge(__first, __first + __step_size,
__first + __step_size,
__first + __two_step,
__result, __comp);
@@ -3362,24 +2824,10 @@
}
__step_size = std::min(_Distance(__last - __first), __step_size);
- std::__move_merge(__first,__first + __step_size,
+ std::__detail::__move_merge(__first, __first + __step_size,
__first + __step_size, __last, __result, __comp);
}
- template<typename _RandomAccessIterator, typename _Distance>
- void
- __chunk_insertion_sort(_RandomAccessIterator __first,
- _RandomAccessIterator __last,
- _Distance __chunk_size)
- {
- while (__last - __first >= __chunk_size)
- {
- std::__insertion_sort(__first, __first + __chunk_size);
- __first += __chunk_size;
- }
- std::__insertion_sort(__first, __last);
- }
-
template<typename _RandomAccessIterator, typename _Distance,
typename _Compare>
void
@@ -3389,38 +2837,15 @@
{
while (__last - __first >= __chunk_size)
{
- std::__insertion_sort(__first, __first + __chunk_size, __comp);
+ std::__detail::__insertion_sort(__first, __first + __chunk_size,
+ __comp);
__first += __chunk_size;
}
- std::__insertion_sort(__first, __last, __comp);
+ std::__detail::__insertion_sort(__first, __last, __comp);
}
enum { _S_chunk_size = 7 };
- template<typename _RandomAccessIterator, typename _Pointer>
- void
- __merge_sort_with_buffer(_RandomAccessIterator __first,
- _RandomAccessIterator __last,
- _Pointer __buffer)
- {
- typedef typename iterator_traits<_RandomAccessIterator>::difference_type
- _Distance;
-
- const _Distance __len = __last - __first;
- const _Pointer __buffer_last = __buffer + __len;
-
- _Distance __step_size = _S_chunk_size;
- std::__chunk_insertion_sort(__first, __last, __step_size);
-
- while (__step_size < __len)
- {
- std::__merge_sort_loop(__first, __last, __buffer, __step_size);
- __step_size *= 2;
- std::__merge_sort_loop(__buffer, __buffer_last, __first, __step_size);
- __step_size *= 2;
- }
- }
-
template<typename _RandomAccessIterator, typename _Pointer, typename _Compare>
void
__merge_sort_with_buffer(_RandomAccessIterator __first,
@@ -3434,47 +2859,22 @@
const _Pointer __buffer_last = __buffer + __len;
_Distance __step_size = _S_chunk_size;
- std::__chunk_insertion_sort(__first, __last, __step_size, __comp);
+ std::__detail::__chunk_insertion_sort(__first, __last, __step_size,
+ __comp);
while (__step_size < __len)
{
- std::__merge_sort_loop(__first, __last, __buffer,
+ std::__detail::__merge_sort_loop(__first, __last, __buffer,
__step_size, __comp);
__step_size *= 2;
- std::__merge_sort_loop(__buffer, __buffer_last, __first,
- __step_size, __comp);
+ std::__detail::__merge_sort_loop(__buffer, __buffer_last,
+ __first, __step_size,
+ __gnu_cxx::__ops::__rebind(__comp, __buffer));
__step_size *= 2;
}
}
template<typename _RandomAccessIterator, typename _Pointer,
- typename _Distance>
- void
- __stable_sort_adaptive(_RandomAccessIterator __first,
- _RandomAccessIterator __last,
- _Pointer __buffer, _Distance __buffer_size)
- {
- const _Distance __len = (__last - __first + 1) / 2;
- const _RandomAccessIterator __middle = __first + __len;
- if (__len > __buffer_size)
- {
- std::__stable_sort_adaptive(__first, __middle,
- __buffer, __buffer_size);
- std::__stable_sort_adaptive(__middle, __last,
- __buffer, __buffer_size);
- }
- else
- {
- std::__merge_sort_with_buffer(__first, __middle, __buffer);
- std::__merge_sort_with_buffer(__middle, __last, __buffer);
- }
- std::__merge_adaptive(__first, __middle, __last,
- _Distance(__middle - __first),
- _Distance(__last - __middle),
- __buffer, __buffer_size);
- }
-
- template<typename _RandomAccessIterator, typename _Pointer,
typename _Distance, typename _Compare>
void
__stable_sort_adaptive(_RandomAccessIterator __first,
@@ -3486,17 +2886,19 @@
const _RandomAccessIterator __middle = __first + __len;
if (__len > __buffer_size)
{
- std::__stable_sort_adaptive(__first, __middle, __buffer,
+ std::__detail::__stable_sort_adaptive(__first, __middle, __buffer,
__buffer_size, __comp);
- std::__stable_sort_adaptive(__middle, __last, __buffer,
+ std::__detail::__stable_sort_adaptive(__middle, __last, __buffer,
__buffer_size, __comp);
}
else
{
- std::__merge_sort_with_buffer(__first, __middle, __buffer, __comp);
- std::__merge_sort_with_buffer(__middle, __last, __buffer, __comp);
+ std::__detail::__merge_sort_with_buffer(__first, __middle,
+ __buffer, __comp);
+ std::__detail::__merge_sort_with_buffer(__middle, __last,
+ __buffer, __comp);
}
- std::__merge_adaptive(__first, __middle, __last,
+ std::__detail::__merge_adaptive(__first, __middle, __last,
_Distance(__middle - __first),
_Distance(__last - __middle),
__buffer, __buffer_size,
@@ -3504,25 +2906,6 @@
}
/// This is a helper function for the stable sorting routines.
- template<typename _RandomAccessIterator>
- void
- __inplace_stable_sort(_RandomAccessIterator __first,
- _RandomAccessIterator __last)
- {
- if (__last - __first < 15)
- {
- std::__insertion_sort(__first, __last);
- return;
- }
- _RandomAccessIterator __middle = __first + (__last - __first) / 2;
- std::__inplace_stable_sort(__first, __middle);
- std::__inplace_stable_sort(__middle, __last);
- std::__merge_without_buffer(__first, __middle, __last,
- __middle - __first,
- __last - __middle);
- }
-
- /// This is a helper function for the stable sorting routines.
template<typename _RandomAccessIterator, typename _Compare>
void
__inplace_stable_sort(_RandomAccessIterator __first,
@@ -3530,13 +2913,13 @@
{
if (__last - __first < 15)
{
- std::__insertion_sort(__first, __last, __comp);
+ std::__detail::__insertion_sort(__first, __last, __comp);
return;
}
_RandomAccessIterator __middle = __first + (__last - __first) / 2;
- std::__inplace_stable_sort(__first, __middle, __comp);
- std::__inplace_stable_sort(__middle, __last, __comp);
- std::__merge_without_buffer(__first, __middle, __last,
+ std::__detail::__inplace_stable_sort(__first, __middle, __comp);
+ std::__detail::__inplace_stable_sort(__middle, __last, __comp);
+ std::__detail::__merge_without_buffer(__first, __middle, __last,
__middle - __first,
__last - __middle,
__comp);
@@ -3549,6 +2932,28 @@
// that their input ranges are sorted and the postcondition that their output
// ranges are sorted.
+ template<typename _InputIterator1, typename _InputIterator2,
+ typename _Compare12, typename _Compare21>
+ bool
+ __includes(_InputIterator1 __first1, _InputIterator1 __last1,
+ _InputIterator2 __first2, _InputIterator2 __last2,
+ _Compare12 __comp12, _Compare21 __comp21)
+ {
+ while (__first1 != __last1 && __first2 != __last2)
+ if (__comp21(__first2, __first1))
+ return false;
+ else if(__comp12(__first1, __first2))
+ ++__first1;
+ else
+ ++__first1, ++__first2;
+
+ return __first2 == __last2;
+ }
+
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
/**
* @brief Determines whether all elements of a sequence exists in a range.
* @param __first1 Start of search range.
@@ -3572,28 +2977,21 @@
includes(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __last2)
{
- typedef typename iterator_traits<_InputIterator1>::value_type
- _ValueType1;
- typedef typename iterator_traits<_InputIterator2>::value_type
- _ValueType2;
-
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
- __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>)
- __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>)
+ __glibcxx_function_requires(_LessThanOpConcept<
+ typename iterator_traits<_InputIterator1>::value_type,
+ typename iterator_traits<_InputIterator2>::value_type>)
+ __glibcxx_function_requires(_LessThanOpConcept<
+ typename iterator_traits<_InputIterator2>::value_type,
+ typename iterator_traits<_InputIterator1>::value_type>)
__glibcxx_requires_sorted_set(__first1, __last1, __first2);
__glibcxx_requires_sorted_set(__first2, __last2, __first1);
- while (__first1 != __last1 && __first2 != __last2)
- if (*__first2 < *__first1)
- return false;
- else if(*__first1 < *__first2)
- ++__first1;
- else
- ++__first1, ++__first2;
-
- return __first2 == __last2;
+ return std::__detail::__includes(__first1, __last1, __first2, __last2,
+ __gnu_cxx::__ops::__iter_less_iter(__first1, __first2),
+ __gnu_cxx::__ops::__iter_less_iter(__first2, __first1));
}
/**
@@ -3624,32 +3022,25 @@
_InputIterator2 __first2, _InputIterator2 __last2,
_Compare __comp)
{
- typedef typename iterator_traits<_InputIterator1>::value_type
- _ValueType1;
- typedef typename iterator_traits<_InputIterator2>::value_type
- _ValueType2;
-
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
__glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
- _ValueType1, _ValueType2>)
+ typename iterator_traits<_InputIterator1>::value_type,
+ typename iterator_traits<_InputIterator2>::value_type>)
__glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
- _ValueType2, _ValueType1>)
+ typename iterator_traits<_InputIterator2>::value_type,
+ typename iterator_traits<_InputIterator1>::value_type>)
__glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp);
__glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp);
- while (__first1 != __last1 && __first2 != __last2)
- if (__comp(*__first2, *__first1))
- return false;
- else if(__comp(*__first1, *__first2))
- ++__first1;
- else
- ++__first1, ++__first2;
-
- return __first2 == __last2;
+ return std::__detail::__includes(__first1, __last1, __first2, __last2,
+ __gnu_cxx::__ops::__iter_comp_iter(__comp, __first1, __first2),
+ __gnu_cxx::__ops::__iter_comp_iter(__comp, __first2, __first1));
}
+_GLIBCXX_END_NAMESPACE_VERSION
+
// nth_element
// merge
// set_difference
@@ -3660,30 +3051,13 @@
// min_element
// max_element
- /**
- * @brief Permute range into the next @e dictionary ordering.
- * @ingroup sorting_algorithms
- * @param __first Start of range.
- * @param __last End of range.
- * @return False if wrapped to first permutation, true otherwise.
- *
- * Treats all permutations of the range as a set of @e dictionary sorted
- * sequences. Permutes the current sequence into the next one of this set.
- * Returns true if there are more sequences to generate. If the sequence
- * is the largest of the set, the smallest is generated and false returned.
- */
- template<typename _BidirectionalIterator>
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
+
+ template<typename _BidirectionalIterator, typename _Compare>
bool
- next_permutation(_BidirectionalIterator __first,
- _BidirectionalIterator __last)
+ __next_permutation(_BidirectionalIterator __first,
+ _BidirectionalIterator __last, _Compare __comp)
{
- // concept requirements
- __glibcxx_function_requires(_BidirectionalIteratorConcept<
- _BidirectionalIterator>)
- __glibcxx_function_requires(_LessThanComparableConcept<
- typename iterator_traits<_BidirectionalIterator>::value_type>)
- __glibcxx_requires_valid_range(__first, __last);
-
if (__first == __last)
return false;
_BidirectionalIterator __i = __first;
@@ -3697,24 +3071,58 @@
{
_BidirectionalIterator __ii = __i;
--__i;
- if (*__i < *__ii)
+ if (__comp(__i, __ii))
{
_BidirectionalIterator __j = __last;
- while (!(*__i < *--__j))
+ while (!__comp(__i, --__j))
{}
std::iter_swap(__i, __j);
- std::reverse(__ii, __last);
+ std::__detail::__reverse(__ii, __last,
+ std::__iterator_category(__first));
return true;
}
if (__i == __first)
{
- std::reverse(__first, __last);
+ std::__detail::__reverse(__first, __last,
+ std::__iterator_category(__first));
return false;
}
}
}
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
/**
+ * @brief Permute range into the next @e dictionary ordering.
+ * @ingroup sorting_algorithms
+ * @param __first Start of range.
+ * @param __last End of range.
+ * @return False if wrapped to first permutation, true otherwise.
+ *
+ * Treats all permutations of the range as a set of @e dictionary sorted
+ * sequences. Permutes the current sequence into the next one of this set.
+ * Returns true if there are more sequences to generate. If the sequence
+ * is the largest of the set, the smallest is generated and false returned.
+ */
+ template<typename _BidirectionalIterator>
+ bool
+ next_permutation(_BidirectionalIterator __first,
+ _BidirectionalIterator __last)
+ {
+ // concept requirements
+ __glibcxx_function_requires(_BidirectionalIteratorConcept<
+ _BidirectionalIterator>)
+ __glibcxx_function_requires(_LessThanComparableConcept<
+ typename iterator_traits<_BidirectionalIterator>::value_type>)
+ __glibcxx_requires_valid_range(__first, __last);
+
+ return std::__detail::__next_permutation(__first, __last,
+ __gnu_cxx::__ops::__iter_less_iter(__first));
+ }
+
+ /**
* @brief Permute range into the next @e dictionary ordering using
* comparison functor.
* @ingroup sorting_algorithms
@@ -3742,6 +3150,19 @@
typename iterator_traits<_BidirectionalIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
+ return std::__detail::__next_permutation(__first, __last,
+ __gnu_cxx::__ops::__iter_comp_iter(__comp, __first));
+ }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
+
+ template<typename _BidirectionalIterator, typename _Compare>
+ bool
+ __prev_permutation(_BidirectionalIterator __first,
+ _BidirectionalIterator __last, _Compare __comp)
+ {
if (__first == __last)
return false;
_BidirectionalIterator __i = __first;
@@ -3755,23 +3176,29 @@
{
_BidirectionalIterator __ii = __i;
--__i;
- if (__comp(*__i, *__ii))
+ if (__comp(__ii, __i))
{
_BidirectionalIterator __j = __last;
- while (!bool(__comp(*__i, *--__j)))
+ while (!__comp(--__j, __i))
{}
std::iter_swap(__i, __j);
- std::reverse(__ii, __last);
+ std::__detail::__reverse(__ii, __last,
+ std::__iterator_category(__first));
return true;
}
if (__i == __first)
{
- std::reverse(__first, __last);
+ std::__detail::__reverse(__first, __last,
+ std::__iterator_category(__first));
return false;
}
}
}
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
/**
* @brief Permute range into the previous @e dictionary ordering.
* @ingroup sorting_algorithms
@@ -3797,34 +3224,8 @@
typename iterator_traits<_BidirectionalIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- if (__first == __last)
- return false;
- _BidirectionalIterator __i = __first;
- ++__i;
- if (__i == __last)
- return false;
- __i = __last;
- --__i;
-
- for(;;)
- {
- _BidirectionalIterator __ii = __i;
- --__i;
- if (*__ii < *__i)
- {
- _BidirectionalIterator __j = __last;
- while (!(*--__j < *__i))
- {}
- std::iter_swap(__i, __j);
- std::reverse(__ii, __last);
- return true;
- }
- if (__i == __first)
- {
- std::reverse(__first, __last);
- return false;
- }
- }
+ return std::__detail::__prev_permutation(__first, __last,
+ __gnu_cxx::__ops::__iter_less_iter(__first));
}
/**
@@ -3855,39 +3256,36 @@
typename iterator_traits<_BidirectionalIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- if (__first == __last)
- return false;
- _BidirectionalIterator __i = __first;
- ++__i;
- if (__i == __last)
- return false;
- __i = __last;
- --__i;
-
- for(;;)
- {
- _BidirectionalIterator __ii = __i;
- --__i;
- if (__comp(*__ii, *__i))
- {
- _BidirectionalIterator __j = __last;
- while (!bool(__comp(*--__j, *__i)))
- {}
- std::iter_swap(__i, __j);
- std::reverse(__ii, __last);
- return true;
- }
- if (__i == __first)
- {
- std::reverse(__first, __last);
- return false;
- }
- }
+ return std::__detail::__prev_permutation(__first, __last,
+ __gnu_cxx::__ops::__iter_comp_iter(__comp, __first));
}
+_GLIBCXX_END_NAMESPACE_VERSION
+
// replace
// replace_if
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
+
+ template<typename _InputIterator, typename _OutputIterator,
+ typename _Predicate, typename _Tp>
+ _OutputIterator
+ __replace_copy_if(_InputIterator __first, _InputIterator __last,
+ _OutputIterator __result,
+ _Predicate __pred, const _Tp& __new_value)
+ {
+ for (; __first != __last; ++__first, ++__result)
+ if (__pred(__first))
+ *__result = __new_value;
+ else
+ *__result = *__first;
+ return __result;
+ }
+
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
/**
* @brief Copy a sequence, replacing each element of one value with another
* value.
@@ -3916,12 +3314,9 @@
typename iterator_traits<_InputIterator>::value_type, _Tp>)
__glibcxx_requires_valid_range(__first, __last);
- for (; __first != __last; ++__first, ++__result)
- if (*__first == __old_value)
- *__result = __new_value;
- else
- *__result = *__first;
- return __result;
+ return std::__detail::__replace_copy_if(__first, __last, __result,
+ __gnu_cxx::__ops::__iter_equal_to_bound_cval(__first, __old_value),
+ __new_value);
}
/**
@@ -3954,15 +3349,31 @@
typename iterator_traits<_InputIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- for (; __first != __last; ++__first, ++__result)
- if (__pred(*__first))
- *__result = __new_value;
- else
- *__result = *__first;
- return __result;
+ return std::__detail::__replace_copy_if(__first, __last, __result,
+ __gnu_cxx::__ops::__pred_iter(__pred, __first),
+ __new_value);
}
-#if __cplusplus >= 201103L
+_GLIBCXX_END_NAMESPACE_VERSION
+
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
+
+ template<typename _InputIterator, typename _Predicate>
+ typename iterator_traits<_InputIterator>::difference_type
+ __count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred)
+ {
+ typename iterator_traits<_InputIterator>::difference_type __n = 0;
+ for (; __first != __last; ++__first)
+ if (__pred(__first))
+ ++__n;
+ return __n;
+ }
+
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
/**
* @brief Determines whether the elements of a sequence are sorted.
* @ingroup sorting_algorithms
@@ -3990,6 +3401,29 @@
_Compare __comp)
{ return std::is_sorted_until(__first, __last, __comp) == __last; }
+_GLIBCXX_END_NAMESPACE_VERSION
+
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
+
+ template<typename _ForwardIterator, typename _Compare>
+ _ForwardIterator
+ __is_sorted_until(_ForwardIterator __first, _ForwardIterator __last,
+ _Compare __comp)
+ {
+ if (__first == __last)
+ return __last;
+
+ _ForwardIterator __next = __first;
+ for (++__next; __next != __last; __first = __next, ++__next)
+ if (__comp(__next, __first))
+ return __next;
+ return __next;
+ }
+
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
/**
* @brief Determines the end of a sorted sequence.
* @ingroup sorting_algorithms
@@ -4008,14 +3442,8 @@
typename iterator_traits<_ForwardIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- if (__first == __last)
- return __last;
-
- _ForwardIterator __next = __first;
- for (++__next; __next != __last; __first = __next, ++__next)
- if (*__next < *__first)
- return __next;
- return __next;
+ return std::__detail::__is_sorted_until(__first, __last,
+ __gnu_cxx::__ops::__iter_less_iter(__first));
}
/**
@@ -4039,14 +3467,8 @@
typename iterator_traits<_ForwardIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- if (__first == __last)
- return __last;
-
- _ForwardIterator __next = __first;
- for (++__next; __next != __last; __first = __next, ++__next)
- if (__comp(*__next, *__first))
- return __next;
- return __next;
+ return std::__detail::__is_sorted_until(__first, __last,
+ __gnu_cxx::__ops::__iter_comp_iter(__comp, __first));
}
/**
@@ -4085,34 +3507,22 @@
: pair<const _Tp&, const _Tp&>(__a, __b);
}
- /**
- * @brief Return a pair of iterators pointing to the minimum and maximum
- * elements in a range.
- * @ingroup sorting_algorithms
- * @param __first Start of range.
- * @param __last End of range.
- * @return make_pair(m, M), where m is the first iterator i in
- * [__first, __last) such that no other element in the range is
- * smaller, and where M is the last iterator i in [__first, __last)
- * such that no other element in the range is larger.
- */
- template<typename _ForwardIterator>
+_GLIBCXX_END_NAMESPACE_VERSION
+
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
+
+ template<typename _ForwardIterator, typename _Compare>
pair<_ForwardIterator, _ForwardIterator>
- minmax_element(_ForwardIterator __first, _ForwardIterator __last)
+ __minmax_element(_ForwardIterator __first, _ForwardIterator __last,
+ _Compare __comp)
{
- // concept requirements
- __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
- __glibcxx_function_requires(_LessThanComparableConcept<
- typename iterator_traits<_ForwardIterator>::value_type>)
- __glibcxx_requires_valid_range(__first, __last);
-
_ForwardIterator __next = __first;
if (__first == __last
|| ++__next == __last)
return std::make_pair(__first, __first);
_ForwardIterator __min, __max;
- if (*__next < *__first)
+ if (__comp(__next, __first))
{
__min = __next;
__max = __first;
@@ -4131,25 +3541,25 @@
__next = __first;
if (++__next == __last)
{
- if (*__first < *__min)
+ if (__comp(__first, __min))
__min = __first;
- else if (!(*__first < *__max))
+ else if (!__comp(__first, __max))
__max = __first;
break;
}
- if (*__next < *__first)
+ if (__comp(__next, __first))
{
- if (*__next < *__min)
+ if (__comp(__next, __min))
__min = __next;
- if (!(*__first < *__max))
+ if (!__comp(__first, __max))
__max = __first;
}
else
{
- if (*__first < *__min)
+ if (__comp(__first, __min))
__min = __first;
- if (!(*__next < *__max))
+ if (!__comp(__next, __max))
__max = __next;
}
@@ -4160,12 +3570,41 @@
return std::make_pair(__min, __max);
}
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
/**
* @brief Return a pair of iterators pointing to the minimum and maximum
* elements in a range.
* @ingroup sorting_algorithms
* @param __first Start of range.
* @param __last End of range.
+ * @return make_pair(m, M), where m is the first iterator i in
+ * [__first, __last) such that no other element in the range is
+ * smaller, and where M is the last iterator i in [__first, __last)
+ * such that no other element in the range is larger.
+ */
+ template<typename _ForwardIterator>
+ pair<_ForwardIterator, _ForwardIterator>
+ minmax_element(_ForwardIterator __first, _ForwardIterator __last)
+ {
+ // concept requirements
+ __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
+ __glibcxx_function_requires(_LessThanComparableConcept<
+ typename iterator_traits<_ForwardIterator>::value_type>)
+ __glibcxx_requires_valid_range(__first, __last);
+
+ return std::__detail::__minmax_element(__first, __last,
+ __gnu_cxx::__ops::__iter_less_iter(__first));
+ }
+
+ /**
+ * @brief Return a pair of iterators pointing to the minimum and maximum
+ * elements in a range.
+ * @ingroup sorting_algorithms
+ * @param __first Start of range.
+ * @param __last End of range.
* @param __comp Comparison functor.
* @return make_pair(m, M), where m is the first iterator i in
* [__first, __last) such that no other element in the range is
@@ -4184,58 +3623,8 @@
typename iterator_traits<_ForwardIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- _ForwardIterator __next = __first;
- if (__first == __last
- || ++__next == __last)
- return std::make_pair(__first, __first);
-
- _ForwardIterator __min, __max;
- if (__comp(*__next, *__first))
- {
- __min = __next;
- __max = __first;
- }
- else
- {
- __min = __first;
- __max = __next;
- }
-
- __first = __next;
- ++__first;
-
- while (__first != __last)
- {
- __next = __first;
- if (++__next == __last)
- {
- if (__comp(*__first, *__min))
- __min = __first;
- else if (!__comp(*__first, *__max))
- __max = __first;
- break;
- }
-
- if (__comp(*__next, *__first))
- {
- if (__comp(*__next, *__min))
- __min = __next;
- if (!__comp(*__first, *__max))
- __max = __first;
- }
- else
- {
- if (__comp(*__first, *__min))
- __min = __first;
- if (!__comp(*__next, *__max))
- __max = __next;
- }
-
- __first = __next;
- ++__first;
- }
-
- return std::make_pair(__min, __max);
+ return std::__detail::__minmax_element(__first, __last,
+ __gnu_cxx::__ops::__iter_comp_iter(__comp, __first));
}
// N2722 + DR 915.
@@ -4277,73 +3666,20 @@
return std::make_pair(*__p.first, *__p.second);
}
- /**
- * @brief Checks whether a permutaion of the second sequence is equal
- * to the first sequence.
- * @ingroup non_mutating_algorithms
- * @param __first1 Start of first range.
- * @param __last1 End of first range.
- * @param __first2 Start of second range.
- * @return true if there exists a permutation of the elements in the range
- * [__first2, __first2 + (__last1 - __first1)), beginning with
- * ForwardIterator2 begin, such that equal(__first1, __last1, begin)
- * returns true; otherwise, returns false.
- */
- template<typename _ForwardIterator1, typename _ForwardIterator2>
- bool
- is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
- _ForwardIterator2 __first2)
- {
- // Efficiently compare identical prefixes: O(N) if sequences
- // have the same elements in the same order.
- for (; __first1 != __last1; ++__first1, ++__first2)
- if (!(*__first1 == *__first2))
- break;
+_GLIBCXX_END_NAMESPACE_VERSION
- if (__first1 == __last1)
- return true;
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
- // Establish __last2 assuming equal ranges by iterating over the
- // rest of the list.
- _ForwardIterator2 __last2 = __first2;
- std::advance(__last2, std::distance(__first1, __last1));
- for (_ForwardIterator1 __scan = __first1; __scan != __last1; ++__scan)
- {
- if (__scan != _GLIBCXX_STD_A::find(__first1, __scan, *__scan))
- continue; // We've seen this one before.
-
- auto __matches = std::count(__first2, __last2, *__scan);
- if (0 == __matches
- || std::count(__scan, __last1, *__scan) != __matches)
- return false;
- }
- return true;
- }
-
- /**
- * @brief Checks whether a permutation of the second sequence is equal
- * to the first sequence.
- * @ingroup non_mutating_algorithms
- * @param __first1 Start of first range.
- * @param __last1 End of first range.
- * @param __first2 Start of second range.
- * @param __pred A binary predicate.
- * @return true if there exists a permutation of the elements in
- * the range [__first2, __first2 + (__last1 - __first1)),
- * beginning with ForwardIterator2 begin, such that
- * equal(__first1, __last1, __begin, __pred) returns true;
- * otherwise, returns false.
- */
template<typename _ForwardIterator1, typename _ForwardIterator2,
typename _BinaryPredicate>
bool
- is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
- _ForwardIterator2 __first2, _BinaryPredicate __pred)
+ __is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
+ _ForwardIterator2 __first2, _BinaryPredicate __pred)
{
// Efficiently compare identical prefixes: O(N) if sequences
// have the same elements in the same order.
for (; __first1 != __last1; ++__first1, ++__first2)
- if (!bool(__pred(*__first1, *__first2)))
+ if (!__pred(__first1, __first2))
break;
if (__first1 == __last1)
@@ -4355,23 +3691,25 @@
std::advance(__last2, std::distance(__first1, __last1));
for (_ForwardIterator1 __scan = __first1; __scan != __last1; ++__scan)
{
- using std::placeholders::_1;
-
- if (__scan != _GLIBCXX_STD_A::find_if(__first1, __scan,
- std::bind(__pred, _1, *__scan)))
+ if (__scan != std::__detail::__find_if(__first1, __scan,
+ __gnu_cxx::__ops::__bind2nd(__pred, __scan)))
continue; // We've seen this one before.
- auto __matches = std::count_if(__first2, __last2,
- std::bind(__pred, _1, *__scan));
+ auto __matches
+ = std::__detail::__count_if(__first2, __last2,
+ __gnu_cxx::__ops::__bind1st(__pred, __scan));
if (0 == __matches
- || std::count_if(__scan, __last1,
- std::bind(__pred, _1, *__scan)) != __matches)
+ || std::__detail::__count_if(__scan, __last1,
+ __gnu_cxx::__ops::__bind2nd(__pred, __scan)) != __matches)
return false;
}
return true;
}
-#if __cplusplus > 201103L
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
/**
* @brief Checks whether a permutaion of the second sequence is equal
* to the first sequence.
@@ -4379,54 +3717,26 @@
* @param __first1 Start of first range.
* @param __last1 End of first range.
* @param __first2 Start of second range.
- * @param __last2 End of first range.
* @return true if there exists a permutation of the elements in the range
- * [__first2, __last2), beginning with ForwardIterator2 begin,
- * such that equal(__first1, __last1, begin) returns true;
- * otherwise, returns false.
+ * [__first2, __first2 + (__last1 - __first1)), beginning with
+ * ForwardIterator2 begin, such that equal(__first1, __last1, begin)
+ * returns true; otherwise, returns false.
*/
template<typename _ForwardIterator1, typename _ForwardIterator2>
bool
is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
- _ForwardIterator2 __first2, _ForwardIterator2 __last2)
+ _ForwardIterator2 __first2)
{
- using _Cat1
- = typename iterator_traits<_ForwardIterator1>::iterator_category;
- using _Cat2
- = typename iterator_traits<_ForwardIterator2>::iterator_category;
- using _It1_is_RA = is_same<_Cat1, random_access_iterator_tag>;
- using _It2_is_RA = is_same<_Cat2, random_access_iterator_tag>;
- if (_It1_is_RA() && _It2_is_RA())
- {
- auto __d1 = std::distance(__first1, __last1);
- auto __d2 = std::distance(__first2, __last2);
- if (__d1 != __d2)
- return false;
- }
+ // concept requirements
+ __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>)
+ __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>)
+ __glibcxx_function_requires(_EqualOpConcept<
+ typename iterator_traits<_ForwardIterator1>::value_type,
+ typename iterator_traits<_ForwardIterator2>::value_type>)
+ __glibcxx_requires_valid_range(__first1, __last1);
- // Efficiently compare identical prefixes: O(N) if sequences
- // have the same elements in the same order.
- for (; __first1 != __last1 && __first2 != __last2; ++__first1, ++__first2)
- if (!(*__first1 == *__first2))
- break;
-
- if (__first1 == __last1 && __first2 == __last2)
- return true;
-
- if (std::distance(__first1, __last1) != std::distance(__first2, __last2))
- return false;
-
- for (auto __scan = __first1; __scan != __last1; ++__scan)
- {
- if (__scan != _GLIBCXX_STD_A::find(__first1, __scan, *__scan))
- continue; // We've seen this one before.
-
- auto __matches = std::count(__first2, __last2, *__scan);
- if (0 == __matches
- || std::count(__scan, __last1, *__scan) != __matches)
- return false;
- }
- return true;
+ return std::__detail::__is_permutation(__first1, __last1, __first2,
+ __gnu_cxx::__ops::__iter_equal_to_iter(__first1, __first2));
}
/**
@@ -4436,20 +3746,43 @@
* @param __first1 Start of first range.
* @param __last1 End of first range.
* @param __first2 Start of second range.
- * @param __last2 End of first range.
* @param __pred A binary predicate.
- * @return true if there exists a permutation of the elements in the range
- * [__first2, __last2), beginning with ForwardIterator2 begin,
- * such that equal(__first1, __last1, __begin, __pred) returns true;
+ * @return true if there exists a permutation of the elements in
+ * the range [__first2, __first2 + (__last1 - __first1)),
+ * beginning with ForwardIterator2 begin, such that
+ * equal(__first1, __last1, __begin, __pred) returns true;
* otherwise, returns false.
*/
template<typename _ForwardIterator1, typename _ForwardIterator2,
typename _BinaryPredicate>
bool
is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
- _ForwardIterator2 __first2, _ForwardIterator2 __last2,
- _BinaryPredicate __pred)
+ _ForwardIterator2 __first2, _BinaryPredicate __pred)
{
+ // concept requirements
+ __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>)
+ __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>)
+ __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
+ typename iterator_traits<_ForwardIterator1>::value_type,
+ typename iterator_traits<_ForwardIterator2>::value_type>)
+ __glibcxx_requires_valid_range(__first1, __last1);
+
+ return std::__detail::__is_permutation(__first1, __last1, __first2,
+ __gnu_cxx::__ops::__iter_comp_iter(__pred, __first1, __first2));
+ }
+
+#if __cplusplus > 201103L
+_GLIBCXX_END_NAMESPACE_VERSION
+
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
+
+ template<typename _ForwardIterator1, typename _ForwardIterator2,
+ typename _BinaryPredicate>
+ bool
+ __is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
+ _ForwardIterator2 __first2, _ForwardIterator2 __last2,
+ _BinaryPredicate __pred)
+ {
using _Cat1
= typename iterator_traits<_ForwardIterator1>::iterator_category;
using _Cat2
@@ -4468,7 +3801,7 @@
// Efficiently compare identical prefixes: O(N) if sequences
// have the same elements in the same order.
for (; __first1 != __last1; ++__first1, ++__first2)
- if (!bool(__pred(*__first1, *__first2)))
+ if (!__pred(__first1, __first2))
break;
if (__ra_iters)
@@ -4488,21 +3821,78 @@
for (_ForwardIterator1 __scan = __first1; __scan != __last1; ++__scan)
{
- using std::placeholders::_1;
-
- if (__scan != _GLIBCXX_STD_A::find_if(__first1, __scan,
- std::bind(__pred, _1, *__scan)))
+ if (__scan != std::__detail::__find_if(__first1, __scan,
+ __gnu_cxx::__ops::__bind2nd(__pred, __scan)))
continue; // We've seen this one before.
- auto __matches = std::count_if(__first2, __last2,
- std::bind(__pred, _1, *__scan));
+ auto __matches = std::__detail::__count_if(__first2, __last2,
+ __gnu_cxx::__ops::__bind1st(__pred, __scan));
if (0 == __matches
- || std::count_if(__scan, __last1,
- std::bind(__pred, _1, *__scan)) != __matches)
+ || std::__detail::__count_if(__scan, __last1,
+ __gnu_cxx::__ops::__bind2nd(__pred, __scan)) != __matches)
return false;
}
return true;
}
+
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+ /**
+ * @brief Checks whether a permutaion of the second sequence is equal
+ * to the first sequence.
+ * @ingroup non_mutating_algorithms
+ * @param __first1 Start of first range.
+ * @param __last1 End of first range.
+ * @param __first2 Start of second range.
+ * @param __last2 End of first range.
+ * @return true if there exists a permutation of the elements in the range
+ * [__first2, __last2), beginning with ForwardIterator2 begin,
+ * such that equal(__first1, __last1, begin) returns true;
+ * otherwise, returns false.
+ */
+ template<typename _ForwardIterator1, typename _ForwardIterator2>
+ bool
+ is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
+ _ForwardIterator2 __first2, _ForwardIterator2 __last2)
+ {
+ __glibcxx_requires_valid_range(__first1, __last1);
+ __glibcxx_requires_valid_range(__first2, __last2);
+
+ return
+ std::__detail::__is_permutation(__first1, __last1, __first2, __last2,
+ __gnu_cxx::__ops::__iter_equal_to_iter(__first1, __first2));
+ }
+
+ /**
+ * @brief Checks whether a permutation of the second sequence is equal
+ * to the first sequence.
+ * @ingroup non_mutating_algorithms
+ * @param __first1 Start of first range.
+ * @param __last1 End of first range.
+ * @param __first2 Start of second range.
+ * @param __last2 End of first range.
+ * @param __pred A binary predicate.
+ * @return true if there exists a permutation of the elements in the range
+ * [__first2, __last2), beginning with ForwardIterator2 begin,
+ * such that equal(__first1, __last1, __begin, __pred) returns true;
+ * otherwise, returns false.
+ */
+ template<typename _ForwardIterator1, typename _ForwardIterator2,
+ typename _BinaryPredicate>
+ bool
+ is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
+ _ForwardIterator2 __first2, _ForwardIterator2 __last2,
+ _BinaryPredicate __pred)
+ {
+ __glibcxx_requires_valid_range(__first1, __last1);
+ __glibcxx_requires_valid_range(__first2, __last2);
+
+ return
+ std::__detail::__is_permutation(__first1, __last1, __first2, __last2,
+ __gnu_cxx::__ops::__iter_comp_iter(__pred, __first1, __first2));
+ }
#endif
#ifdef _GLIBCXX_USE_C99_STDINT_TR1
@@ -4570,6 +3960,7 @@
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
__glibcxx_requires_valid_range(__first, __last);
+
for (; __first != __last; ++__first)
__f(*__first);
return _GLIBCXX_MOVE(__f);
@@ -4594,8 +3985,9 @@
__glibcxx_function_requires(_EqualOpConcept<
typename iterator_traits<_InputIterator>::value_type, _Tp>)
__glibcxx_requires_valid_range(__first, __last);
- return std::__find(__first, __last, __val,
- std::__iterator_category(__first));
+
+ return std::__detail::__find_if(__first, __last,
+ __gnu_cxx::__ops::__iter_equal_to_bound_cval(__first, __val));
}
/**
@@ -4618,8 +4010,9 @@
__glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
typename iterator_traits<_InputIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- return std::__find_if(__first, __last, __pred,
- std::__iterator_category(__first));
+
+ return std::__detail::__find_if(__first, __last,
+ __gnu_cxx::__ops::__pred_iter(__pred, __first));
}
/**
@@ -4719,16 +4112,9 @@
__glibcxx_function_requires(_EqualityComparableConcept<
typename iterator_traits<_ForwardIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- if (__first == __last)
- return __last;
- _ForwardIterator __next = __first;
- while(++__next != __last)
- {
- if (*__first == *__next)
- return __first;
- __first = __next;
- }
- return __last;
+
+ return std::__detail::__adjacent_find(__first, __last,
+ __gnu_cxx::__ops::__iter_equal_to_iter(__first));
}
/**
@@ -4753,16 +4139,9 @@
typename iterator_traits<_ForwardIterator>::value_type,
typename iterator_traits<_ForwardIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- if (__first == __last)
- return __last;
- _ForwardIterator __next = __first;
- while(++__next != __last)
- {
- if (__binary_pred(*__first, *__next))
- return __first;
- __first = __next;
- }
- return __last;
+
+ return std::__detail::__adjacent_find(__first, __last,
+ __gnu_cxx::__ops::__iter_comp_iter(__binary_pred, __first));
}
/**
@@ -4781,13 +4160,11 @@
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
__glibcxx_function_requires(_EqualOpConcept<
- typename iterator_traits<_InputIterator>::value_type, _Tp>)
+ typename iterator_traits<_InputIterator>::value_type, _Tp>)
__glibcxx_requires_valid_range(__first, __last);
- typename iterator_traits<_InputIterator>::difference_type __n = 0;
- for (; __first != __last; ++__first)
- if (*__first == __value)
- ++__n;
- return __n;
+
+ return std::__detail::__count_if(__first, __last,
+ __gnu_cxx::__ops::__iter_equal_to_bound_cval(__first, __value));
}
/**
@@ -4808,11 +4185,9 @@
__glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
typename iterator_traits<_InputIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- typename iterator_traits<_InputIterator>::difference_type __n = 0;
- for (; __first != __last; ++__first)
- if (__pred(*__first))
- ++__n;
- return __n;
+
+ return std::__detail::__count_if(__first, __last,
+ __gnu_cxx::__ops::__pred_iter(__pred, __first));
}
/**
@@ -4855,40 +4230,8 @@
__glibcxx_requires_valid_range(__first1, __last1);
__glibcxx_requires_valid_range(__first2, __last2);
- // Test for empty ranges
- if (__first1 == __last1 || __first2 == __last2)
- return __first1;
-
- // Test for a pattern of length 1.
- _ForwardIterator2 __p1(__first2);
- if (++__p1 == __last2)
- return _GLIBCXX_STD_A::find(__first1, __last1, *__first2);
-
- // General case.
- _ForwardIterator2 __p;
- _ForwardIterator1 __current = __first1;
-
- for (;;)
- {
- __first1 = _GLIBCXX_STD_A::find(__first1, __last1, *__first2);
- if (__first1 == __last1)
- return __last1;
-
- __p = __p1;
- __current = __first1;
- if (++__current == __last1)
- return __last1;
-
- while (*__current == *__p)
- {
- if (++__p == __last2)
- return __first1;
- if (++__current == __last1)
- return __last1;
- }
- ++__first1;
- }
- return __first1;
+ return std::__detail::__search(__first1, __last1, __first2, __last2,
+ __gnu_cxx::__ops::__iter_equal_to_iter(__first1, __first2));
}
/**
@@ -4928,50 +4271,10 @@
__glibcxx_requires_valid_range(__first1, __last1);
__glibcxx_requires_valid_range(__first2, __last2);
- // Test for empty ranges
- if (__first1 == __last1 || __first2 == __last2)
- return __first1;
-
- // Test for a pattern of length 1.
- _ForwardIterator2 __p1(__first2);
- if (++__p1 == __last2)
- {
- while (__first1 != __last1
- && !bool(__predicate(*__first1, *__first2)))
- ++__first1;
- return __first1;
- }
-
- // General case.
- _ForwardIterator2 __p;
- _ForwardIterator1 __current = __first1;
-
- for (;;)
- {
- while (__first1 != __last1
- && !bool(__predicate(*__first1, *__first2)))
- ++__first1;
- if (__first1 == __last1)
- return __last1;
-
- __p = __p1;
- __current = __first1;
- if (++__current == __last1)
- return __last1;
-
- while (__predicate(*__current, *__p))
- {
- if (++__p == __last2)
- return __first1;
- if (++__current == __last1)
- return __last1;
- }
- ++__first1;
- }
- return __first1;
+ return std::__detail::__search(__first1, __last1, __first2, __last2,
+ __gnu_cxx::__ops::__iter_comp_iter(__predicate, __first1, __first2));
}
-
/**
* @brief Search a sequence for a number of consecutive values.
* @ingroup non_mutating_algorithms
@@ -4995,15 +4298,11 @@
// concept requirements
__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
__glibcxx_function_requires(_EqualOpConcept<
- typename iterator_traits<_ForwardIterator>::value_type, _Tp>)
+ typename iterator_traits<_ForwardIterator>::value_type, _Tp>)
__glibcxx_requires_valid_range(__first, __last);
- if (__count <= 0)
- return __first;
- if (__count == 1)
- return _GLIBCXX_STD_A::find(__first, __last, __val);
- return std::__search_n(__first, __last, __count, __val,
- std::__iterator_category(__first));
+ return std::__detail::__search_n(__first, __last, __count,
+ __gnu_cxx::__ops::__iter_equal_to_bound_cval(__first, __val));
}
@@ -5037,16 +4336,10 @@
typename iterator_traits<_ForwardIterator>::value_type, _Tp>)
__glibcxx_requires_valid_range(__first, __last);
- if (__count <= 0)
- return __first;
- if (__count == 1)
- {
- while (__first != __last && !bool(__binary_pred(*__first, __val)))
- ++__first;
- return __first;
- }
- return std::__search_n(__first, __last, __count, __val, __binary_pred,
- std::__iterator_category(__first));
+ return std::__detail::__search_n(__first, __last, __count,
+ __gnu_cxx::__ops::__bind2nd(
+ __gnu_cxx::__ops::__iter_comp_cval(__binary_pred, __first, __val),
+ __val));
}
@@ -5283,7 +4576,9 @@
if (__first == __last)
return __result;
- return std::__unique_copy(__first, __last, __result,
+
+ return std::__detail::__unique_copy(__first, __last, __result,
+ __gnu_cxx::__ops::__iter_equal_to_iter(__first),
std::__iterator_category(__first),
std::__iterator_category(__result));
}
@@ -5319,12 +4614,17 @@
__glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
typename iterator_traits<_InputIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
+ __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
+ typename iterator_traits<_InputIterator>::value_type,
+ typename iterator_traits<_InputIterator>::value_type>)
if (__first == __last)
return __result;
- return std::__unique_copy(__first, __last, __result, __binary_pred,
- std::__iterator_category(__first),
- std::__iterator_category(__result));
+
+ return std::__detail::__unique_copy(__first, __last, __result,
+ __gnu_cxx::__ops::__iter_comp_iter(__binary_pred, __first),
+ std::__iterator_category(__first),
+ std::__iterator_category(__result));
}
@@ -5415,12 +4715,11 @@
typename iterator_traits<_ForwardIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- return std::__partition(__first, __last, __pred,
+ return std::__detail::__partition(__first, __last, __pred,
std::__iterator_category(__first));
}
-
/**
* @brief Sort the smallest elements of a sequence.
* @ingroup sorting_algorithms
@@ -5443,18 +4742,16 @@
_RandomAccessIterator __middle,
_RandomAccessIterator __last)
{
- typedef typename iterator_traits<_RandomAccessIterator>::value_type
- _ValueType;
-
// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIterator>)
- __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
+ __glibcxx_function_requires(_LessThanComparableConcept<
+ typename iterator_traits<_RandomAccessIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __middle);
__glibcxx_requires_valid_range(__middle, __last);
- std::__heap_select(__first, __middle, __last);
- std::sort_heap(__first, __middle);
+ std::__detail::__partial_sort(__first, __middle, __last,
+ __gnu_cxx::__ops::__iter_less_iter(__first));
}
/**
@@ -5483,19 +4780,17 @@
_RandomAccessIterator __last,
_Compare __comp)
{
- typedef typename iterator_traits<_RandomAccessIterator>::value_type
- _ValueType;
-
// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIterator>)
__glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
- _ValueType, _ValueType>)
+ typename iterator_traits<_RandomAccessIterator>::value_type,
+ typename iterator_traits<_RandomAccessIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __middle);
__glibcxx_requires_valid_range(__middle, __last);
- std::__heap_select(__first, __middle, __last, __comp);
- std::sort_heap(__first, __middle, __comp);
+ std::__detail::__partial_sort(__first, __middle, __last,
+ __gnu_cxx::__ops::__iter_comp_iter(__comp, __first));
}
/**
@@ -5518,21 +4813,20 @@
nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth,
_RandomAccessIterator __last)
{
- typedef typename iterator_traits<_RandomAccessIterator>::value_type
- _ValueType;
-
// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIterator>)
- __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
+ __glibcxx_function_requires(_LessThanComparableConcept<
+ typename iterator_traits<_RandomAccessIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __nth);
__glibcxx_requires_valid_range(__nth, __last);
if (__first == __last || __nth == __last)
return;
- std::__introselect(__first, __nth, __last,
- std::__lg(__last - __first) * 2);
+ std::__detail::__introselect(__first, __nth, __last,
+ std::__detail::__lg(__last - __first) * 2,
+ __gnu_cxx::__ops::__iter_less_iter(__first));
}
/**
@@ -5557,25 +4851,23 @@
nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth,
_RandomAccessIterator __last, _Compare __comp)
{
- typedef typename iterator_traits<_RandomAccessIterator>::value_type
- _ValueType;
-
// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIterator>)
__glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
- _ValueType, _ValueType>)
+ typename iterator_traits<_RandomAccessIterator>::value_type,
+ typename iterator_traits<_RandomAccessIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __nth);
__glibcxx_requires_valid_range(__nth, __last);
if (__first == __last || __nth == __last)
return;
- std::__introselect(__first, __nth, __last,
- std::__lg(__last - __first) * 2, __comp);
+ std::__detail::__introselect(__first, __nth, __last,
+ std::__detail::__lg(__last - __first) * 2,
+ __gnu_cxx::__ops::__iter_comp_iter(__comp, __first));
}
-
/**
* @brief Sort the elements of a sequence.
* @ingroup sorting_algorithms
@@ -5594,21 +4886,15 @@
inline void
sort(_RandomAccessIterator __first, _RandomAccessIterator __last)
{
- typedef typename iterator_traits<_RandomAccessIterator>::value_type
- _ValueType;
-
// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIterator>)
- __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
+ __glibcxx_function_requires(_LessThanComparableConcept<
+ typename iterator_traits<_RandomAccessIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- if (__first != __last)
- {
- std::__introsort_loop(__first, __last,
- std::__lg(__last - __first) * 2);
- std::__final_insertion_sort(__first, __last);
- }
+ std::__detail::__sort(__first, __last,
+ __gnu_cxx::__ops::__iter_less_iter(__first));
}
/**
@@ -5631,24 +4917,51 @@
sort(_RandomAccessIterator __first, _RandomAccessIterator __last,
_Compare __comp)
{
- typedef typename iterator_traits<_RandomAccessIterator>::value_type
- _ValueType;
-
// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIterator>)
- __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, _ValueType,
- _ValueType>)
+ __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
+ typename iterator_traits<_RandomAccessIterator>::value_type,
+ typename iterator_traits<_RandomAccessIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- if (__first != __last)
+ std::__detail::__sort(__first, __last,
+ __gnu_cxx::__ops::__iter_comp_iter(__comp, __first));
+ }
+
+_GLIBCXX_END_NAMESPACE_ALGO
+
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
+
+ template<typename _InputIterator1, typename _InputIterator2,
+ typename _OutputIterator, typename _Compare>
+ _OutputIterator
+ __merge(_InputIterator1 __first1, _InputIterator1 __last1,
+ _InputIterator2 __first2, _InputIterator2 __last2,
+ _OutputIterator __result, _Compare __comp)
+ {
+ while (__first1 != __last1 && __first2 != __last2)
{
- std::__introsort_loop(__first, __last,
- std::__lg(__last - __first) * 2, __comp);
- std::__final_insertion_sort(__first, __last, __comp);
+ if (__comp(__first2, __first1))
+ {
+ *__result = *__first2;
+ ++__first2;
+ }
+ else
+ {
+ *__result = *__first1;
+ ++__first1;
+ }
+ ++__result;
}
+ return std::__detail::__copy(__first2, __last2,
+ std::__detail::__copy(__first1, __last1, __result));
}
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_ALGO
+
/**
* @brief Merges two sorted ranges.
* @ingroup sorting_algorithms
@@ -5675,38 +4988,22 @@
_InputIterator2 __first2, _InputIterator2 __last2,
_OutputIterator __result)
{
- typedef typename iterator_traits<_InputIterator1>::value_type
- _ValueType1;
- typedef typename iterator_traits<_InputIterator2>::value_type
- _ValueType2;
-
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
__glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
- _ValueType1>)
+ typename iterator_traits<_InputIterator1>::value_type>)
__glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
- _ValueType2>)
- __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>)
+ typename iterator_traits<_InputIterator2>::value_type>)
+ __glibcxx_function_requires(_LessThanOpConcept<
+ typename iterator_traits<_InputIterator2>::value_type,
+ typename iterator_traits<_InputIterator1>::value_type>)
__glibcxx_requires_sorted_set(__first1, __last1, __first2);
__glibcxx_requires_sorted_set(__first2, __last2, __first1);
- while (__first1 != __last1 && __first2 != __last2)
- {
- if (*__first2 < *__first1)
- {
- *__result = *__first2;
- ++__first2;
- }
- else
- {
- *__result = *__first1;
- ++__first1;
- }
- ++__result;
- }
- return std::copy(__first2, __last2, std::copy(__first1, __last1,
- __result));
+ return std::__detail::__merge(__first1, __last1,
+ __first2, __last2, __result,
+ __gnu_cxx::__ops::__iter_less_iter(__first1, __first2));
}
/**
@@ -5739,42 +5036,52 @@
_InputIterator2 __first2, _InputIterator2 __last2,
_OutputIterator __result, _Compare __comp)
{
- typedef typename iterator_traits<_InputIterator1>::value_type
- _ValueType1;
- typedef typename iterator_traits<_InputIterator2>::value_type
- _ValueType2;
-
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
__glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
- _ValueType1>)
+ typename iterator_traits<_InputIterator1>::value_type>)
__glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
- _ValueType2>)
+ typename iterator_traits<_InputIterator2>::value_type>)
__glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
- _ValueType2, _ValueType1>)
+ typename iterator_traits<_InputIterator2>::value_type,
+ typename iterator_traits<_InputIterator1>::value_type>)
__glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp);
__glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp);
- while (__first1 != __last1 && __first2 != __last2)
- {
- if (__comp(*__first2, *__first1))
- {
- *__result = *__first2;
- ++__first2;
- }
- else
- {
- *__result = *__first1;
- ++__first1;
- }
- ++__result;
- }
- return std::copy(__first2, __last2, std::copy(__first1, __last1,
- __result));
+ return std::__detail::__merge(__first1, __last1,
+ __first2, __last2, __result,
+ __gnu_cxx::__ops::__iter_comp_iter(__comp, __first2, __first1));
}
+_GLIBCXX_END_NAMESPACE_ALGO
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
+
+ template<typename _RandomAccessIterator, typename _Compare>
+ inline void
+ __stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last,
+ _Compare __comp)
+ {
+ typedef typename iterator_traits<_RandomAccessIterator>::value_type
+ _ValueType;
+ typedef typename iterator_traits<_RandomAccessIterator>::difference_type
+ _DistanceType;
+
+ typedef _Temporary_buffer<_RandomAccessIterator, _ValueType> _TmpBuf;
+ _TmpBuf __buf(__first, __last);
+
+ if (__buf.begin() == 0)
+ std::__detail::__inplace_stable_sort(__first, __last, __comp);
+ else
+ std::__detail::__stable_sort_adaptive(__first, __last, __buf.begin(),
+ _DistanceType(__buf.size()), __comp);
+ }
+
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_ALGO
+
/**
* @brief Sort the elements of a sequence, preserving the relative order
* of equivalent elements.
@@ -5796,24 +5103,15 @@
inline void
stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last)
{
- typedef typename iterator_traits<_RandomAccessIterator>::value_type
- _ValueType;
- typedef typename iterator_traits<_RandomAccessIterator>::difference_type
- _DistanceType;
-
// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIterator>)
- __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
+ __glibcxx_function_requires(_LessThanComparableConcept<
+ typename iterator_traits<_RandomAccessIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- _Temporary_buffer<_RandomAccessIterator, _ValueType> __buf(__first,
- __last);
- if (__buf.begin() == 0)
- std::__inplace_stable_sort(__first, __last);
- else
- std::__stable_sort_adaptive(__first, __last, __buf.begin(),
- _DistanceType(__buf.size()));
+ std::__detail::__stable_sort(__first, __last,
+ __gnu_cxx::__ops::__iter_less_iter(__first));
}
/**
@@ -5839,29 +5137,59 @@
stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last,
_Compare __comp)
{
- typedef typename iterator_traits<_RandomAccessIterator>::value_type
- _ValueType;
- typedef typename iterator_traits<_RandomAccessIterator>::difference_type
- _DistanceType;
-
// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIterator>)
__glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
- _ValueType,
- _ValueType>)
+ typename iterator_traits<_RandomAccessIterator>::value_type,
+ typename iterator_traits<_RandomAccessIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- _Temporary_buffer<_RandomAccessIterator, _ValueType> __buf(__first,
- __last);
- if (__buf.begin() == 0)
- std::__inplace_stable_sort(__first, __last, __comp);
- else
- std::__stable_sort_adaptive(__first, __last, __buf.begin(),
- _DistanceType(__buf.size()), __comp);
+ std::__detail::__stable_sort(__first, __last,
+ __gnu_cxx::__ops::__iter_comp_iter(__comp, __first));
}
+_GLIBCXX_END_NAMESPACE_ALGO
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
+
+ template<typename _InputIterator1, typename _InputIterator2,
+ typename _OutputIterator,
+ typename _Compare12, typename _Compare21>
+ _OutputIterator
+ __set_union(_InputIterator1 __first1, _InputIterator1 __last1,
+ _InputIterator2 __first2, _InputIterator2 __last2,
+ _OutputIterator __result,
+ _Compare12 __comp12, _Compare21 __comp21)
+ {
+ while (__first1 != __last1 && __first2 != __last2)
+ {
+ if (__comp12(__first1, __first2))
+ {
+ *__result = *__first1;
+ ++__first1;
+ }
+ else if (__comp21(__first2, __first1))
+ {
+ *__result = *__first2;
+ ++__first2;
+ }
+ else
+ {
+ *__result = *__first1;
+ ++__first1;
+ ++__first2;
+ }
+ ++__result;
+ }
+ return std::__detail::__copy(__first2, __last2,
+ std::__detail::__copy(__first1, __last1, __result));
+ }
+
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_ALGO
+
/**
* @brief Return the union of two sorted ranges.
* @ingroup set_algorithms
@@ -5887,45 +5215,26 @@
_InputIterator2 __first2, _InputIterator2 __last2,
_OutputIterator __result)
{
- typedef typename iterator_traits<_InputIterator1>::value_type
- _ValueType1;
- typedef typename iterator_traits<_InputIterator2>::value_type
- _ValueType2;
-
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
__glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
- _ValueType1>)
+ typename iterator_traits<_InputIterator1>::value_type>)
__glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
- _ValueType2>)
- __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>)
- __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>)
+ typename iterator_traits<_InputIterator2>::value_type>)
+ __glibcxx_function_requires(_LessThanOpConcept<
+ typename iterator_traits<_InputIterator1>::value_type,
+ typename iterator_traits<_InputIterator2>::value_type>)
+ __glibcxx_function_requires(_LessThanOpConcept<
+ typename iterator_traits<_InputIterator2>::value_type,
+ typename iterator_traits<_InputIterator1>::value_type>)
__glibcxx_requires_sorted_set(__first1, __last1, __first2);
__glibcxx_requires_sorted_set(__first2, __last2, __first1);
- while (__first1 != __last1 && __first2 != __last2)
- {
- if (*__first1 < *__first2)
- {
- *__result = *__first1;
- ++__first1;
- }
- else if (*__first2 < *__first1)
- {
- *__result = *__first2;
- ++__first2;
- }
- else
- {
- *__result = *__first1;
- ++__first1;
- ++__first2;
- }
- ++__result;
- }
- return std::copy(__first2, __last2, std::copy(__first1, __last1,
- __result));
+ return std::__detail::__set_union(__first1, __last1,
+ __first2, __last2, __result,
+ __gnu_cxx::__ops::__iter_less_iter(__first1, __first2),
+ __gnu_cxx::__ops::__iter_less_iter(__first2, __first1));
}
/**
@@ -5954,49 +5263,60 @@
_InputIterator2 __first2, _InputIterator2 __last2,
_OutputIterator __result, _Compare __comp)
{
- typedef typename iterator_traits<_InputIterator1>::value_type
- _ValueType1;
- typedef typename iterator_traits<_InputIterator2>::value_type
- _ValueType2;
-
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
__glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
- _ValueType1>)
+ typename iterator_traits<_InputIterator1>::value_type>)
__glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
- _ValueType2>)
+ typename iterator_traits<_InputIterator2>::value_type>)
__glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
- _ValueType1, _ValueType2>)
+ typename iterator_traits<_InputIterator1>::value_type,
+ typename iterator_traits<_InputIterator2>::value_type>)
__glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
- _ValueType2, _ValueType1>)
+ typename iterator_traits<_InputIterator2>::value_type,
+ typename iterator_traits<_InputIterator1>::value_type>)
__glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp);
__glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp);
+ return std::__detail::__set_union(__first1, __last1,
+ __first2, __last2, __result,
+ __gnu_cxx::__ops::__iter_comp_iter(__comp, __first1, __first2),
+ __gnu_cxx::__ops::__iter_comp_iter(__comp, __first2, __first1));
+ }
+
+_GLIBCXX_END_NAMESPACE_ALGO
+
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
+
+ template<typename _InputIterator1, typename _InputIterator2,
+ typename _OutputIterator,
+ typename _Compare12, typename _Compare21>
+ _OutputIterator
+ __set_intersection(_InputIterator1 __first1, _InputIterator1 __last1,
+ _InputIterator2 __first2, _InputIterator2 __last2,
+ _OutputIterator __result,
+ _Compare12 __comp12, _Compare21 __comp21)
+ {
while (__first1 != __last1 && __first2 != __last2)
- {
- if (__comp(*__first1, *__first2))
- {
- *__result = *__first1;
- ++__first1;
- }
- else if (__comp(*__first2, *__first1))
- {
- *__result = *__first2;
- ++__first2;
- }
- else
- {
- *__result = *__first1;
- ++__first1;
- ++__first2;
- }
- ++__result;
- }
- return std::copy(__first2, __last2, std::copy(__first1, __last1,
- __result));
+ if (__comp12(__first1, __first2))
+ ++__first1;
+ else if (__comp21(__first2, __first1))
+ ++__first2;
+ else
+ {
+ *__result = *__first1;
+ ++__first1;
+ ++__first2;
+ ++__result;
+ }
+ return __result;
}
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_ALGO
+
/**
* @brief Return the intersection of two sorted ranges.
* @ingroup set_algorithms
@@ -6021,34 +5341,24 @@
_InputIterator2 __first2, _InputIterator2 __last2,
_OutputIterator __result)
{
- typedef typename iterator_traits<_InputIterator1>::value_type
- _ValueType1;
- typedef typename iterator_traits<_InputIterator2>::value_type
- _ValueType2;
-
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
__glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
- _ValueType1>)
- __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>)
- __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>)
+ typename iterator_traits<_InputIterator1>::value_type>)
+ __glibcxx_function_requires(_LessThanOpConcept<
+ typename iterator_traits<_InputIterator1>::value_type,
+ typename iterator_traits<_InputIterator2>::value_type>)
+ __glibcxx_function_requires(_LessThanOpConcept<
+ typename iterator_traits<_InputIterator2>::value_type,
+ typename iterator_traits<_InputIterator1>::value_type>)
__glibcxx_requires_sorted_set(__first1, __last1, __first2);
__glibcxx_requires_sorted_set(__first2, __last2, __first1);
- while (__first1 != __last1 && __first2 != __last2)
- if (*__first1 < *__first2)
- ++__first1;
- else if (*__first2 < *__first1)
- ++__first2;
- else
- {
- *__result = *__first1;
- ++__first1;
- ++__first2;
- ++__result;
- }
- return __result;
+ return std::__detail::__set_intersection( __first1, __last1,
+ __first2, __last2, __result,
+ __gnu_cxx::__ops::__iter_less_iter(__first1, __first2),
+ __gnu_cxx::__ops::__iter_less_iter(__first2, __first1));
}
/**
@@ -6078,38 +5388,60 @@
_InputIterator2 __first2, _InputIterator2 __last2,
_OutputIterator __result, _Compare __comp)
{
- typedef typename iterator_traits<_InputIterator1>::value_type
- _ValueType1;
- typedef typename iterator_traits<_InputIterator2>::value_type
- _ValueType2;
-
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
__glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
- _ValueType1>)
+ typename iterator_traits<_InputIterator1>::value_type>)
__glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
- _ValueType1, _ValueType2>)
+ typename iterator_traits<_InputIterator1>::value_type,
+ typename iterator_traits<_InputIterator2>::value_type>)
__glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
- _ValueType2, _ValueType1>)
+ typename iterator_traits<_InputIterator2>::value_type,
+ typename iterator_traits<_InputIterator1>::value_type>)
__glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp);
__glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp);
+ return std::__detail::__set_intersection(__first1, __last1,
+ __first2, __last2, __result,
+ __gnu_cxx::__ops::__iter_comp_iter(__comp, __first1, __first2),
+ __gnu_cxx::__ops::__iter_comp_iter(__comp, __first2, __first1));
+ }
+
+_GLIBCXX_END_NAMESPACE_ALGO
+
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
+
+ template<typename _InputIterator1, typename _InputIterator2,
+ typename _OutputIterator,
+ typename _Compare12, typename _Compare21>
+ _OutputIterator
+ __set_difference(_InputIterator1 __first1, _InputIterator1 __last1,
+ _InputIterator2 __first2, _InputIterator2 __last2,
+ _OutputIterator __result,
+ _Compare12 __comp12, _Compare21 __comp21)
+ {
while (__first1 != __last1 && __first2 != __last2)
- if (__comp(*__first1, *__first2))
- ++__first1;
- else if (__comp(*__first2, *__first1))
+ if (__comp12(__first1, __first2))
+ {
+ *__result = *__first1;
+ ++__first1;
+ ++__result;
+ }
+ else if (__comp21(__first2, __first1))
++__first2;
else
{
- *__result = *__first1;
++__first1;
++__first2;
- ++__result;
}
- return __result;
+ return std::__detail::__copy(__first1, __last1, __result);
}
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_ALGO
+
/**
* @brief Return the difference of two sorted ranges.
* @ingroup set_algorithms
@@ -6136,36 +5468,24 @@
_InputIterator2 __first2, _InputIterator2 __last2,
_OutputIterator __result)
{
- typedef typename iterator_traits<_InputIterator1>::value_type
- _ValueType1;
- typedef typename iterator_traits<_InputIterator2>::value_type
- _ValueType2;
-
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
__glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
- _ValueType1>)
- __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>)
- __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>)
+ typename iterator_traits<_InputIterator1>::value_type>)
+ __glibcxx_function_requires(_LessThanOpConcept<
+ typename iterator_traits<_InputIterator1>::value_type,
+ typename iterator_traits<_InputIterator2>::value_type>)
+ __glibcxx_function_requires(_LessThanOpConcept<
+ typename iterator_traits<_InputIterator2>::value_type,
+ typename iterator_traits<_InputIterator1>::value_type>)
__glibcxx_requires_sorted_set(__first1, __last1, __first2);
__glibcxx_requires_sorted_set(__first2, __last2, __first1);
- while (__first1 != __last1 && __first2 != __last2)
- if (*__first1 < *__first2)
- {
- *__result = *__first1;
- ++__first1;
- ++__result;
- }
- else if (*__first2 < *__first1)
- ++__first2;
- else
- {
- ++__first1;
- ++__first2;
- }
- return std::copy(__first1, __last1, __result);
+ return std::__detail::__set_difference(__first1, __last1,
+ __first2, __last2, __result,
+ __gnu_cxx::__ops::__iter_less_iter(__first1, __first2),
+ __gnu_cxx::__ops::__iter_less_iter(__first2, __first1));
}
/**
@@ -6197,40 +5517,67 @@
_InputIterator2 __first2, _InputIterator2 __last2,
_OutputIterator __result, _Compare __comp)
{
- typedef typename iterator_traits<_InputIterator1>::value_type
- _ValueType1;
- typedef typename iterator_traits<_InputIterator2>::value_type
- _ValueType2;
-
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
__glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
- _ValueType1>)
+ typename iterator_traits<_InputIterator1>::value_type>)
__glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
- _ValueType1, _ValueType2>)
+ typename iterator_traits<_InputIterator1>::value_type,
+ typename iterator_traits<_InputIterator2>::value_type>)
__glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
- _ValueType2, _ValueType1>)
+ typename iterator_traits<_InputIterator2>::value_type,
+ typename iterator_traits<_InputIterator1>::value_type>)
__glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp);
__glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp);
+ return std::__detail::__set_difference(__first1, __last1,
+ __first2, __last2, __result,
+ __gnu_cxx::__ops::__iter_comp_iter(__comp, __first1, __first2),
+ __gnu_cxx::__ops::__iter_comp_iter(__comp, __first2, __first1));
+ }
+
+_GLIBCXX_END_NAMESPACE_ALGO
+
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
+
+ template<typename _InputIterator1, typename _InputIterator2,
+ typename _OutputIterator,
+ typename _Compare12, typename _Compare21>
+ _OutputIterator
+ __set_symmetric_difference(_InputIterator1 __first1,
+ _InputIterator1 __last1,
+ _InputIterator2 __first2,
+ _InputIterator2 __last2,
+ _OutputIterator __result,
+ _Compare12 __comp12, _Compare21 __comp21)
+ {
while (__first1 != __last1 && __first2 != __last2)
- if (__comp(*__first1, *__first2))
+ if (__comp12(__first1, __first2))
{
*__result = *__first1;
++__first1;
++__result;
}
- else if (__comp(*__first2, *__first1))
- ++__first2;
+ else if (__comp21(__first2, __first1))
+ {
+ *__result = *__first2;
+ ++__first2;
+ ++__result;
+ }
else
{
++__first1;
++__first2;
}
- return std::copy(__first1, __last1, __result);
+ return std::__detail::__copy(__first2, __last2,
+ std::__detail::__copy(__first1, __last1, __result));
}
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_ALGO
+
/**
* @brief Return the symmetric difference of two sorted ranges.
* @ingroup set_algorithms
@@ -6255,43 +5602,26 @@
_InputIterator2 __first2, _InputIterator2 __last2,
_OutputIterator __result)
{
- typedef typename iterator_traits<_InputIterator1>::value_type
- _ValueType1;
- typedef typename iterator_traits<_InputIterator2>::value_type
- _ValueType2;
-
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
__glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
- _ValueType1>)
+ typename iterator_traits<_InputIterator1>::value_type>)
__glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
- _ValueType2>)
- __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>)
- __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>)
+ typename iterator_traits<_InputIterator2>::value_type>)
+ __glibcxx_function_requires(_LessThanOpConcept<
+ typename iterator_traits<_InputIterator1>::value_type,
+ typename iterator_traits<_InputIterator2>::value_type>)
+ __glibcxx_function_requires(_LessThanOpConcept<
+ typename iterator_traits<_InputIterator2>::value_type,
+ typename iterator_traits<_InputIterator1>::value_type>)
__glibcxx_requires_sorted_set(__first1, __last1, __first2);
__glibcxx_requires_sorted_set(__first2, __last2, __first1);
- while (__first1 != __last1 && __first2 != __last2)
- if (*__first1 < *__first2)
- {
- *__result = *__first1;
- ++__first1;
- ++__result;
- }
- else if (*__first2 < *__first1)
- {
- *__result = *__first2;
- ++__first2;
- ++__result;
- }
- else
- {
- ++__first1;
- ++__first2;
- }
- return std::copy(__first2, __last2, std::copy(__first1,
- __last1, __result));
+ return std::__detail::__set_symmetric_difference(
+ __first1, __last1, __first2, __last2, __result,
+ __gnu_cxx::__ops::__iter_less_iter(__first1, __first2),
+ __gnu_cxx::__ops::__iter_less_iter(__first2, __first1));
}
/**
@@ -6322,48 +5652,50 @@
_OutputIterator __result,
_Compare __comp)
{
- typedef typename iterator_traits<_InputIterator1>::value_type
- _ValueType1;
- typedef typename iterator_traits<_InputIterator2>::value_type
- _ValueType2;
-
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
__glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
- _ValueType1>)
+ typename iterator_traits<_InputIterator1>::value_type>)
__glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
- _ValueType2>)
+ typename iterator_traits<_InputIterator2>::value_type>)
__glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
- _ValueType1, _ValueType2>)
+ typename iterator_traits<_InputIterator1>::value_type,
+ typename iterator_traits<_InputIterator2>::value_type>)
__glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
- _ValueType2, _ValueType1>)
+ typename iterator_traits<_InputIterator2>::value_type,
+ typename iterator_traits<_InputIterator1>::value_type>)
__glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp);
__glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp);
- while (__first1 != __last1 && __first2 != __last2)
- if (__comp(*__first1, *__first2))
- {
- *__result = *__first1;
- ++__first1;
- ++__result;
- }
- else if (__comp(*__first2, *__first1))
- {
- *__result = *__first2;
- ++__first2;
- ++__result;
- }
- else
- {
- ++__first1;
- ++__first2;
- }
- return std::copy(__first2, __last2,
- std::copy(__first1, __last1, __result));
+ return std::__detail::__set_symmetric_difference(
+ __first1, __last1, __first2, __last2, __result,
+ __gnu_cxx::__ops::__iter_comp_iter(__comp, __first1, __first2),
+ __gnu_cxx::__ops::__iter_comp_iter(__comp, __first2, __first1));
}
+_GLIBCXX_END_NAMESPACE_ALGO
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
+
+ template<typename _ForwardIterator, typename _Compare>
+ _ForwardIterator
+ __min_element(_ForwardIterator __first, _ForwardIterator __last,
+ _Compare __comp)
+ {
+ if (__first == __last)
+ return __first;
+ _ForwardIterator __result = __first;
+ while (++__first != __last)
+ if (__comp(__first, __result))
+ __result = __first;
+ return __result;
+ }
+
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_ALGO
+
/**
* @brief Return the minimum element in a range.
* @ingroup sorting_algorithms
@@ -6381,13 +5713,8 @@
typename iterator_traits<_ForwardIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- if (__first == __last)
- return __first;
- _ForwardIterator __result = __first;
- while (++__first != __last)
- if (*__first < *__result)
- __result = __first;
- return __result;
+ return std::__detail::__min_element(__first, __last,
+ __gnu_cxx::__ops::__iter_less_iter(__first));
}
/**
@@ -6411,15 +5738,31 @@
typename iterator_traits<_ForwardIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- if (__first == __last)
- return __first;
+ return std::__detail::__min_element(__first, __last,
+ __gnu_cxx::__ops::__iter_comp_iter(__comp, __first));
+ }
+
+_GLIBCXX_END_NAMESPACE_ALGO
+
+_GLIBCXX_BEGIN_NAMESPACE_DETAIL
+
+ template<typename _ForwardIterator, typename _Compare>
+ _ForwardIterator
+ __max_element(_ForwardIterator __first, _ForwardIterator __last,
+ _Compare __comp)
+ {
+ if (__first == __last) return __first;
_ForwardIterator __result = __first;
while (++__first != __last)
- if (__comp(*__first, *__result))
+ if (__comp(__result, __first))
__result = __first;
return __result;
}
+_GLIBCXX_END_NAMESPACE_DETAIL
+
+_GLIBCXX_BEGIN_NAMESPACE_ALGO
+
/**
* @brief Return the maximum element in a range.
* @ingroup sorting_algorithms
@@ -6437,13 +5780,8 @@
typename iterator_traits<_ForwardIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- if (__first == __last)
- return __first;
- _ForwardIterator __result = __first;
- while (++__first != __last)
- if (*__result < *__first)
- __result = __first;
- return __result;
+ return std::__detail::__max_element(__first, __last,
+ __gnu_cxx::__ops::__iter_less_iter(__first));
}
/**
@@ -6467,12 +5805,8 @@
typename iterator_traits<_ForwardIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- if (__first == __last) return __first;
- _ForwardIterator __result = __first;
- while (++__first != __last)
- if (__comp(*__result, *__first))
- __result = __first;
- return __result;
+ return std::__detail::__max_element(__first, __last,
+ __gnu_cxx::__ops::__iter_comp_iter(__comp, __first));
}
_GLIBCXX_END_NAMESPACE_ALGO
Index: include/Makefile.am
===================================================================
--- include/Makefile.am (revision 202183)
+++ include/Makefile.am (working copy)
@@ -121,6 +121,7 @@
${bits_srcdir}/ostream_insert.h \
${bits_srcdir}/parse_numbers.h \
${bits_srcdir}/postypes.h \
+ ${bits_srcdir}/predefined_ops.h \
${bits_srcdir}/ptr_traits.h \
${bits_srcdir}/random.h \
${bits_srcdir}/random.tcc \
Index: include/Makefile.in
===================================================================
--- include/Makefile.in (revision 202183)
+++ include/Makefile.in (working copy)
@@ -388,6 +388,7 @@
${bits_srcdir}/ostream_insert.h \
${bits_srcdir}/parse_numbers.h \
${bits_srcdir}/postypes.h \
+ ${bits_srcdir}/predefined_ops.h \
${bits_srcdir}/ptr_traits.h \
${bits_srcdir}/random.h \
${bits_srcdir}/random.tcc \