This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Remove algo duplication


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 \

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]