I think I still got no feedback about this cleanup proposal.

Here is a new version.

François

On 15/06/2023 07:07, François Dumont wrote:
I think we all agree that __gnu_cxx::__ops needed to be reimplemented, here it is.

Note that I kept the usage of std::ref in <string>, <vector> and <deque>.

    libstdc++: Reimplement __gnu_cxx::__ops operators

    Replace functors using iterators as input to adopt functors that
    are matching the same Standard expectations as the ones imposed on
    predicates used in predicates-aware algos. Doing so we need far less
    functors. It impose that iterators are dereference at algo level and
    not in the functors anymore.

    libstdc++-v3/ChangeLog:

            * include/std/functional (_Not_fn): Move to...
            * include/bits/predefined_ops.h: ...here, and expose a version
            in pre-C++14 mode.
            (__not_fn): New, use latter.
            (_Iter_less_iter, _Iter_less_val, _Val_less_iter, _Iter_equal_to_iter)             (_Iter_equal_to_val, _Iter_comp_iter, _Iter_comp_val, _Val_comp_iter)             (_Iter_equals_val, _Iter_equals_iter, _Iter_pred, _Iter_comp_val)             (_Iter_comp_to_val, _Iter_comp_to_iter, _Iter_negate): Remove.             (__iter_less_iter, __iter_less_val, __iter_comp_val, __val_less_iter)             (__val_comp_iter, __iter_equal_to_iter, __iter_equal_to_val, __iter_comp_iter)             (__val_comp_iter, __iter_equals_val, __iter_comp_iter, __pred_iter): Remove.
            (_Less, _Equal_to, _Equal_to_val, _Comp_val): New.
            (__less, __equal_to, __comp_val): New.
            * include/bits/stl_algo.h: Adapt all algos to use new __gnu_cxx::__ops operators.             When possible use std::move to pass predicates between routines.
            * include/bits/stl_algobase.h: Likewise.
            * include/bits/stl_heap.h: Likewise.
            * include/std/deque: Cleanup usage of __gnu_cxx::__ops operators.
            * include/std/string: Likewise.
            * include/std/vector: Likewise.

Tested under Linux x86_64 normal and _GLIBCXX_DEBUG modes.

Ok to commit ?

François
diff --git a/libstdc++-v3/include/bits/predefined_ops.h 
b/libstdc++-v3/include/bits/predefined_ops.h
index e9933373ed9..8753e6f64cd 100644
--- a/libstdc++-v3/include/bits/predefined_ops.h
+++ b/libstdc++-v3/include/bits/predefined_ops.h
@@ -32,376 +32,229 @@
 
 #include <bits/move.h>
 
+#if __cplusplus >= 201103L
+# include <bits/invoke.h>
+#endif
+
 namespace __gnu_cxx
 {
 namespace __ops
 {
-  struct _Iter_less_iter
+  struct _Less
   {
-    template<typename _Iterator1, typename _Iterator2>
+    template<typename _Lhs, typename _Rhs>
       _GLIBCXX14_CONSTEXPR
       bool
-      operator()(_Iterator1 __it1, _Iterator2 __it2) const
-      { return *__it1 < *__it2; }
+      operator()(const _Lhs& __lhs, const _Rhs& __rhs) const
+      { return __lhs < __rhs; }
   };
 
   _GLIBCXX14_CONSTEXPR
-  inline _Iter_less_iter
-  __iter_less_iter()
-  { return _Iter_less_iter(); }
-
-  struct _Iter_less_val
-  {
-#if __cplusplus >= 201103L
-    constexpr _Iter_less_val() = default;
-#else
-    _Iter_less_val() { }
-#endif
-
-    _GLIBCXX20_CONSTEXPR
-    explicit
-    _Iter_less_val(_Iter_less_iter) { }
-
-    template<typename _Iterator, typename _Value>
-      _GLIBCXX20_CONSTEXPR
-      bool
-      operator()(_Iterator __it, _Value& __val) const
-      { return *__it < __val; }
-  };
-
-  _GLIBCXX20_CONSTEXPR
-  inline _Iter_less_val
-  __iter_less_val()
-  { return _Iter_less_val(); }
-
-  _GLIBCXX20_CONSTEXPR
-  inline _Iter_less_val
-  __iter_comp_val(_Iter_less_iter)
-  { return _Iter_less_val(); }
-
-  struct _Val_less_iter
-  {
-#if __cplusplus >= 201103L
-    constexpr _Val_less_iter() = default;
-#else
-    _Val_less_iter() { }
-#endif
-
-    _GLIBCXX20_CONSTEXPR
-    explicit
-    _Val_less_iter(_Iter_less_iter) { }
-
-    template<typename _Value, typename _Iterator>
-      _GLIBCXX20_CONSTEXPR
-      bool
-      operator()(_Value& __val, _Iterator __it) const
-      { return __val < *__it; }
-  };
+  inline _Less
+  __less()
+  { return _Less(); }
 
-  _GLIBCXX20_CONSTEXPR
-  inline _Val_less_iter
-  __val_less_iter()
-  { return _Val_less_iter(); }
-
-  _GLIBCXX20_CONSTEXPR
-  inline _Val_less_iter
-  __val_comp_iter(_Iter_less_iter)
-  { return _Val_less_iter(); }
-
-  struct _Iter_equal_to_iter
+  struct _Equal_to
   {
-    template<typename _Iterator1, typename _Iterator2>
+    template<typename _Lhs, typename _Rhs>
       _GLIBCXX20_CONSTEXPR
       bool
-      operator()(_Iterator1 __it1, _Iterator2 __it2) const
-      { return *__it1 == *__it2; }
+      operator()(const _Lhs& __lhs, const _Rhs& __rhs) const
+      { return __lhs == __rhs; }
   };
 
   _GLIBCXX20_CONSTEXPR
-  inline _Iter_equal_to_iter
-  __iter_equal_to_iter()
-  { return _Iter_equal_to_iter(); }
-
-  struct _Iter_equal_to_val
-  {
-    template<typename _Iterator, typename _Value>
-      _GLIBCXX20_CONSTEXPR
-      bool
-      operator()(_Iterator __it, _Value& __val) const
-      { return *__it == __val; }
-  };
+  inline _Equal_to
+  __equal_to()
+  { return _Equal_to(); }
 
-  _GLIBCXX20_CONSTEXPR
-  inline _Iter_equal_to_val
-  __iter_equal_to_val()
-  { return _Iter_equal_to_val(); }
-
-  _GLIBCXX20_CONSTEXPR
-  inline _Iter_equal_to_val
-  __iter_comp_val(_Iter_equal_to_iter)
-  { return _Iter_equal_to_val(); }
-
-  template<typename _Compare>
-    struct _Iter_comp_iter
+  template<typename _Val>
+    struct _Equal_to_val
     {
-      _Compare _M_comp;
-
-      explicit _GLIBCXX14_CONSTEXPR
-      _Iter_comp_iter(_Compare __comp)
-       : _M_comp(_GLIBCXX_MOVE(__comp))
-      { }
-
-      template<typename _Iterator1, typename _Iterator2>
-        _GLIBCXX14_CONSTEXPR
-        bool
-        operator()(_Iterator1 __it1, _Iterator2 __it2)
-        { return bool(_M_comp(*__it1, *__it2)); }
-    };
-
-  template<typename _Compare>
-    _GLIBCXX14_CONSTEXPR
-    inline _Iter_comp_iter<_Compare>
-    __iter_comp_iter(_Compare __comp)
-    { return _Iter_comp_iter<_Compare>(_GLIBCXX_MOVE(__comp)); }
-
-  template<typename _Compare>
-    struct _Iter_comp_val
-    {
-      _Compare _M_comp;
+      const _Val& _M_val;
 
       _GLIBCXX20_CONSTEXPR
-      explicit
-      _Iter_comp_val(_Compare __comp)
-       : _M_comp(_GLIBCXX_MOVE(__comp))
+      _Equal_to_val(const _Val& __val)
+      : _M_val(__val)
       { }
 
-      _GLIBCXX20_CONSTEXPR
-      explicit
-      _Iter_comp_val(const _Iter_comp_iter<_Compare>& __comp)
-       : _M_comp(__comp._M_comp)
-      { }
-
-#if __cplusplus >= 201103L
-      _GLIBCXX20_CONSTEXPR
-      explicit
-      _Iter_comp_val(_Iter_comp_iter<_Compare>&& __comp)
-       : _M_comp(std::move(__comp._M_comp))
-      { }
-#endif
-
-      template<typename _Iterator, typename _Value>
+      template<typename _Lhs>
        _GLIBCXX20_CONSTEXPR
        bool
-       operator()(_Iterator __it, _Value& __val)
-       { return bool(_M_comp(*__it, __val)); }
+       operator()(const _Lhs& __lhs) const
+       { return __lhs == _M_val; }
     };
 
-  template<typename _Compare>
+  template<typename _Val>
     _GLIBCXX20_CONSTEXPR
-    inline _Iter_comp_val<_Compare>
-    __iter_comp_val(_Compare __comp)
-    { return _Iter_comp_val<_Compare>(_GLIBCXX_MOVE(__comp)); }
+    inline _Equal_to_val<_Val>
+    __equal_to(const _Val& __val)
+    { return _Equal_to_val<_Val>(__val); }
 
-  template<typename _Compare>
-    _GLIBCXX20_CONSTEXPR
-    inline _Iter_comp_val<_Compare>
-    __iter_comp_val(_Iter_comp_iter<_Compare> __comp)
-    { return _Iter_comp_val<_Compare>(_GLIBCXX_MOVE(__comp)); }
-
-  template<typename _Compare>
-    struct _Val_comp_iter
+  template<typename _BinaryPred, typename _Val>
+    struct _Comp_val
     {
-      _Compare _M_comp;
-
-      _GLIBCXX20_CONSTEXPR
-      explicit
-      _Val_comp_iter(_Compare __comp)
-       : _M_comp(_GLIBCXX_MOVE(__comp))
-      { }
-
-      _GLIBCXX20_CONSTEXPR
-      explicit
-      _Val_comp_iter(const _Iter_comp_iter<_Compare>& __comp)
-       : _M_comp(__comp._M_comp)
-      { }
-
 #if __cplusplus >= 201103L
-      _GLIBCXX20_CONSTEXPR
-      explicit
-      _Val_comp_iter(_Iter_comp_iter<_Compare>&& __comp)
-       : _M_comp(std::move(__comp._M_comp))
+      template<typename _BPred>
+       constexpr
+       _Comp_val(_BPred&& __pred, const _Val& __val)
+       : _M_binary_pred(std::forward<_BPred>(__pred)), _M_val(__val)
+       { }
+
+      _Comp_val(const _Comp_val&) = default;
+      _Comp_val(_Comp_val&&) = default;
+      ~_Comp_val() = default;
+#else
+    public:
+      _Comp_val(_BinaryPred __pred, const _Val& __val)
+      : _M_binary_pred(__pred), _M_val(__val)
       { }
 #endif
 
-      template<typename _Value, typename _Iterator>
-       _GLIBCXX20_CONSTEXPR
-       bool
-       operator()(_Value& __val, _Iterator __it)
-       { return bool(_M_comp(__val, *__it)); }
-    };
-
-  template<typename _Compare>
-    _GLIBCXX20_CONSTEXPR
-    inline _Val_comp_iter<_Compare>
-    __val_comp_iter(_Compare __comp)
-    { return _Val_comp_iter<_Compare>(_GLIBCXX_MOVE(__comp)); }
-
-  template<typename _Compare>
-    _GLIBCXX20_CONSTEXPR
-    inline _Val_comp_iter<_Compare>
-    __val_comp_iter(_Iter_comp_iter<_Compare> __comp)
-    { return _Val_comp_iter<_Compare>(_GLIBCXX_MOVE(__comp)); }
-
-  template<typename _Value>
-    struct _Iter_equals_val
-    {
-      _Value& _M_value;
-
-      _GLIBCXX20_CONSTEXPR
-      explicit
-      _Iter_equals_val(_Value& __value)
-       : _M_value(__value)
-      { }
-
-      template<typename _Iterator>
-       _GLIBCXX20_CONSTEXPR
-       bool
-       operator()(_Iterator __it)
-       { return *__it == _M_value; }
-    };
-
-  template<typename _Value>
-    _GLIBCXX20_CONSTEXPR
-    inline _Iter_equals_val<_Value>
-    __iter_equals_val(_Value& __val)
-    { return _Iter_equals_val<_Value>(__val); }
-
-  template<typename _Iterator1>
-    struct _Iter_equals_iter
-    {
-      _Iterator1 _M_it1;
-
-      _GLIBCXX20_CONSTEXPR
-      explicit
-      _Iter_equals_iter(_Iterator1 __it1)
-       : _M_it1(__it1)
-      { }
-
-      template<typename _Iterator2>
-       _GLIBCXX20_CONSTEXPR
-       bool
-       operator()(_Iterator2 __it2)
-       { return *__it2 == *_M_it1; }
-    };
-
-  template<typename _Iterator>
-    _GLIBCXX20_CONSTEXPR
-    inline _Iter_equals_iter<_Iterator>
-    __iter_comp_iter(_Iter_equal_to_iter, _Iterator __it)
-    { return _Iter_equals_iter<_Iterator>(__it); }
-
-  template<typename _Predicate>
-    struct _Iter_pred
-    {
-      _Predicate _M_pred;
-
-      _GLIBCXX20_CONSTEXPR
-      explicit
-      _Iter_pred(_Predicate __pred)
-       : _M_pred(_GLIBCXX_MOVE(__pred))
-      { }
-
-      template<typename _Iterator>
-       _GLIBCXX20_CONSTEXPR
-       bool
-       operator()(_Iterator __it)
-       { return bool(_M_pred(*__it)); }
-    };
-
-  template<typename _Predicate>
-    _GLIBCXX20_CONSTEXPR
-    inline _Iter_pred<_Predicate>
-    __pred_iter(_Predicate __pred)
-    { return _Iter_pred<_Predicate>(_GLIBCXX_MOVE(__pred)); }
-
-  template<typename _Compare, typename _Value>
-    struct _Iter_comp_to_val
-    {
-      _Compare _M_comp;
-      _Value& _M_value;
-
-      _GLIBCXX20_CONSTEXPR
-      _Iter_comp_to_val(_Compare __comp, _Value& __value)
-       : _M_comp(_GLIBCXX_MOVE(__comp)), _M_value(__value)
-      { }
-
-      template<typename _Iterator>
-       _GLIBCXX20_CONSTEXPR
+#if __cplusplus >= 201103L
+      // Macro to define operator() with given cv-qualifiers ref-qualifiers,
+      // forwarding _M_binary_pred and the function arguments with the same
+      // qualifiers, and deducing the return type and exception-specification.
+# define _GLIBCXX_BINARY_PRED_CALL_OP( _QUALS )                                
\
+      template<typename _Arg,                                          \
+              typename = std::__enable_if_t<std::__is_invocable<       \
+                _BinaryPred _QUALS, _Arg, const _Val&>::value>>        \
+       _GLIBCXX20_CONSTEXPR                                            \
+       bool                                                            \
+       operator()(_Arg&& __arg) _QUALS                                 \
+       noexcept(std::__is_nothrow_invocable<                           \
+                _BinaryPred _QUALS, _Arg, const _Val&>::value)         \
+       {                                                               \
+         return std::__invoke(                                         \
+                  std::forward< _BinaryPred _QUALS >(_M_binary_pred),  \
+                  std::forward<_Arg>(__arg), _M_val);                  \
+       }                                                               \
+                                                                       \
+      template<typename _Arg,                                          \
+              typename = std::__enable_if_t<!std::__is_invocable<      \
+                _BinaryPred _QUALS, _Arg, const _Val&>::value>>        \
+       void operator()(_Arg&&) _QUALS = delete;
+
+      _GLIBCXX_BINARY_PRED_CALL_OP( & )
+      _GLIBCXX_BINARY_PRED_CALL_OP( const & )
+      _GLIBCXX_BINARY_PRED_CALL_OP( && )
+      _GLIBCXX_BINARY_PRED_CALL_OP( const && )
+# undef _GLIBCXX_BINARY_PRED_CALL_OP
+#else
+      template<typename _Lhs>
        bool
-       operator()(_Iterator __it)
-       { return bool(_M_comp(*__it, _M_value)); }
+       operator()(const _Lhs& __lhs)
+       { return bool(_M_binary_pred(__lhs, _M_val)); }
+#endif
+    private:
+      _BinaryPred _M_binary_pred;
+      const _Val& _M_val;
     };
 
-  template<typename _Compare, typename _Value>
-    _Iter_comp_to_val<_Compare, _Value>
+#if __cplusplus >= 201103L
+  template<typename _BPred, typename _Val>
     _GLIBCXX20_CONSTEXPR
-    __iter_comp_val(_Compare __comp, _Value &__val)
+    inline _Comp_val<std::__decay_t<_BPred>, _Val>
+    __comp_val(_BPred&& __pred, const _Val& __val)
+    noexcept(std::is_nothrow_constructible<std::__decay_t<_BPred>,
+            _BPred&&>::value)
     {
-      return _Iter_comp_to_val<_Compare, _Value>(_GLIBCXX_MOVE(__comp), __val);
+      return
+       _Comp_val<std::__decay_t<_BPred>, _Val>(std::forward<_BPred>(__pred),
+                                               __val);
     }
+#else
+  template<typename _BPred, typename _Val>
+    inline _Comp_val<_BPred, _Val>
+    __comp_val(_BPred __pred, const _Val& __val)
+    { return _Comp_val<_BPred, _Val>(__pred, __val); }
+#endif
+} // namespace __ops
+} // namespace __gnu_cxx
 
-  template<typename _Compare, typename _Iterator1>
-    struct _Iter_comp_to_iter
-    {
-      _Compare _M_comp;
-      _Iterator1 _M_it1;
-
-      _GLIBCXX20_CONSTEXPR
-      _Iter_comp_to_iter(_Compare __comp, _Iterator1 __it1)
-       : _M_comp(_GLIBCXX_MOVE(__comp)), _M_it1(__it1)
-      { }
-
-      template<typename _Iterator2>
-       _GLIBCXX20_CONSTEXPR
-       bool
-       operator()(_Iterator2 __it2)
-       { return bool(_M_comp(*__it2, *_M_it1)); }
-    };
 
-  template<typename _Compare, typename _Iterator>
-    _GLIBCXX20_CONSTEXPR
-    inline _Iter_comp_to_iter<_Compare, _Iterator>
-    __iter_comp_iter(_Iter_comp_iter<_Compare> __comp, _Iterator __it)
-    {
-      return _Iter_comp_to_iter<_Compare, _Iterator>(
-         _GLIBCXX_MOVE(__comp._M_comp), __it);
-    }
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-  template<typename _Predicate>
-    struct _Iter_negate
+  /// Generalized negator.
+  template<typename _Fn>
+    class _Not_fn
     {
-      _Predicate _M_pred;
-
-      _GLIBCXX20_CONSTEXPR
-      explicit
-      _Iter_negate(_Predicate __pred)
-       : _M_pred(_GLIBCXX_MOVE(__pred))
-      { }
+#if __cplusplus >= 201103L
+      template<typename _Fn2, typename... _Args>
+       using __inv_res_t = typename __invoke_result<_Fn2, _Args...>::type;
+
+      template<typename _Tp>
+       static decltype(!std::declval<_Tp>())
+       _S_not() noexcept(noexcept(!std::declval<_Tp>()));
+
+    public:
+      template<typename _Fn2>
+       constexpr
+       _Not_fn(_Fn2&& __fn, int)
+       : _M_fn(std::forward<_Fn2>(__fn)) { }
+
+      _Not_fn(const _Not_fn& __fn) = default;
+      _Not_fn(_Not_fn&& __fn) = default;
+      ~_Not_fn() = default;
+#else
+    public:
+      _Not_fn(_Fn __fn, int)
+      : _M_fn(__fn) { }
+#endif
 
-      template<typename _Iterator>
-       _GLIBCXX20_CONSTEXPR
+#if __cplusplus >= 201103L
+      // Macro to define operator() with given cv-qualifiers ref-qualifiers,
+      // forwarding _M_fn and the function arguments with the same qualifiers,
+      // and deducing the return type and exception-specification.
+# define _GLIBCXX_NOT_FN_CALL_OP( _QUALS )                             \
+      template<typename... _Args,                                      \
+              typename = __enable_if_t<__is_invocable<_Fn _QUALS, 
_Args...>::value>> \
+       _GLIBCXX20_CONSTEXPR                                            \
+       decltype(_S_not<__inv_res_t<_Fn _QUALS, _Args...>>())           \
+       operator()(_Args&&... __args) _QUALS                            \
+       noexcept(__is_nothrow_invocable<_Fn _QUALS, _Args...>::value    \
+           && noexcept(_S_not<__inv_res_t<_Fn _QUALS, _Args...>>()))   \
+       {                                                               \
+         return !std::__invoke(std::forward< _Fn _QUALS >(_M_fn),      \
+                               std::forward<_Args>(__args)...);        \
+       }                                                               \
+                                                                       \
+      template<typename... _Args,                                      \
+              typename = __enable_if_t<!__is_invocable<_Fn _QUALS, 
_Args...>::value>> \
+       void operator()(_Args&&... __args) _QUALS = delete;
+
+      _GLIBCXX_NOT_FN_CALL_OP( & )
+      _GLIBCXX_NOT_FN_CALL_OP( const & )
+      _GLIBCXX_NOT_FN_CALL_OP( && )
+      _GLIBCXX_NOT_FN_CALL_OP( const && )
+# undef _GLIBCXX_NOT_FN_CALL_OP
+#else
+      template<typename _Arg>
        bool
-       operator()(_Iterator __it)
-       { return !bool(_M_pred(*__it)); }
+       operator()(const _Arg& __arg)
+       { return !bool(_M_fn(__arg)); }
+#endif
+    private:
+      _Fn _M_fn;
     };
 
-  template<typename _Predicate>
+#if __cplusplus >= 201103L
+  template<typename _Fn>
     _GLIBCXX20_CONSTEXPR
-    inline _Iter_negate<_Predicate>
-    __negate(_Iter_pred<_Predicate> __pred)
-    { return _Iter_negate<_Predicate>(_GLIBCXX_MOVE(__pred._M_pred)); }
+    inline _Not_fn<std::__decay_t<_Fn>>
+    __not_fn(_Fn&& __fn)
+    noexcept(std::is_nothrow_constructible<std::__decay_t<_Fn>, _Fn&&>::value)
+    { return _Not_fn<std::__decay_t<_Fn>>{std::forward<_Fn>(__fn), 0}; }
+#else
+  template<typename _Fn>
+    inline _Not_fn<_Fn>
+    __not_fn(_Fn __fn)
+    { return _Not_fn<_Fn>(__fn, 0); }
+#endif
 
-} // namespace __ops
-} // namespace __gnu_cxx
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
 
 #endif
diff --git a/libstdc++-v3/include/bits/stl_algo.h 
b/libstdc++-v3/include/bits/stl_algo.h
index 0b34a4f86b0..2ef5b6717bd 100644
--- a/libstdc++-v3/include/bits/stl_algo.h
+++ b/libstdc++-v3/include/bits/stl_algo.h
@@ -85,18 +85,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     __move_median_to_first(_Iterator __result,_Iterator __a, _Iterator __b,
                           _Iterator __c, _Compare __comp)
     {
-      if (__comp(__a, __b))
+      if (__comp(*__a, *__b))
        {
-         if (__comp(__b, __c))
+         if (__comp(*__b, *__c))
            std::iter_swap(__result, __b);
-         else if (__comp(__a, __c))
+         else if (__comp(*__a, *__c))
            std::iter_swap(__result, __c);
          else
            std::iter_swap(__result, __a);
        }
-      else if (__comp(__a, __c))
+      else if (__comp(*__a, *__c))
        std::iter_swap(__result, __a);
-      else if (__comp(__b, __c))
+      else if (__comp(*__b, *__c))
        std::iter_swap(__result, __c);
       else
        std::iter_swap(__result, __b);
@@ -110,7 +110,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                  _Predicate __pred)
     {
       return std::__find_if(__first, __last,
-                           __gnu_cxx::__ops::__negate(__pred),
+                           std::__not_fn(_GLIBCXX_MOVE(__pred)),
                            std::__iterator_category(__first));
     }
 
@@ -123,7 +123,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     __find_if_not_n(_InputIterator __first, _Distance& __len, _Predicate 
__pred)
     {
       for (; __len; --__len,  (void) ++__first)
-       if (!__pred(__first))
+       if (!__pred(*__first))
          break;
       return __first;
     }
@@ -160,7 +160,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
            __n = __count;
          _ForwardIterator __i = __first;
          ++__i;
-         while (__i != __last && __n != 1 && __unary_pred(__i))
+         while (__i != __last && __n != 1 && __unary_pred(*__i))
            {
              ++__i;
              --__n;
@@ -199,7 +199,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
          // __first here is always pointing to one past the last element of
          // next possible match.
          _RandomAccessIter __backTrack = __first; 
-         while (__unary_pred(--__backTrack))
+         while (__unary_pred(*(--__backTrack)))
            {
              if (--__remainder == 0)
                return (__first - __count); // Success
@@ -337,7 +337,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       return std::__find_end(__first1, __last1, __first2, __last2,
                             std::__iterator_category(__first1),
                             std::__iterator_category(__first2),
-                            __gnu_cxx::__ops::__iter_equal_to_iter());
+                            __gnu_cxx::__ops::__equal_to());
     }
 
   /**
@@ -388,7 +388,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       return std::__find_end(__first1, __last1, __first2, __last2,
                             std::__iterator_category(__first1),
                             std::__iterator_category(__first2),
-                            __gnu_cxx::__ops::__iter_comp_iter(__comp));
+                            _GLIBCXX_MOVE(__comp));
     }
 
 #if __cplusplus >= 201103L
@@ -408,7 +408,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     _GLIBCXX20_CONSTEXPR
     inline bool
     all_of(_InputIterator __first, _InputIterator __last, _Predicate __pred)
-    { return __last == std::find_if_not(__first, __last, __pred); }
+    { return __last == std::find_if_not(__first, __last, std::move(__pred)); }
 
   /**
    *  @brief  Checks that a predicate is false for all the elements
@@ -426,7 +426,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     _GLIBCXX20_CONSTEXPR
     inline bool
     none_of(_InputIterator __first, _InputIterator __last, _Predicate __pred)
-    { return __last == _GLIBCXX_STD_A::find_if(__first, __last, __pred); }
+    {
+      return
+       __last == _GLIBCXX_STD_A::find_if(__first, __last, std::move(__pred));
+    }
 
   /**
    *  @brief  Checks that a predicate is true for at least one element
@@ -445,7 +448,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     _GLIBCXX20_CONSTEXPR
     inline bool
     any_of(_InputIterator __first, _InputIterator __last, _Predicate __pred)
-    { return !std::none_of(__first, __last, __pred); }
+    { return !std::none_of(__first, __last, std::move(__pred)); }
 
   /**
    *  @brief  Find the first element in a sequence for which a
@@ -468,8 +471,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
              typename iterator_traits<_InputIterator>::value_type>)
       __glibcxx_requires_valid_range(__first, __last);
-      return std::__find_if_not(__first, __last,
-                               __gnu_cxx::__ops::__pred_iter(__pred));
+      return std::__find_if_not(__first, __last, std::move(__pred));
     }
 
   /**
@@ -492,7 +494,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       if (__first == __last)
        return true;
       ++__first;
-      return std::none_of(__first, __last, __pred);
+      return std::none_of(__first, __last, std::move(__pred));
     }
 
   /**
@@ -539,7 +541,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        }
       return __first;
     }
-#endif
+#endif // C++11
 
   template<typename _InputIterator, typename _OutputIterator,
           typename _Predicate>
@@ -549,7 +551,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                     _OutputIterator __result, _Predicate __pred)
     {
       for (; __first != __last; ++__first)
-       if (!__pred(__first))
+       if (!__pred(*__first))
          {
            *__result = *__first;
            ++__result;
@@ -586,7 +588,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       __glibcxx_requires_valid_range(__first, __last);
 
       return std::__remove_copy_if(__first, __last, __result,
-       __gnu_cxx::__ops::__iter_equals_val(__value));
+                                  __gnu_cxx::__ops::__equal_to(__value));
     }
 
   /**
@@ -620,7 +622,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       __glibcxx_requires_valid_range(__first, __last);
 
       return std::__remove_copy_if(__first, __last, __result,
-                                  __gnu_cxx::__ops::__pred_iter(__pred));
+                                  _GLIBCXX_MOVE(__pred));
     }
 
 #if __cplusplus >= 201103L
@@ -796,7 +798,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       __glibcxx_requires_valid_range(__first, __last);
 
       return std::__remove_if(__first, __last,
-               __gnu_cxx::__ops::__iter_equals_val(__value));
+                             __gnu_cxx::__ops::__equal_to(__value));
     }
 
   /**
@@ -829,8 +831,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
            typename iterator_traits<_ForwardIterator>::value_type>)
       __glibcxx_requires_valid_range(__first, __last);
 
-      return std::__remove_if(__first, __last,
-                             __gnu_cxx::__ops::__pred_iter(__pred));
+      return std::__remove_if(__first, __last, _GLIBCXX_MOVE(__pred));
     }
 
   template<typename _ForwardIterator, typename _BinaryPredicate>
@@ -844,7 +845,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _ForwardIterator __next = __first;
       while (++__next != __last)
        {
-         if (__binary_pred(__first, __next))
+         if (__binary_pred(*__first, *__next))
            return __first;
          __first = __next;
        }
@@ -866,7 +867,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _ForwardIterator __dest = __first;
       ++__first;
       while (++__first != __last)
-       if (!__binary_pred(__dest, __first))
+       if (!__binary_pred(*__dest, *__first))
          *++__dest = _GLIBCXX_MOVE(*__first);
       return ++__dest;
     }
@@ -898,7 +899,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       __glibcxx_requires_valid_range(__first, __last);
 
       return std::__unique(__first, __last,
-                          __gnu_cxx::__ops::__iter_equal_to_iter());
+                          __gnu_cxx::__ops::__equal_to());
     }
 
   /**
@@ -930,8 +931,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                typename iterator_traits<_ForwardIterator>::value_type>)
       __glibcxx_requires_valid_range(__first, __last);
 
-      return std::__unique(__first, __last,
-                          __gnu_cxx::__ops::__iter_comp_iter(__binary_pred));
+      return std::__unique(__first, __last, _GLIBCXX_MOVE(__binary_pred));
     }
 
   /**
@@ -956,7 +956,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _ForwardIterator __next = __first;
       *__result = *__first;
       while (++__next != __last)
-       if (!__binary_pred(__first, __next))
+       if (!__binary_pred(*__first, *__next))
          {
            __first = __next;
            *++__result = *__first;
@@ -984,12 +984,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
          typename iterator_traits<_InputIterator>::value_type>)
 
       typename iterator_traits<_InputIterator>::value_type __value = *__first;
-      __decltype(__gnu_cxx::__ops::__iter_comp_val(__binary_pred))
-       __rebound_pred
-       = __gnu_cxx::__ops::__iter_comp_val(__binary_pred);
       *__result = __value;
       while (++__first != __last)
-       if (!__rebound_pred(__first, __value))
+       if (!__binary_pred(*__first, __value))
          {
            __value = *__first;
            *++__result = __value;
@@ -1017,7 +1014,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
          typename iterator_traits<_InputIterator>::value_type>)
       *__result = *__first;
       while (++__first != __last)
-       if (!__binary_pred(__result, __first))
+       if (!__binary_pred(*__result, *__first))
          *++__result = *__first;
       return ++__result;
     }
@@ -1479,7 +1476,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
          ++__result2;
          ++__first;
          for (; __first != __last; ++__first)
-           if (__pred(__first))
+           if (__pred(*__first))
              {
                *__result1 = _GLIBCXX_MOVE(*__first);
                ++__result1;
@@ -1534,7 +1531,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
       _Temporary_buffer<_ForwardIterator, _ValueType>
        __buf(__first, std::distance(__first, __last));
       return
-       std::__stable_partition_adaptive(__first, __last, __pred,
+       std::__stable_partition_adaptive(__first, __last, _GLIBCXX_MOVE(__pred),
                                         _DistanceType(__buf.requested_size()),
                                         __buf.begin(),
                                         _DistanceType(__buf.size()));
@@ -1569,8 +1566,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
            typename iterator_traits<_ForwardIterator>::value_type>)
       __glibcxx_requires_valid_range(__first, __last);
 
-      return std::__stable_partition(__first, __last,
-                                    __gnu_cxx::__ops::__pred_iter(__pred));
+      return std::__stable_partition(__first, __last, _GLIBCXX_MOVE(__pred));
     }
 #endif // HOSTED
 
@@ -1586,7 +1582,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
     {
       std::__make_heap(__first, __middle, __comp);
       for (_RandomAccessIterator __i = __middle; __i < __last; ++__i)
-       if (__comp(__i, __first))
+       if (__comp(*__i, *__first))
          std::__pop_heap(__first, __middle, __i, __comp);
     }
 
@@ -1619,14 +1615,15 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
       std::__make_heap(__result_first, __result_real_last, __comp);
       while (__first != __last)
        {
-         if (__comp(__first, __result_first))
+         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);
+      std::__sort_heap(__result_first, __result_real_last,
+                      _GLIBCXX_MOVE(__comp));
       return __result_real_last;
     }
 
@@ -1677,7 +1674,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
 
       return std::__partial_sort_copy(__first, __last,
                                      __result_first, __result_last,
-                                     __gnu_cxx::__ops::__iter_less_iter());
+                                     __gnu_cxx::__ops::__less());
     }
 
   /**
@@ -1732,7 +1729,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
 
       return std::__partial_sort_copy(__first, __last,
                                      __result_first, __result_last,
-                               __gnu_cxx::__ops::__iter_comp_iter(__comp));
+                                     _GLIBCXX_MOVE(__comp));
     }
 
   /// @cond undocumented
@@ -1748,7 +1745,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
        __val = _GLIBCXX_MOVE(*__last);
       _RandomAccessIterator __next = __last;
       --__next;
-      while (__comp(__val, __next))
+      while (__comp(__val, *__next))
        {
          *__last = _GLIBCXX_MOVE(*__next);
          __last = __next;
@@ -1764,11 +1761,12 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
     __insertion_sort(_RandomAccessIterator __first,
                     _RandomAccessIterator __last, _Compare __comp)
     {
-      if (__first == __last) return;
+      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);
@@ -1776,8 +1774,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
              *__first = _GLIBCXX_MOVE(__val);
            }
          else
-           std::__unguarded_linear_insert(__i,
-                               __gnu_cxx::__ops::__val_comp_iter(__comp));
+           std::__unguarded_linear_insert(__i, __comp);
        }
     }
 
@@ -1789,8 +1786,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
                               _RandomAccessIterator __last, _Compare __comp)
     {
       for (_RandomAccessIterator __i = __first; __i != __last; ++__i)
-       std::__unguarded_linear_insert(__i,
-                               __gnu_cxx::__ops::__val_comp_iter(__comp));
+       std::__unguarded_linear_insert(__i, __comp);
     }
 
   /**
@@ -1810,10 +1806,10 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
        {
          std::__insertion_sort(__first, __first + int(_S_threshold), __comp);
          std::__unguarded_insertion_sort(__first + int(_S_threshold), __last,
-                                         __comp);
+                                         _GLIBCXX_MOVE(__comp));
        }
       else
-       std::__insertion_sort(__first, __last, __comp);
+       std::__insertion_sort(__first, __last, _GLIBCXX_MOVE(__comp));
     }
 
   /// This is a helper function...
@@ -1826,10 +1822,10 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
     {
       while (true)
        {
-         while (__comp(__first, __pivot))
+         while (__comp(*__first, *__pivot))
            ++__first;
          --__last;
-         while (__comp(__pivot, __last))
+         while (__comp(*__pivot, *__last))
            --__last;
          if (!(__first < __last))
            return __first;
@@ -1848,7 +1844,8 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
       _RandomAccessIterator __mid = __first + (__last - __first) / 2;
       std::__move_median_to_first(__first, __first + 1, __mid, __last - 1,
                                  __comp);
-      return std::__unguarded_partition(__first + 1, __last, __first, __comp);
+      return std::__unguarded_partition(__first + 1, __last, __first,
+                                       _GLIBCXX_MOVE(__comp));
     }
 
   template<typename _RandomAccessIterator, typename _Compare>
@@ -1860,7 +1857,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
                   _Compare __comp)
     {
       std::__heap_select(__first, __middle, __last, __comp);
-      std::__sort_heap(__first, __middle, __comp);
+      std::__sort_heap(__first, __middle, _GLIBCXX_MOVE(__comp));
     }
 
   /// This is a helper function for the sort routine.
@@ -1899,7 +1896,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
          std::__introsort_loop(__first, __last,
                                std::__lg(__last - __first) * 2,
                                __comp);
-         std::__final_insertion_sort(__first, __last, __comp);
+         std::__final_insertion_sort(__first, __last, _GLIBCXX_MOVE(__comp));
        }
     }
 
@@ -1927,7 +1924,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
          else
            __last = __cut;
        }
-      std::__insertion_sort(__first, __last, __comp);
+      std::__insertion_sort(__first, __last, _GLIBCXX_MOVE(__comp));
     }
 
   /// @endcond
@@ -1964,8 +1961,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
       __glibcxx_requires_partitioned_lower_pred(__first, __last,
                                                __val, __comp);
 
-      return std::__lower_bound(__first, __last, __val,
-                               __gnu_cxx::__ops::__iter_comp_val(__comp));
+      return std::__lower_bound(__first, __last, __val, _GLIBCXX_MOVE(__comp));
     }
 
   template<typename _ForwardIterator, typename _Tp, typename _Compare>
@@ -1984,7 +1980,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
          _DistanceType __half = __len >> 1;
          _ForwardIterator __middle = __first;
          std::advance(__middle, __half);
-         if (__comp(__val, __middle))
+         if (__comp(__val, *__middle))
            __len = __half;
          else
            {
@@ -2020,7 +2016,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
       __glibcxx_requires_partitioned_upper(__first, __last, __val);
 
       return std::__upper_bound(__first, __last, __val,
-                               __gnu_cxx::__ops::__val_less_iter());
+                               __gnu_cxx::__ops::__less());
     }
 
   /**
@@ -2051,17 +2047,14 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
       __glibcxx_requires_partitioned_upper_pred(__first, __last,
                                                __val, __comp);
 
-      return std::__upper_bound(__first, __last, __val,
-                               __gnu_cxx::__ops::__val_comp_iter(__comp));
+      return std::__upper_bound(__first, __last, __val, _GLIBCXX_MOVE(__comp));
     }
 
-  template<typename _ForwardIterator, typename _Tp,
-          typename _CompareItTp, typename _CompareTpIt>
+  template<typename _ForwardIterator, typename _Tp, typename _Comp>
     _GLIBCXX20_CONSTEXPR
     pair<_ForwardIterator, _ForwardIterator>
     __equal_range(_ForwardIterator __first, _ForwardIterator __last,
-                 const _Tp& __val,
-                 _CompareItTp __comp_it_val, _CompareTpIt __comp_val_it)
+                 const _Tp& __val, _Comp __comp)
     {
       typedef typename iterator_traits<_ForwardIterator>::difference_type
        _DistanceType;
@@ -2073,21 +2066,22 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
          _DistanceType __half = __len >> 1;
          _ForwardIterator __middle = __first;
          std::advance(__middle, __half);
-         if (__comp_it_val(__middle, __val))
+         if (__comp(*__middle, __val))
            {
              __first = __middle;
              ++__first;
              __len = __len - __half - 1;
            }
-         else if (__comp_val_it(__val, __middle))
+         else if (__comp(__val, *__middle))
            __len = __half;
          else
            {
              _ForwardIterator __left
-               = std::__lower_bound(__first, __middle, __val, __comp_it_val);
+               = std::__lower_bound(__first, __middle, __val, __comp);
              std::advance(__first, __len);
              _ForwardIterator __right
-               = std::__upper_bound(++__middle, __first, __val, __comp_val_it);
+               = std::__upper_bound(++__middle, __first, __val,
+                                    _GLIBCXX_MOVE(__comp));
              return pair<_ForwardIterator, _ForwardIterator>(__left, __right);
            }
        }
@@ -2127,8 +2121,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
       __glibcxx_requires_partitioned_upper(__first, __last, __val);
 
       return std::__equal_range(__first, __last, __val,
-                               __gnu_cxx::__ops::__iter_less_val(),
-                               __gnu_cxx::__ops::__val_less_iter());
+                               __gnu_cxx::__ops::__less());
     }
 
   /**
@@ -2165,9 +2158,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
       __glibcxx_requires_partitioned_upper_pred(__first, __last,
                                                __val, __comp);
 
-      return std::__equal_range(__first, __last, __val,
-                               __gnu_cxx::__ops::__iter_comp_val(__comp),
-                               __gnu_cxx::__ops::__val_comp_iter(__comp));
+      return std::__equal_range(__first, __last, __val, _GLIBCXX_MOVE(__comp));
     }
 
   /**
@@ -2197,7 +2188,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
 
       _ForwardIterator __i
        = std::__lower_bound(__first, __last, __val,
-                            __gnu_cxx::__ops::__iter_less_val());
+                            __gnu_cxx::__ops::__less());
       return __i != __last && !(__val < *__i);
     }
 
@@ -2232,8 +2223,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
                                                __val, __comp);
 
       _ForwardIterator __i
-       = std::__lower_bound(__first, __last, __val,
-                            __gnu_cxx::__ops::__iter_comp_val(__comp));
+       = std::__lower_bound(__first, __last, __val, __comp);
       return __i != __last && !bool(__comp(__val, *__i));
     }
 
@@ -2249,7 +2239,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
     {
       while (__first1 != __last1 && __first2 != __last2)
        {
-         if (__comp(__first2, __first1))
+         if (__comp(*__first2, *__first1))
            {
              *__result = _GLIBCXX_MOVE(*__first2);
              ++__first2;
@@ -2288,7 +2278,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
       --__last2;
       while (true)
        {
-         if (__comp(__last2, __last1))
+         if (__comp(*__last2, *__last1))
            {
              *--__result = _GLIBCXX_MOVE(*__last1);
              if (__first1 == __last1)
@@ -2360,13 +2350,14 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
        {
          _Pointer __buffer_end = _GLIBCXX_MOVE3(__first, __middle, __buffer);
          std::__move_merge_adaptive(__buffer, __buffer_end, __middle, __last,
-                                    __first, __comp);
+                                    __first, _GLIBCXX_MOVE(__comp));
        }
       else
        {
          _Pointer __buffer_end = _GLIBCXX_MOVE3(__middle, __last, __buffer);
          std::__move_merge_adaptive_backward(__first, __middle, __buffer,
-                                             __buffer_end, __last, __comp);
+                                             __buffer_end, __last,
+                                             _GLIBCXX_MOVE(__comp));
        }
     }
 
@@ -2382,7 +2373,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
     {
       if (__len1 <= __buffer_size || __len2 <= __buffer_size)
        std::__merge_adaptive(__first, __middle, __last,
-                             __len1, __len2, __buffer, __comp);
+                             __len1, __len2, __buffer, _GLIBCXX_MOVE(__comp));
       else
        {
          _BidirectionalIterator __first_cut = __first;
@@ -2394,8 +2385,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
              __len11 = __len1 / 2;
              std::advance(__first_cut, __len11);
              __second_cut
-               = std::__lower_bound(__middle, __last, *__first_cut,
-                                    __gnu_cxx::__ops::__iter_comp_val(__comp));
+               = std::__lower_bound(__middle, __last, *__first_cut, __comp);
              __len22 = std::distance(__middle, __second_cut);
            }
          else
@@ -2403,8 +2393,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
              __len22 = __len2 / 2;
              std::advance(__second_cut, __len22);
              __first_cut
-               = std::__upper_bound(__first, __middle, *__second_cut,
-                                    __gnu_cxx::__ops::__val_comp_iter(__comp));
+               = std::__upper_bound(__first, __middle, *__second_cut, __comp);
              __len11 = std::distance(__first, __first_cut);
            }
 
@@ -2418,7 +2407,8 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
          std::__merge_adaptive_resize(__new_middle, __second_cut, __last,
                                       _Distance(__len1 - __len11),
                                       _Distance(__len2 - __len22),
-                                      __buffer, __buffer_size, __comp);
+                                      __buffer, __buffer_size,
+                                      _GLIBCXX_MOVE(__comp));
        }
     }
 
@@ -2437,7 +2427,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
 
       if (__len1 + __len2 == 2)
        {
-         if (__comp(__middle, __first))
+         if (__comp(*__middle, *__first))
            std::iter_swap(__first, __middle);
          return;
        }
@@ -2451,8 +2441,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
          __len11 = __len1 / 2;
          std::advance(__first_cut, __len11);
          __second_cut
-           = std::__lower_bound(__middle, __last, *__first_cut,
-                                __gnu_cxx::__ops::__iter_comp_val(__comp));
+           = std::__lower_bound(__middle, __last, *__first_cut, __comp);
          __len22 = std::distance(__middle, __second_cut);
        }
       else
@@ -2460,8 +2449,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
          __len22 = __len2 / 2;
          std::advance(__second_cut, __len22);
          __first_cut
-           = std::__upper_bound(__first, __middle, *__second_cut,
-                                __gnu_cxx::__ops::__val_comp_iter(__comp));
+           = std::__upper_bound(__first, __middle, *__second_cut, __comp);
          __len11 = std::distance(__first, __first_cut);
        }
 
@@ -2470,7 +2458,8 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
       std::__merge_without_buffer(__first, __first_cut, __new_middle,
                                  __len11, __len22, __comp);
       std::__merge_without_buffer(__new_middle, __second_cut, __last,
-                                 __len1 - __len11, __len2 - __len22, __comp);
+                                 __len1 - __len11, __len2 - __len22,
+                                 _GLIBCXX_MOVE(__comp));
     }
 
   template<typename _BidirectionalIterator, typename _Compare>
@@ -2498,18 +2487,18 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
       _TmpBuf __buf(__first, std::min(__len1, __len2));
 
       if (__builtin_expect(__buf.size() == __buf.requested_size(), true))
-       std::__merge_adaptive
-         (__first, __middle, __last, __len1, __len2, __buf.begin(), __comp);
+       std::__merge_adaptive(__first, __middle, __last, __len1, __len2,
+                             __buf.begin(), _GLIBCXX_MOVE(__comp));
       else if (__builtin_expect(__buf.begin() == 0, false))
-       std::__merge_without_buffer
-         (__first, __middle, __last, __len1, __len2, __comp);
+       std::__merge_without_buffer(__first, __middle, __last, __len1, __len2,
+                                   _GLIBCXX_MOVE(__comp));
       else
-       std::__merge_adaptive_resize
-         (__first, __middle, __last, __len1, __len2, __buf.begin(),
-          _DistanceType(__buf.size()), __comp);
+       std::__merge_adaptive_resize(__first, __middle, __last, __len1, __len2,
+                                    __buf.begin(), _DistanceType(__buf.size()),
+                                    _GLIBCXX_MOVE(__comp));
 #else
       std::__merge_without_buffer
-       (__first, __middle, __last, __len1, __len2, __comp);
+       (__first, __middle, __last, __len1, __len2, _GLIBCXX_MOVE(__comp));
 #endif
     }
 
@@ -2547,7 +2536,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
       __glibcxx_requires_irreflexive(__first, __last);
 
       std::__inplace_merge(__first, __middle, __last,
-                          __gnu_cxx::__ops::__iter_less_iter());
+                          __gnu_cxx::__ops::__less());
     }
 
   /**
@@ -2589,8 +2578,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
       __glibcxx_requires_sorted_pred(__middle, __last, __comp);
       __glibcxx_requires_irreflexive_pred(__first, __last, __comp);
 
-      std::__inplace_merge(__first, __middle, __last,
-                          __gnu_cxx::__ops::__iter_comp_iter(__comp));
+      std::__inplace_merge(__first, __middle, __last, _GLIBCXX_MOVE(__comp));
     }
 
 
@@ -2604,7 +2592,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
     {
       while (__first1 != __last1 && __first2 != __last2)
        {
-         if (__comp(__first2, __first1))
+         if (__comp(*__first2, *__first1))
            {
              *__result = _GLIBCXX_MOVE(*__first2);
              ++__first2;
@@ -2617,8 +2605,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
          ++__result;
        }
       return _GLIBCXX_MOVE3(__first2, __last2,
-                           _GLIBCXX_MOVE3(__first1, __last1,
-                                          __result));
+                           _GLIBCXX_MOVE3(__first1, __last1, __result));
     }
 
   template<typename _RandomAccessIterator1, typename _RandomAccessIterator2,
@@ -2642,7 +2629,8 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
       __step_size = std::min(_Distance(__last - __first), __step_size);
 
       std::__move_merge(__first, __first + __step_size,
-                       __first + __step_size, __last, __result, __comp);
+                       __first + __step_size, __last, __result,
+                       _GLIBCXX_MOVE(__comp));
     }
 
   template<typename _RandomAccessIterator, typename _Distance,
@@ -2658,7 +2646,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
          std::__insertion_sort(__first, __first + __chunk_size, __comp);
          __first += __chunk_size;
        }
-      std::__insertion_sort(__first, __last, __comp);
+      std::__insertion_sort(__first, __last, _GLIBCXX_MOVE(__comp));
     }
 
   enum { _S_chunk_size = 7 };
@@ -2724,11 +2712,11 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
                                       _Distance(__middle - __first),
                                       _Distance(__last - __middle),
                                       __buffer, __buffer_size,
-                                      __comp);
+                                      _GLIBCXX_MOVE(__comp));
        }
       else
        std::__stable_sort_adaptive(__first, __middle, __last,
-                                   __buffer, __comp);
+                                   __buffer, _GLIBCXX_MOVE(__comp));
     }
 
   /// This is a helper function for the stable sorting routines.
@@ -2748,7 +2736,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
       std::__merge_without_buffer(__first, __middle, __last,
                                  __middle - __first,
                                  __last - __middle,
-                                 __comp);
+                                 _GLIBCXX_MOVE(__comp));
     }
 
   // stable_sort
@@ -2768,9 +2756,9 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
     {
       while (__first1 != __last1 && __first2 != __last2)
        {
-         if (__comp(__first2, __first1))
+         if (__comp(*__first2, *__first1))
            return false;
-         if (!__comp(__first1, __first2))
+         if (!__comp(*__first1, *__first2))
            ++__first2;
          ++__first1;
        }
@@ -2817,7 +2805,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
       __glibcxx_requires_irreflexive2(__first2, __last2);
 
       return std::__includes(__first1, __last1, __first2, __last2,
-                            __gnu_cxx::__ops::__iter_less_iter());
+                            __gnu_cxx::__ops::__less());
     }
 
   /**
@@ -2864,7 +2852,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
       __glibcxx_requires_irreflexive_pred2(__first2, __last2, __comp);
 
       return std::__includes(__first1, __last1, __first2, __last2,
-                            __gnu_cxx::__ops::__iter_comp_iter(__comp));
+                            _GLIBCXX_MOVE(__comp));
     }
 
   // nth_element
@@ -2896,10 +2884,10 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
        {
          _BidirectionalIterator __ii = __i;
          --__i;
-         if (__comp(__i, __ii))
+         if (__comp(*__i, *__ii))
            {
              _BidirectionalIterator __j = __last;
-             while (!__comp(__i, --__j))
+             while (!__comp(*__i, *(--__j)))
                {}
              std::iter_swap(__i, __j);
              std::__reverse(__ii, __last,
@@ -2942,7 +2930,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
       __glibcxx_requires_irreflexive(__first, __last);
 
       return std::__next_permutation
-       (__first, __last, __gnu_cxx::__ops::__iter_less_iter());
+       (__first, __last, __gnu_cxx::__ops::__less());
     }
 
   /**
@@ -2975,8 +2963,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
       __glibcxx_requires_valid_range(__first, __last);
       __glibcxx_requires_irreflexive_pred(__first, __last, __comp);
 
-      return std::__next_permutation
-       (__first, __last, __gnu_cxx::__ops::__iter_comp_iter(__comp));
+      return std::__next_permutation(__first, __last, _GLIBCXX_MOVE(__comp));
     }
 
   template<typename _BidirectionalIterator, typename _Compare>
@@ -2998,10 +2985,10 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
        {
          _BidirectionalIterator __ii = __i;
          --__i;
-         if (__comp(__ii, __i))
+         if (__comp(*__ii, *__i))
            {
              _BidirectionalIterator __j = __last;
-             while (!__comp(--__j, __i))
+             while (!__comp(*(--__j), *__i))
                {}
              std::iter_swap(__i, __j);
              std::__reverse(__ii, __last,
@@ -3045,7 +3032,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
       __glibcxx_requires_irreflexive(__first, __last);
 
       return std::__prev_permutation(__first, __last,
-                                    __gnu_cxx::__ops::__iter_less_iter());
+                                    __gnu_cxx::__ops::__less());
     }
 
   /**
@@ -3078,8 +3065,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
       __glibcxx_requires_valid_range(__first, __last);
       __glibcxx_requires_irreflexive_pred(__first, __last, __comp);
 
-      return std::__prev_permutation(__first, __last,
-                               __gnu_cxx::__ops::__iter_comp_iter(__comp));
+      return std::__prev_permutation(__first, __last, _GLIBCXX_MOVE(__comp));
     }
 
   // replace
@@ -3094,7 +3080,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
                      _Predicate __pred, const _Tp& __new_value)
     {
       for (; __first != __last; ++__first, (void)++__result)
-       if (__pred(__first))
+       if (__pred(*__first))
          *__result = __new_value;
        else
          *__result = *__first;
@@ -3131,8 +3117,8 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
       __glibcxx_requires_valid_range(__first, __last);
 
       return std::__replace_copy_if(__first, __last, __result,
-                       __gnu_cxx::__ops::__iter_equals_val(__old_value),
-                                             __new_value);
+                                   __gnu_cxx::__ops::__equal_to(__old_value),
+                                   __new_value);
     }
 
   /**
@@ -3167,8 +3153,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
       __glibcxx_requires_valid_range(__first, __last);
 
       return std::__replace_copy_if(__first, __last, __result,
-                               __gnu_cxx::__ops::__pred_iter(__pred),
-                                             __new_value);
+                                   _GLIBCXX_MOVE(__pred), __new_value);
     }
 
 #if __cplusplus >= 201103L
@@ -3199,7 +3184,9 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
     inline bool
     is_sorted(_ForwardIterator __first, _ForwardIterator __last,
              _Compare __comp)
-    { return std::is_sorted_until(__first, __last, __comp) == __last; }
+    {
+      return std::is_sorted_until(__first, __last, std::move(__comp)) == 
__last;
+    }
 
   template<typename _ForwardIterator, typename _Compare>
     _GLIBCXX20_CONSTEXPR
@@ -3212,7 +3199,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
 
       _ForwardIterator __next = __first;
       for (++__next; __next != __last; __first = __next, (void)++__next)
-       if (__comp(__next, __first))
+       if (__comp(*__next, *__first))
          return __next;
       return __next;
     }
@@ -3238,7 +3225,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
       __glibcxx_requires_irreflexive(__first, __last);
 
       return std::__is_sorted_until(__first, __last,
-                                   __gnu_cxx::__ops::__iter_less_iter());
+                                   __gnu_cxx::__ops::__less());
     }
 
   /**
@@ -3264,8 +3251,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
       __glibcxx_requires_valid_range(__first, __last);
       __glibcxx_requires_irreflexive_pred(__first, __last, __comp);
 
-      return std::__is_sorted_until(__first, __last,
-                                   __gnu_cxx::__ops::__iter_comp_iter(__comp));
+      return std::__is_sorted_until(__first, __last, std::move(__comp));
     }
 
   /**
@@ -3318,7 +3304,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
        return std::make_pair(__first, __first);
 
       _ForwardIterator __min{}, __max{};
-      if (__comp(__next, __first))
+      if (__comp(*__next, *__first))
        {
          __min = __next;
          __max = __first;
@@ -3337,25 +3323,25 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
          __next = __first;
          if (++__next == __last)
            {
-             if (__comp(__first, __min))
+             if (__comp(*__first, *__min))
                __min = __first;
-             else if (!__comp(__first, __max))
+             else if (!__comp(*__first, *__max))
                __max = __first;
              break;
            }
 
-         if (__comp(__next, __first))
+         if (__comp(*__next, *__first))
            {
-             if (__comp(__next, __min))
+             if (__comp(*__next, *__min))
                __min = __next;
-             if (!__comp(__first, __max))
+             if (!__comp(*__first, *__max))
                __max = __first;
            }
          else
            {
-             if (__comp(__first, __min))
+             if (__comp(*__first, *__min))
                __min = __first;
-             if (!__comp(__next, __max))
+             if (!__comp(*__next, *__max))
                __max = __next;
            }
 
@@ -3389,8 +3375,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
       __glibcxx_requires_valid_range(__first, __last);
       __glibcxx_requires_irreflexive(__first, __last);
 
-      return std::__minmax_element(__first, __last,
-                                  __gnu_cxx::__ops::__iter_less_iter());
+      return std::__minmax_element(__first, __last, 
__gnu_cxx::__ops::__less());
     }
 
   /**
@@ -3419,8 +3404,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
       __glibcxx_requires_valid_range(__first, __last);
       __glibcxx_requires_irreflexive_pred(__first, __last, __comp);
 
-      return std::__minmax_element(__first, __last,
-                                  __gnu_cxx::__ops::__iter_comp_iter(__comp));
+      return std::__minmax_element(__first, __last, std::move(__comp));
     }
 
   template<typename _Tp>
@@ -3431,7 +3415,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
       __glibcxx_requires_irreflexive(__l.begin(), __l.end());
       pair<const _Tp*, const _Tp*> __p =
        std::__minmax_element(__l.begin(), __l.end(),
-                             __gnu_cxx::__ops::__iter_less_iter());
+                             __gnu_cxx::__ops::__less());
       return std::make_pair(*__p.first, *__p.second);
     }
 
@@ -3442,8 +3426,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
     {
       __glibcxx_requires_irreflexive_pred(__l.begin(), __l.end(), __comp);
       pair<const _Tp*, const _Tp*> __p =
-       std::__minmax_element(__l.begin(), __l.end(),
-                             __gnu_cxx::__ops::__iter_comp_iter(__comp));
+       std::__minmax_element(__l.begin(), __l.end(), std::move(__comp));
       return std::make_pair(*__p.first, *__p.second);
     }
 
@@ -3477,7 +3460,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
       __glibcxx_requires_valid_range(__first1, __last1);
 
       return std::__is_permutation(__first1, __last1, __first2,
-                                  __gnu_cxx::__ops::__iter_comp_iter(__pred));
+                                  std::move(__pred));
     }
 
 #if __cplusplus > 201103L
@@ -3508,7 +3491,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
       // have the same elements in the same order.
       for (; __first1 != __last1 && __first2 != __last2;
          ++__first1, (void)++__first2)
-       if (!__pred(__first1, __first2))
+       if (!__pred(*__first1, *__first2))
          break;
 
       if (__ra_iters)
@@ -3529,14 +3512,14 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
       for (_ForwardIterator1 __scan = __first1; __scan != __last1; ++__scan)
        {
          if (__scan != std::__find_if(__first1, __scan,
-                       __gnu_cxx::__ops::__iter_comp_iter(__pred, __scan)))
+                               __gnu_cxx::__ops::__comp_val(__pred, *__scan)))
            continue; // We've seen this one before.
 
          auto __matches = std::__count_if(__first2, __last2,
-               __gnu_cxx::__ops::__iter_comp_iter(__pred, __scan));
+               __gnu_cxx::__ops::__comp_val(__pred, *__scan));
          if (0 == __matches
              || std::__count_if(__scan, __last1,
-                       __gnu_cxx::__ops::__iter_comp_iter(__pred, __scan))
+                       __gnu_cxx::__ops::__comp_val(__pred, *__scan))
              != __matches)
            return false;
        }
@@ -3567,7 +3550,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
 
       return
        std::__is_permutation(__first1, __last1, __first2, __last2,
-                             __gnu_cxx::__ops::__iter_equal_to_iter());
+                             __gnu_cxx::__ops::__equal_to());
     }
 
   /**
@@ -3596,7 +3579,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
       __glibcxx_requires_valid_range(__first2, __last2);
 
       return std::__is_permutation(__first1, __last1, __first2, __last2,
-                                  __gnu_cxx::__ops::__iter_comp_iter(__pred));
+                                  std::move(__pred));
     }
 #endif // C++14
 
@@ -3841,7 +3824,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
                typename iterator_traits<_InputIterator>::value_type, _Tp>)
       __glibcxx_requires_valid_range(__first, __last);
       return std::__find_if(__first, __last,
-                           __gnu_cxx::__ops::__iter_equals_val(__val));
+                           __gnu_cxx::__ops::__equal_to(__val));
     }
 
   /**
@@ -3866,8 +3849,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
              typename iterator_traits<_InputIterator>::value_type>)
       __glibcxx_requires_valid_range(__first, __last);
 
-      return std::__find_if(__first, __last,
-                           __gnu_cxx::__ops::__pred_iter(__pred));
+      return std::__find_if(__first, __last, _GLIBCXX_MOVE(__pred));
     }
 
   /**
@@ -3972,7 +3954,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
       __glibcxx_requires_valid_range(__first, __last);
 
       return std::__adjacent_find(__first, __last,
-                                 __gnu_cxx::__ops::__iter_equal_to_iter());
+                                 __gnu_cxx::__ops::__equal_to());
     }
 
   /**
@@ -4000,7 +3982,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
       __glibcxx_requires_valid_range(__first, __last);
 
       return std::__adjacent_find(__first, __last,
-                       __gnu_cxx::__ops::__iter_comp_iter(__binary_pred));
+                                 _GLIBCXX_MOVE(__binary_pred));
     }
 
   /**
@@ -4024,7 +4006,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
       __glibcxx_requires_valid_range(__first, __last);
 
       return std::__count_if(__first, __last,
-                            __gnu_cxx::__ops::__iter_equals_val(__value));
+                            __gnu_cxx::__ops::__equal_to(__value));
     }
 
   /**
@@ -4047,8 +4029,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
            typename iterator_traits<_InputIterator>::value_type>)
       __glibcxx_requires_valid_range(__first, __last);
 
-      return std::__count_if(__first, __last,
-                            __gnu_cxx::__ops::__pred_iter(__pred));
+      return std::__count_if(__first, __last, _GLIBCXX_MOVE(__pred));
     }
 
   /**
@@ -4093,7 +4074,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
       __glibcxx_requires_valid_range(__first2, __last2);
 
       return std::__search(__first1, __last1, __first2, __last2,
-                          __gnu_cxx::__ops::__iter_equal_to_iter());
+                          __gnu_cxx::__ops::__equal_to());
     }
 
   /**
@@ -4124,7 +4105,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
       __glibcxx_requires_valid_range(__first, __last);
 
       return std::__search_n(__first, __last, __count,
-                            __gnu_cxx::__ops::__iter_equals_val(__val));
+                            __gnu_cxx::__ops::__equal_to(__val));
     }
 
 
@@ -4160,7 +4141,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
       __glibcxx_requires_valid_range(__first, __last);
 
       return std::__search_n(__first, __last, __count,
-               __gnu_cxx::__ops::__iter_comp_val(__binary_pred, __val));
+       __gnu_cxx::__ops::__comp_val(_GLIBCXX_MOVE(__binary_pred), __val));
     }
 
 #if __cplusplus >= 201703L
@@ -4417,7 +4398,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
       if (__first == __last)
        return __result;
       return std::__unique_copy(__first, __last, __result,
-                               __gnu_cxx::__ops::__iter_equal_to_iter(),
+                               __gnu_cxx::__ops::__equal_to(),
                                std::__iterator_category(__first),
                                std::__iterator_category(__result));
     }
@@ -4457,7 +4438,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
       if (__first == __last)
        return __result;
       return std::__unique_copy(__first, __last, __result,
-                       __gnu_cxx::__ops::__iter_comp_iter(__binary_pred),
+                               _GLIBCXX_MOVE(__binary_pred),
                                std::__iterator_category(__first),
                                std::__iterator_category(__result));
     }
@@ -4573,7 +4554,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
            typename iterator_traits<_ForwardIterator>::value_type>)
       __glibcxx_requires_valid_range(__first, __last);
 
-      return std::__partition(__first, __last, __pred,
+      return std::__partition(__first, __last, _GLIBCXX_MOVE(__pred),
                              std::__iterator_category(__first));
     }
 
@@ -4612,7 +4593,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
       __glibcxx_requires_irreflexive(__first, __last);
 
       std::__partial_sort(__first, __middle, __last,
-                         __gnu_cxx::__ops::__iter_less_iter());
+                         __gnu_cxx::__ops::__less());
     }
 
   /**
@@ -4652,8 +4633,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
       __glibcxx_requires_valid_range(__middle, __last);
       __glibcxx_requires_irreflexive_pred(__first, __last, __comp);
 
-      std::__partial_sort(__first, __middle, __last,
-                         __gnu_cxx::__ops::__iter_comp_iter(__comp));
+      std::__partial_sort(__first, __middle, __last, _GLIBCXX_MOVE(__comp));
     }
 
   /**
@@ -4691,7 +4671,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
 
       std::__introselect(__first, __nth, __last,
                         std::__lg(__last - __first) * 2,
-                        __gnu_cxx::__ops::__iter_less_iter());
+                        __gnu_cxx::__ops::__less());
     }
 
   /**
@@ -4732,7 +4712,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
 
       std::__introselect(__first, __nth, __last,
                         std::__lg(__last - __first) * 2,
-                        __gnu_cxx::__ops::__iter_comp_iter(__comp));
+                        _GLIBCXX_MOVE(__comp));
     }
 
   /**
@@ -4762,7 +4742,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
       __glibcxx_requires_valid_range(__first, __last);
       __glibcxx_requires_irreflexive(__first, __last);
 
-      std::__sort(__first, __last, __gnu_cxx::__ops::__iter_less_iter());
+      std::__sort(__first, __last, __gnu_cxx::__ops::__less());
     }
 
   /**
@@ -4795,7 +4775,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
       __glibcxx_requires_valid_range(__first, __last);
       __glibcxx_requires_irreflexive_pred(__first, __last, __comp);
 
-      std::__sort(__first, __last, __gnu_cxx::__ops::__iter_comp_iter(__comp));
+      std::__sort(__first, __last, _GLIBCXX_MOVE(__comp));
     }
 
   template<typename _InputIterator1, typename _InputIterator2,
@@ -4808,7 +4788,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
     {
       while (__first1 != __last1 && __first2 != __last2)
        {
-         if (__comp(__first2, __first1))
+         if (__comp(*__first2, *__first1))
            {
              *__result = *__first2;
              ++__first2;
@@ -4868,7 +4848,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
 
       return _GLIBCXX_STD_A::__merge(__first1, __last1,
                                     __first2, __last2, __result,
-                                    __gnu_cxx::__ops::__iter_less_iter());
+                                    __gnu_cxx::__ops::__less());
     }
 
   /**
@@ -4918,8 +4898,8 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
       __glibcxx_requires_irreflexive_pred2(__first2, __last2, __comp);
 
       return _GLIBCXX_STD_A::__merge(__first1, __last1,
-                               __first2, __last2, __result,
-                               __gnu_cxx::__ops::__iter_comp_iter(__comp));
+                                    __first2, __last2, __result,
+                                    _GLIBCXX_MOVE(__comp));
     }
 
   template<typename _RandomAccessIterator, typename _Compare>
@@ -4944,14 +4924,16 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
       if (__builtin_expect(__buf.requested_size() == __buf.size(), true))
        std::__stable_sort_adaptive(__first,
                                    __first + _DistanceType(__buf.size()),
-                                   __last, __buf.begin(), __comp);
+                                   __last, __buf.begin(),
+                                   _GLIBCXX_MOVE(__comp));
       else if (__builtin_expect(__buf.begin() == 0, false))
-       std::__inplace_stable_sort(__first, __last, __comp);
+       std::__inplace_stable_sort(__first, __last, _GLIBCXX_MOVE(__comp));
       else
        std::__stable_sort_adaptive_resize(__first, __last, __buf.begin(),
-                                          _DistanceType(__buf.size()), __comp);
+                                          _DistanceType(__buf.size()),
+                                          _GLIBCXX_MOVE(__comp));
 #else
-      std::__inplace_stable_sort(__first, __last, __comp);
+      std::__inplace_stable_sort(__first, __last, _GLIBCXX_MOVE(__comp));
 #endif
     }
 
@@ -4985,7 +4967,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
       __glibcxx_requires_irreflexive(__first, __last);
 
       _GLIBCXX_STD_A::__stable_sort(__first, __last,
-                                   __gnu_cxx::__ops::__iter_less_iter());
+                                   __gnu_cxx::__ops::__less());
     }
 
   /**
@@ -5021,7 +5003,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
       __glibcxx_requires_irreflexive_pred(__first, __last, __comp);
 
       _GLIBCXX_STD_A::__stable_sort(__first, __last,
-                                   __gnu_cxx::__ops::__iter_comp_iter(__comp));
+                                   _GLIBCXX_MOVE(__comp));
     }
 
   template<typename _InputIterator1, typename _InputIterator2,
@@ -5035,12 +5017,12 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
     {
       while (__first1 != __last1 && __first2 != __last2)
        {
-         if (__comp(__first1, __first2))
+         if (__comp(*__first1, *__first2))
            {
              *__result = *__first1;
              ++__first1;
            }
-         else if (__comp(__first2, __first1))
+         else if (__comp(*__first2, *__first1))
            {
              *__result = *__first2;
              ++__first2;
@@ -5103,8 +5085,8 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
       __glibcxx_requires_irreflexive2(__first2, __last2);
 
       return _GLIBCXX_STD_A::__set_union(__first1, __last1,
-                               __first2, __last2, __result,
-                               __gnu_cxx::__ops::__iter_less_iter());
+                                        __first2, __last2, __result,
+                                        __gnu_cxx::__ops::__less());
     }
 
   /**
@@ -5154,8 +5136,8 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
       __glibcxx_requires_irreflexive_pred2(__first2, __last2, __comp);
 
       return _GLIBCXX_STD_A::__set_union(__first1, __last1,
-                               __first2, __last2, __result,
-                               __gnu_cxx::__ops::__iter_comp_iter(__comp));
+                                        __first2, __last2, __result,
+                                        _GLIBCXX_MOVE(__comp));
     }
 
   template<typename _InputIterator1, typename _InputIterator2,
@@ -5168,9 +5150,9 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
                       _OutputIterator __result, _Compare __comp)
     {
       while (__first1 != __last1 && __first2 != __last2)
-       if (__comp(__first1, __first2))
+       if (__comp(*__first1, *__first2))
          ++__first1;
-       else if (__comp(__first2, __first1))
+       else if (__comp(*__first2, *__first1))
          ++__first2;
        else
          {
@@ -5225,8 +5207,8 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
       __glibcxx_requires_irreflexive2(__first2, __last2);
 
       return _GLIBCXX_STD_A::__set_intersection(__first1, __last1,
-                                    __first2, __last2, __result,
-                                    __gnu_cxx::__ops::__iter_less_iter());
+                                               __first2, __last2, __result,
+                                               __gnu_cxx::__ops::__less());
     }
 
   /**
@@ -5275,8 +5257,8 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
       __glibcxx_requires_irreflexive_pred2(__first2, __last2, __comp);
 
       return _GLIBCXX_STD_A::__set_intersection(__first1, __last1,
-                               __first2, __last2, __result,
-                               __gnu_cxx::__ops::__iter_comp_iter(__comp));
+                                               __first2, __last2, __result,
+                                               _GLIBCXX_MOVE(__comp));
     }
 
   template<typename _InputIterator1, typename _InputIterator2,
@@ -5289,13 +5271,13 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
                     _OutputIterator __result, _Compare __comp)
     {
       while (__first1 != __last1 && __first2 != __last2)
-       if (__comp(__first1, __first2))
+       if (__comp(*__first1, *__first2))
          {
            *__result = *__first1;
            ++__first1;
            ++__result;
          }
-       else if (__comp(__first2, __first1))
+       else if (__comp(*__first2, *__first1))
          ++__first2;
        else
          {
@@ -5350,8 +5332,8 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
       __glibcxx_requires_irreflexive2(__first2, __last2);
 
       return _GLIBCXX_STD_A::__set_difference(__first1, __last1,
-                                  __first2, __last2, __result,
-                                  __gnu_cxx::__ops::__iter_less_iter());
+                                             __first2, __last2, __result,
+                                             __gnu_cxx::__ops::__less());
     }
 
   /**
@@ -5402,8 +5384,8 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
       __glibcxx_requires_irreflexive_pred2(__first2, __last2, __comp);
 
       return _GLIBCXX_STD_A::__set_difference(__first1, __last1,
-                                  __first2, __last2, __result,
-                                  __gnu_cxx::__ops::__iter_comp_iter(__comp));
+                                             __first2, __last2, __result,
+                                             _GLIBCXX_MOVE(__comp));
     }
 
   template<typename _InputIterator1, typename _InputIterator2,
@@ -5419,13 +5401,13 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
                               _Compare __comp)
     {
       while (__first1 != __last1 && __first2 != __last2)
-       if (__comp(__first1, __first2))
+       if (__comp(*__first1, *__first2))
          {
            *__result = *__first1;
            ++__first1;
            ++__result;
          }
-       else if (__comp(__first2, __first1))
+       else if (__comp(*__first2, *__first1))
          {
            *__result = *__first2;
            ++__first2;
@@ -5486,7 +5468,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
 
       return _GLIBCXX_STD_A::__set_symmetric_difference(__first1, __last1,
                                        __first2, __last2, __result,
-                                       __gnu_cxx::__ops::__iter_less_iter());
+                                       __gnu_cxx::__ops::__less());
     }
 
   /**
@@ -5539,7 +5521,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
 
       return _GLIBCXX_STD_A::__set_symmetric_difference(__first1, __last1,
                                __first2, __last2, __result,
-                               __gnu_cxx::__ops::__iter_comp_iter(__comp));
+                               _GLIBCXX_MOVE(__comp));
     }
 
   template<typename _ForwardIterator, typename _Compare>
@@ -5552,7 +5534,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
        return __first;
       _ForwardIterator __result = __first;
       while (++__first != __last)
-       if (__comp(__first, __result))
+       if (__comp(*__first, *__result))
          __result = __first;
       return __result;
     }
@@ -5577,7 +5559,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
       __glibcxx_requires_irreflexive(__first, __last);
 
       return _GLIBCXX_STD_A::__min_element(__first, __last,
-                               __gnu_cxx::__ops::__iter_less_iter());
+                                          __gnu_cxx::__ops::__less());
     }
 
   /**
@@ -5604,7 +5586,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
       __glibcxx_requires_irreflexive_pred(__first, __last, __comp);
 
       return _GLIBCXX_STD_A::__min_element(__first, __last,
-                               __gnu_cxx::__ops::__iter_comp_iter(__comp));
+                                          _GLIBCXX_MOVE(__comp));
     }
 
   template<typename _ForwardIterator, typename _Compare>
@@ -5616,7 +5598,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
       if (__first == __last) return __first;
       _ForwardIterator __result = __first;
       while (++__first != __last)
-       if (__comp(__result, __first))
+       if (__comp(*__result, *__first))
          __result = __first;
       return __result;
     }
@@ -5641,7 +5623,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
       __glibcxx_requires_irreflexive(__first, __last);
 
       return _GLIBCXX_STD_A::__max_element(__first, __last,
-                               __gnu_cxx::__ops::__iter_less_iter());
+                                          __gnu_cxx::__ops::__less());
     }
 
   /**
@@ -5668,7 +5650,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
       __glibcxx_requires_irreflexive_pred(__first, __last, __comp);
 
       return _GLIBCXX_STD_A::__max_element(__first, __last,
-                               __gnu_cxx::__ops::__iter_comp_iter(__comp));
+                                          _GLIBCXX_MOVE(__comp));
     }
 
 #if __cplusplus >= 201103L
@@ -5680,7 +5662,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
     {
       __glibcxx_requires_irreflexive(__l.begin(), __l.end());
       return *_GLIBCXX_STD_A::__min_element(__l.begin(), __l.end(),
-         __gnu_cxx::__ops::__iter_less_iter());
+                                           __gnu_cxx::__ops::__less());
     }
 
   template<typename _Tp, typename _Compare>
@@ -5690,7 +5672,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
     {
       __glibcxx_requires_irreflexive_pred(__l.begin(), __l.end(), __comp);
       return *_GLIBCXX_STD_A::__min_element(__l.begin(), __l.end(),
-         __gnu_cxx::__ops::__iter_comp_iter(__comp));
+                                           std::move(__comp));
     }
 
   template<typename _Tp>
@@ -5700,7 +5682,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
     {
       __glibcxx_requires_irreflexive(__l.begin(), __l.end());
       return *_GLIBCXX_STD_A::__max_element(__l.begin(), __l.end(),
-         __gnu_cxx::__ops::__iter_less_iter());
+                                           __gnu_cxx::__ops::__less());
     }
 
   template<typename _Tp, typename _Compare>
@@ -5710,7 +5692,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
     {
       __glibcxx_requires_irreflexive_pred(__l.begin(), __l.end(), __comp);
       return *_GLIBCXX_STD_A::__max_element(__l.begin(), __l.end(),
-         __gnu_cxx::__ops::__iter_comp_iter(__comp));
+                                           std::move(__comp));
     }
 #endif // C++11
 
diff --git a/libstdc++-v3/include/bits/stl_algobase.h 
b/libstdc++-v3/include/bits/stl_algobase.h
index 6276d85b86f..bf404bf849b 100644
--- a/libstdc++-v3/include/bits/stl_algobase.h
+++ b/libstdc++-v3/include/bits/stl_algobase.h
@@ -1300,9 +1300,9 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
       for (; __first1 != __last1 && __rai_type::__cnd2(__first2, __last2);
           ++__first1, (void)++__first2)
        {
-         if (__comp(__first1, __first2))
+         if (__comp(*__first1, *__first2))
            return true;
-         if (__comp(__first2, __first1))
+         if (__comp(*__first2, *__first1))
            return false;
        }
       return __first1 == __last1 && __first2 != __last2;
@@ -1316,10 +1316,9 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
        static bool
        __lc(_II1 __first1, _II1 __last1, _II2 __first2, _II2 __last2)
        {
-         using __gnu_cxx::__ops::__iter_less_iter;
          return std::__lexicographical_compare_impl(__first1, __last1,
                                                     __first2, __last2,
-                                                    __iter_less_iter());
+                                               __gnu_cxx::__ops::__less());
        }
 
       template<typename _II1, typename _II2>
@@ -1469,7 +1468,7 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
          _DistanceType __half = __len >> 1;
          _ForwardIterator __middle = __first;
          std::advance(__middle, __half);
-         if (__comp(__middle, __val))
+         if (__comp(*__middle, __val))
            {
              __first = __middle;
              ++__first;
@@ -1505,7 +1504,7 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
       __glibcxx_requires_partitioned_lower(__first, __last, __val);
 
       return std::__lower_bound(__first, __last, __val,
-                               __gnu_cxx::__ops::__iter_less_val());
+                               __gnu_cxx::__ops::__less());
     }
 
   /// This is a helper function for the sort routines and for random.tcc.
@@ -1634,7 +1633,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
          if (__d1 != __d2)
            return false;
          return _GLIBCXX_STD_A::equal(__first1, __last1, __first2,
-                                      __binary_pred);
+                                      std::move(__binary_pred));
        }
 
       for (; __first1 != __last1 && __first2 != __last2;
@@ -1772,8 +1771,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
       __glibcxx_requires_valid_range(__first2, __last2);
 
       return std::__lexicographical_compare_impl
-       (__first1, __last1, __first2, __last2,
-        __gnu_cxx::__ops::__iter_comp_iter(__comp));
+       (__first1, __last1, __first2, __last2, _GLIBCXX_MOVE(__comp));
     }
 
 #if __cpp_lib_three_way_comparison
@@ -1878,7 +1876,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
     __mismatch(_InputIterator1 __first1, _InputIterator1 __last1,
               _InputIterator2 __first2, _BinaryPredicate __binary_pred)
     {
-      while (__first1 != __last1 && __binary_pred(__first1, __first2))
+      while (__first1 != __last1 && __binary_pred(*__first1, *__first2))
        {
          ++__first1;
          ++__first2;
@@ -1914,7 +1912,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
       __glibcxx_requires_valid_range(__first1, __last1);
 
       return _GLIBCXX_STD_A::__mismatch(__first1, __last1, __first2,
-                            __gnu_cxx::__ops::__iter_equal_to_iter());
+                                       __gnu_cxx::__ops::__equal_to());
     }
 
   /**
@@ -1946,7 +1944,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
       __glibcxx_requires_valid_range(__first1, __last1);
 
       return _GLIBCXX_STD_A::__mismatch(__first1, __last1, __first2,
-       __gnu_cxx::__ops::__iter_comp_iter(__binary_pred));
+                                       _GLIBCXX_MOVE(__binary_pred));
     }
 
 #if __glibcxx_robust_nonmodifying_seq_ops // C++ >= 14
@@ -1959,7 +1957,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
               _BinaryPredicate __binary_pred)
     {
       while (__first1 != __last1 && __first2 != __last2
-            && __binary_pred(__first1, __first2))
+            && __binary_pred(*__first1, *__first2))
        {
          ++__first1;
          ++__first2;
@@ -1997,7 +1995,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
       __glibcxx_requires_valid_range(__first2, __last2);
 
       return _GLIBCXX_STD_A::__mismatch(__first1, __last1, __first2, __last2,
-                            __gnu_cxx::__ops::__iter_equal_to_iter());
+                                       __gnu_cxx::__ops::__equal_to());
     }
 
   /**
@@ -2032,7 +2030,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
       __glibcxx_requires_valid_range(__first2, __last2);
 
       return _GLIBCXX_STD_A::__mismatch(__first1, __last1, __first2, __last2,
-                            __gnu_cxx::__ops::__iter_comp_iter(__binary_pred));
+                                       _GLIBCXX_MOVE(__binary_pred));
     }
 #endif
 
@@ -2045,7 +2043,7 @@ _GLIBCXX_END_NAMESPACE_ALGO
     __find_if(_InputIterator __first, _InputIterator __last,
              _Predicate __pred, input_iterator_tag)
     {
-      while (__first != __last && !__pred(__first))
+      while (__first != __last && !__pred(*__first))
        ++__first;
       return __first;
     }
@@ -2062,19 +2060,19 @@ _GLIBCXX_END_NAMESPACE_ALGO
 
       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;
        }
@@ -2082,17 +2080,17 @@ _GLIBCXX_END_NAMESPACE_ALGO
       switch (__last - __first)
        {
        case 3:
-         if (__pred(__first))
+         if (__pred(*__first))
            return __first;
          ++__first;
          // FALLTHRU
        case 2:
-         if (__pred(__first))
+         if (__pred(*__first))
            return __first;
          ++__first;
          // FALLTHRU
        case 1:
-         if (__pred(__first))
+         if (__pred(*__first))
            return __first;
          ++__first;
          // FALLTHRU
@@ -2118,7 +2116,7 @@ _GLIBCXX_END_NAMESPACE_ALGO
     {
       typename iterator_traits<_InputIterator>::difference_type __n = 0;
       for (; __first != __last; ++__first)
-       if (__pred(__first))
+       if (__pred(*__first))
          ++__n;
       return __n;
     }
@@ -2135,7 +2133,7 @@ _GLIBCXX_END_NAMESPACE_ALGO
       _ForwardIterator __result = __first;
       ++__first;
       for (; __first != __last; ++__first)
-       if (!__pred(__first))
+       if (!__pred(*__first))
          {
            *__result = _GLIBCXX_MOVE(*__first);
            ++__result;
@@ -2149,7 +2147,7 @@ _GLIBCXX_END_NAMESPACE_ALGO
     _ForwardIterator1
     __search(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
             _ForwardIterator2 __first2, _ForwardIterator2 __last2,
-            _BinaryPredicate  __predicate)
+            _BinaryPredicate  __pred)
     {
       // Test for empty ranges
       if (__first1 == __last1 || __first2 == __last2)
@@ -2159,7 +2157,7 @@ _GLIBCXX_END_NAMESPACE_ALGO
       _ForwardIterator2 __p1(__first2);
       if (++__p1 == __last2)
        return std::__find_if(__first1, __last1,
-               __gnu_cxx::__ops::__iter_comp_iter(__predicate, __first2));
+         __gnu_cxx::__ops::__comp_val(_GLIBCXX_MOVE(__pred), *__first2));
 
       // General case.
       _ForwardIterator1 __current = __first1;
@@ -2168,7 +2166,7 @@ _GLIBCXX_END_NAMESPACE_ALGO
        {
          __first1 =
            std::__find_if(__first1, __last1,
-               __gnu_cxx::__ops::__iter_comp_iter(__predicate, __first2));
+                          __gnu_cxx::__ops::__comp_val(__pred, *__first2));
 
          if (__first1 == __last1)
            return __last1;
@@ -2178,7 +2176,7 @@ _GLIBCXX_END_NAMESPACE_ALGO
          if (++__current == __last1)
            return __last1;
 
-         while (__predicate(__current, __p))
+         while (__pred(*__current, *__p))
            {
              if (++__p == __last2)
                return __first1;
@@ -2201,7 +2199,7 @@ _GLIBCXX_END_NAMESPACE_ALGO
       // Efficiently compare identical prefixes:  O(N) if sequences
       // have the same elements in the same order.
       for (; __first1 != __last1; ++__first1, (void)++__first2)
-       if (!__pred(__first1, __first2))
+       if (!__pred(*__first1, *__first2))
          break;
 
       if (__first1 == __last1)
@@ -2214,15 +2212,15 @@ _GLIBCXX_END_NAMESPACE_ALGO
       for (_ForwardIterator1 __scan = __first1; __scan != __last1; ++__scan)
        {
          if (__scan != std::__find_if(__first1, __scan,
-                         __gnu_cxx::__ops::__iter_comp_iter(__pred, __scan)))
+                         __gnu_cxx::__ops::__comp_val(__pred, *__scan)))
            continue; // We've seen this one before.
 
          auto __matches
            = std::__count_if(__first2, __last2,
-                       __gnu_cxx::__ops::__iter_comp_iter(__pred, __scan));
+                             __gnu_cxx::__ops::__comp_val(__pred, *__scan));
          if (0 == __matches ||
              std::__count_if(__scan, __last1,
-                       __gnu_cxx::__ops::__iter_comp_iter(__pred, __scan))
+                             __gnu_cxx::__ops::__comp_val(__pred, *__scan))
              != __matches)
            return false;
        }
@@ -2256,7 +2254,7 @@ _GLIBCXX_END_NAMESPACE_ALGO
       __glibcxx_requires_valid_range(__first1, __last1);
 
       return std::__is_permutation(__first1, __last1, __first2,
-                                  __gnu_cxx::__ops::__iter_equal_to_iter());
+                                  __gnu_cxx::__ops::__equal_to());
     }
 #endif // C++11
 
@@ -2301,7 +2299,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
       __glibcxx_requires_valid_range(__first2, __last2);
 
       return std::__search(__first1, __last1, __first2, __last2,
-                          __gnu_cxx::__ops::__iter_comp_iter(__predicate));
+                          _GLIBCXX_MOVE(__predicate));
     }
 
 _GLIBCXX_END_NAMESPACE_ALGO
diff --git a/libstdc++-v3/include/bits/stl_heap.h 
b/libstdc++-v3/include/bits/stl_heap.h
index 551c3687624..854d1cffd67 100644
--- a/libstdc++-v3/include/bits/stl_heap.h
+++ b/libstdc++-v3/include/bits/stl_heap.h
@@ -74,12 +74,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     _GLIBCXX20_CONSTEXPR
     _Distance
     __is_heap_until(_RandomAccessIterator __first, _Distance __n,
-                   _Compare& __comp)
+                   _Compare __comp)
     {
       _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;
@@ -94,8 +94,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     inline bool
     __is_heap(_RandomAccessIterator __first, _Distance __n)
     {
-      __gnu_cxx::__ops::_Iter_less_iter __comp;
-      return std::__is_heap_until(__first, __n, __comp) == __n;
+      return std::__is_heap_until(__first, __n,
+                                 __gnu_cxx::__ops::__less()) == __n;
     }
 
   template<typename _RandomAccessIterator, typename _Compare,
@@ -104,9 +104,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     inline bool
     __is_heap(_RandomAccessIterator __first, _Compare __comp, _Distance __n)
     {
-      typedef __decltype(__comp) _Cmp;
-      __gnu_cxx::__ops::_Iter_comp_iter<_Cmp> __cmp(_GLIBCXX_MOVE(__comp));
-      return std::__is_heap_until(__first, __n, __cmp) == __n;
+      return std::__is_heap_until(__first, __n,
+                                 _GLIBCXX_MOVE(__comp)) == __n;
     }
 
   template<typename _RandomAccessIterator>
@@ -134,10 +133,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     void
     __push_heap(_RandomAccessIterator __first,
                _Distance __holeIndex, _Distance __topIndex, _Tp __value,
-               _Compare& __comp)
+               _Compare __comp)
     {
       _Distance __parent = (__holeIndex - 1) / 2;
-      while (__holeIndex > __topIndex && __comp(__first + __parent, __value))
+      while (__holeIndex > __topIndex && __comp(__first[__parent], __value))
        {
          *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __parent));
          __holeIndex = __parent;
@@ -174,10 +173,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       __glibcxx_requires_irreflexive(__first, __last);
       __glibcxx_requires_heap(__first, __last - 1);
 
-      __gnu_cxx::__ops::_Iter_less_val __comp;
       _ValueType __value = _GLIBCXX_MOVE(*(__last - 1));
       std::__push_heap(__first, _DistanceType((__last - __first) - 1),
-                      _DistanceType(0), _GLIBCXX_MOVE(__value), __comp);
+                      _DistanceType(0), _GLIBCXX_MOVE(__value),
+                      __gnu_cxx::__ops::__less());
     }
 
   /**
@@ -210,11 +209,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       __glibcxx_requires_irreflexive_pred(__first, __last, __comp);
       __glibcxx_requires_heap_pred(__first, __last - 1, __comp);
 
-      __decltype(__gnu_cxx::__ops::__iter_comp_val(_GLIBCXX_MOVE(__comp)))
-       __cmp(_GLIBCXX_MOVE(__comp));
       _ValueType __value = _GLIBCXX_MOVE(*(__last - 1));
       std::__push_heap(__first, _DistanceType((__last - __first) - 1),
-                      _DistanceType(0), _GLIBCXX_MOVE(__value), __cmp);
+                      _DistanceType(0), _GLIBCXX_MOVE(__value),
+                      _GLIBCXX_MOVE(__comp));
     }
 
   template<typename _RandomAccessIterator, typename _Distance,
@@ -229,8 +227,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       while (__secondChild < (__len - 1) / 2)
        {
          __secondChild = 2 * (__secondChild + 1);
-         if (__comp(__first + __secondChild,
-                    __first + (__secondChild - 1)))
+         if (__comp(__first[__secondChild],
+                    __first[__secondChild - 1]))
            __secondChild--;
          *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __secondChild));
          __holeIndex = __secondChild;
@@ -242,17 +240,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                                                     + (__secondChild - 1)));
          __holeIndex = __secondChild - 1;
        }
-      __decltype(__gnu_cxx::__ops::__iter_comp_val(_GLIBCXX_MOVE(__comp)))
-       __cmp(_GLIBCXX_MOVE(__comp));
       std::__push_heap(__first, __holeIndex, __topIndex,
-                      _GLIBCXX_MOVE(__value), __cmp);
+                      _GLIBCXX_MOVE(__value), _GLIBCXX_MOVE(__comp));
     }
 
   template<typename _RandomAccessIterator, typename _Compare>
     _GLIBCXX20_CONSTEXPR
     inline void
     __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
-              _RandomAccessIterator __result, _Compare& __comp)
+              _RandomAccessIterator __result, _Compare __comp)
     {
       typedef typename iterator_traits<_RandomAccessIterator>::value_type
        _ValueType;
@@ -263,7 +259,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       *__result = _GLIBCXX_MOVE(*__first);
       std::__adjust_heap(__first, _DistanceType(0),
                         _DistanceType(__last - __first),
-                        _GLIBCXX_MOVE(__value), __comp);
+                        _GLIBCXX_MOVE(__value), _GLIBCXX_MOVE(__comp));
     }
 
   /**
@@ -295,8 +291,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       if (__last - __first > 1)
        {
          --__last;
-         __gnu_cxx::__ops::_Iter_less_iter __comp;
-         std::__pop_heap(__first, __last, __last, __comp);
+         std::__pop_heap(__first, __last, __last,
+                         __gnu_cxx::__ops::__less());
        }
     }
 
@@ -327,10 +323,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       if (__last - __first > 1)
        {
-         typedef __decltype(__comp) _Cmp;
-         __gnu_cxx::__ops::_Iter_comp_iter<_Cmp> __cmp(_GLIBCXX_MOVE(__comp));
          --__last;
-         std::__pop_heap(__first, __last, __last, __cmp);
+         std::__pop_heap(__first, __last, __last, _GLIBCXX_MOVE(__comp));
        }
     }
 
@@ -338,7 +332,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     _GLIBCXX20_CONSTEXPR
     void
     __make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
-               _Compare& __comp)
+               _Compare __comp)
     {
       typedef typename iterator_traits<_RandomAccessIterator>::value_type
          _ValueType;
@@ -382,8 +376,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       __glibcxx_requires_valid_range(__first, __last);
       __glibcxx_requires_irreflexive(__first, __last);
 
-      __gnu_cxx::__ops::_Iter_less_iter __comp;
-      std::__make_heap(__first, __last, __comp);
+      std::__make_heap(__first, __last, __gnu_cxx::__ops::__less());
     }
 
   /**
@@ -408,16 +401,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       __glibcxx_requires_valid_range(__first, __last);
       __glibcxx_requires_irreflexive_pred(__first, __last, __comp);
 
-      typedef __decltype(__comp) _Cmp;
-      __gnu_cxx::__ops::_Iter_comp_iter<_Cmp> __cmp(_GLIBCXX_MOVE(__comp));
-      std::__make_heap(__first, __last, __cmp);
+      std::__make_heap(__first, __last, _GLIBCXX_MOVE(__comp));
     }
 
   template<typename _RandomAccessIterator, typename _Compare>
     _GLIBCXX20_CONSTEXPR
     void
     __sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
-               _Compare& __comp)
+               _Compare __comp)
     {
       while (__last - __first > 1)
        {
@@ -448,8 +439,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       __glibcxx_requires_irreflexive(__first, __last);
       __glibcxx_requires_heap(__first, __last);
 
-      __gnu_cxx::__ops::_Iter_less_iter __comp;
-      std::__sort_heap(__first, __last, __comp);
+      std::__sort_heap(__first, __last, __gnu_cxx::__ops::__less());
     }
 
   /**
@@ -475,9 +465,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       __glibcxx_requires_irreflexive_pred(__first, __last, __comp);
       __glibcxx_requires_heap_pred(__first, __last, __comp);
 
-      typedef __decltype(__comp) _Cmp;
-      __gnu_cxx::__ops::_Iter_comp_iter<_Cmp> __cmp(_GLIBCXX_MOVE(__comp));
-      std::__sort_heap(__first, __last, __cmp);
+      std::__sort_heap(__first, __last, _GLIBCXX_MOVE(__comp));
     }
 
 #if __cplusplus >= 201103L
@@ -504,9 +492,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       __glibcxx_requires_valid_range(__first, __last);
       __glibcxx_requires_irreflexive(__first, __last);
 
-      __gnu_cxx::__ops::_Iter_less_iter __comp;
       return __first + 
-       std::__is_heap_until(__first, std::distance(__first, __last), __comp);
+       std::__is_heap_until(__first, std::distance(__first, __last),
+                            __gnu_cxx::__ops::__less());
     }
 
   /**
@@ -532,10 +520,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       __glibcxx_requires_valid_range(__first, __last);
       __glibcxx_requires_irreflexive_pred(__first, __last, __comp);
 
-      typedef __decltype(__comp) _Cmp;
-      __gnu_cxx::__ops::_Iter_comp_iter<_Cmp> __cmp(_GLIBCXX_MOVE(__comp));
       return __first
-       + std::__is_heap_until(__first, std::distance(__first, __last), __cmp);
+       + std::__is_heap_until(__first, std::distance(__first, __last),
+                              _GLIBCXX_MOVE(__comp));
     }
 
   /**
@@ -572,9 +559,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       __glibcxx_requires_irreflexive_pred(__first, __last, __comp);
 
       const auto __dist = std::distance(__first, __last);
-      typedef __decltype(__comp) _Cmp;
-      __gnu_cxx::__ops::_Iter_comp_iter<_Cmp> __cmp(_GLIBCXX_MOVE(__comp));
-      return std::__is_heap_until(__first, __dist, __cmp) == __dist;
+      return std::__is_heap_until(__first, __dist,
+                                 _GLIBCXX_MOVE(__comp)) == __dist;
     }
 #endif
 
diff --git a/libstdc++-v3/include/std/deque b/libstdc++-v3/include/std/deque
index e48dc9968e8..ebca63dc1da 100644
--- a/libstdc++-v3/include/std/deque
+++ b/libstdc++-v3/include/std/deque
@@ -64,7 +64,7 @@
 #include <bits/stl_construct.h>
 #include <bits/stl_uninitialized.h>
 #include <bits/stl_deque.h>
-#include <bits/refwrap.h>
+#include <bits/move.h>
 #include <bits/range_access.h>
 #include <bits/deque.tcc>
 
@@ -99,12 +99,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     inline typename deque<_Tp, _Alloc>::size_type
     erase_if(deque<_Tp, _Alloc>& __cont, _Predicate __pred)
     {
-      using namespace __gnu_cxx;
       _GLIBCXX_STD_C::deque<_Tp, _Alloc>& __ucont = __cont;
       const auto __osz = __cont.size();
       const auto __end = __ucont.end();
       auto __removed = std::__remove_if(__ucont.begin(), __end,
-                                       __ops::__pred_iter(std::ref(__pred)));
+                                       std::move(__pred));
       if (__removed != __end)
        {
          __cont.erase(__niter_wrap(__cont.begin(), __removed),
@@ -124,7 +123,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       const auto __osz = __cont.size();
       const auto __end = __ucont.end();
       auto __removed = std::__remove_if(__ucont.begin(), __end,
-                                       __ops::__iter_equals_val(__value));
+                                       __ops::__equal_to(__value));
       if (__removed != __end)
        {
          __cont.erase(__niter_wrap(__cont.begin(), __removed),
diff --git a/libstdc++-v3/include/std/functional 
b/libstdc++-v3/include/std/functional
index 729d11c9804..2d8b806fa0d 100644
--- a/libstdc++-v3/include/std/functional
+++ b/libstdc++-v3/include/std/functional
@@ -58,6 +58,9 @@
 #if _GLIBCXX_HOSTED
 # include <bits/std_function.h>        // std::function
 #endif
+#if __cplusplus >= 201402L
+# include <bits/predefined_ops.h> // std::_Not_fn
+#endif
 #if __cplusplus >= 201703L
 # if _GLIBCXX_HOSTED
 #  include <unordered_map>
@@ -1039,57 +1042,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif // __cpp_lib_bind_front
 
 #if __cplusplus >= 201402L
-  /// Generalized negator.
-  template<typename _Fn>
-    class _Not_fn
-    {
-      template<typename _Fn2, typename... _Args>
-       using __inv_res_t = typename __invoke_result<_Fn2, _Args...>::type;
-
-      template<typename _Tp>
-       static decltype(!std::declval<_Tp>())
-       _S_not() noexcept(noexcept(!std::declval<_Tp>()));
-
-    public:
-      template<typename _Fn2>
-       constexpr
-       _Not_fn(_Fn2&& __fn, int)
-       : _M_fn(std::forward<_Fn2>(__fn)) { }
-
-      _Not_fn(const _Not_fn& __fn) = default;
-      _Not_fn(_Not_fn&& __fn) = default;
-      ~_Not_fn() = default;
-
-      // Macro to define operator() with given cv-qualifiers ref-qualifiers,
-      // forwarding _M_fn and the function arguments with the same qualifiers,
-      // and deducing the return type and exception-specification.
-#define _GLIBCXX_NOT_FN_CALL_OP( _QUALS )                              \
-      template<typename... _Args,                                      \
-              typename = enable_if_t<__is_invocable<_Fn _QUALS, 
_Args...>::value>> \
-       _GLIBCXX20_CONSTEXPR                                            \
-       decltype(_S_not<__inv_res_t<_Fn _QUALS, _Args...>>())           \
-       operator()(_Args&&... __args) _QUALS                            \
-       noexcept(__is_nothrow_invocable<_Fn _QUALS, _Args...>::value    \
-           && noexcept(_S_not<__inv_res_t<_Fn _QUALS, _Args...>>()))   \
-       {                                                               \
-         return !std::__invoke(std::forward< _Fn _QUALS >(_M_fn),      \
-                               std::forward<_Args>(__args)...);        \
-       }                                                               \
-                                                                       \
-      template<typename... _Args,                                      \
-              typename = enable_if_t<!__is_invocable<_Fn _QUALS, 
_Args...>::value>> \
-       void operator()(_Args&&... __args) _QUALS = delete;
-
-      _GLIBCXX_NOT_FN_CALL_OP( & )
-      _GLIBCXX_NOT_FN_CALL_OP( const & )
-      _GLIBCXX_NOT_FN_CALL_OP( && )
-      _GLIBCXX_NOT_FN_CALL_OP( const && )
-#undef _GLIBCXX_NOT_FN_CALL_OP
-
-    private:
-      _Fn _M_fn;
-    };
-
   template<typename _Tp, typename _Pred>
     struct __is_byte_like : false_type { };
 
diff --git a/libstdc++-v3/include/std/string b/libstdc++-v3/include/std/string
index 78e8bacc007..af2a7ef8ca1 100644
--- a/libstdc++-v3/include/std/string
+++ b/libstdc++-v3/include/std/string
@@ -49,7 +49,7 @@
 #include <bits/stl_function.h> // For less
 #include <ext/numeric_traits.h>
 #include <bits/stl_algobase.h>
-#include <bits/refwrap.h>
+#include <bits/move.h>
 #include <bits/range_access.h>
 #include <bits/basic_string.h>
 #include <bits/basic_string.tcc>
@@ -95,11 +95,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     inline typename basic_string<_CharT, _Traits, _Alloc>::size_type
     erase_if(basic_string<_CharT, _Traits, _Alloc>& __cont, _Predicate __pred)
     {
-      using namespace __gnu_cxx;
       const auto __osz = __cont.size();
       const auto __end = __cont.end();
       auto __removed = std::__remove_if(__cont.begin(), __end,
-                                       __ops::__pred_iter(std::ref(__pred)));
+                                       std::move(__pred));
       __cont.erase(__removed, __end);
       return __osz - __cont.size();
     }
@@ -113,7 +112,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       const auto __osz = __cont.size();
       const auto __end = __cont.end();
       auto __removed = std::__remove_if(__cont.begin(), __end,
-                                       __ops::__iter_equals_val(__value));
+                                       __ops::__equal_to(__value));
       __cont.erase(__removed, __end);
       return __osz - __cont.size();
     }
diff --git a/libstdc++-v3/include/std/vector b/libstdc++-v3/include/std/vector
index 5e1d54a04ac..2dfc7b4798e 100644
--- a/libstdc++-v3/include/std/vector
+++ b/libstdc++-v3/include/std/vector
@@ -65,7 +65,7 @@
 #include <bits/stl_uninitialized.h>
 #include <bits/stl_vector.h>
 #include <bits/stl_bvector.h>
-#include <bits/refwrap.h>
+#include <bits/move.h>
 #include <bits/range_access.h>
 
 #ifndef _GLIBCXX_EXPORT_TEMPLATE
@@ -112,12 +112,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     inline typename vector<_Tp, _Alloc>::size_type
     erase_if(vector<_Tp, _Alloc>& __cont, _Predicate __pred)
     {
-      using namespace __gnu_cxx;
       _GLIBCXX_STD_C::vector<_Tp, _Alloc>& __ucont = __cont;
       const auto __osz = __cont.size();
       const auto __end = __ucont.end();
       auto __removed = std::__remove_if(__ucont.begin(), __end,
-                                       __ops::__pred_iter(std::ref(__pred)));
+                                       std::move(__pred));
       if (__removed != __end)
        {
          __cont.erase(__niter_wrap(__cont.begin(), __removed),
@@ -138,7 +137,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       const auto __osz = __cont.size();
       const auto __end = __ucont.end();
       auto __removed = std::__remove_if(__ucont.begin(), __end,
-                                       __ops::__iter_equals_val(__value));
+                                       __ops::__equal_to(__value));
       if (__removed != __end)
        {
          __cont.erase(__niter_wrap(__cont.begin(), __removed),

Reply via email to