[libc++] [P0619] Add _LIBCPP_ABI_NO_BINDER_BASES and remove binder typedefs in C++20.

Differential Revision: https://reviews.llvm.org/D103753

NOKEYCHECK=True
GitOrigin-RevId: dc066888bd98c0500ca7b590317dc91ccce0fd38
diff --git a/include/__config b/include/__config
index 1f966ad..abeb9a7 100644
--- a/include/__config
+++ b/include/__config
@@ -94,6 +94,9 @@
 #  define _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION
 // Enable optimized version of __do_get_(un)signed which avoids redundant copies.
 #  define _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET
+// In C++20 and later, don't derive std::plus from std::binary_function,
+// nor std::negate from std::unary_function.
+#  define _LIBCPP_ABI_NO_BINDER_BASES
 // Give reverse_iterator<T> one data member of type T, not two.
 // Also, in C++17 and later, don't derive iterator types from std::iterator.
 #  define _LIBCPP_ABI_NO_ITERATOR_BASES
@@ -1360,6 +1363,7 @@
 
 #if defined(_LIBCPP_ENABLE_CXX20_REMOVED_FEATURES)
 #define _LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS
+#define _LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS
 #define _LIBCPP_ENABLE_CXX20_REMOVED_NEGATORS
 #define _LIBCPP_ENABLE_CXX20_REMOVED_RAW_STORAGE_ITERATOR
 #endif // _LIBCPP_ENABLE_CXX20_REMOVED_FEATURES
diff --git a/include/__functional_base b/include/__functional_base
index cdef0f8..b6f2efd 100644
--- a/include/__functional_base
+++ b/include/__functional_base
@@ -42,14 +42,24 @@
     static const bool value = sizeof(__test<_Tp>(0)) == 1;
 };
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 #if _LIBCPP_STD_VER > 11
 template <class _Tp = void>
 #else
 template <class _Tp>
 #endif
-struct _LIBCPP_TEMPLATE_VIS less : binary_function<_Tp, _Tp, bool>
+struct _LIBCPP_TEMPLATE_VIS less
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : binary_function<_Tp, _Tp, bool>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
     typedef bool __result_type;  // used by valarray
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
+#endif
     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
     bool operator()(const _Tp& __x, const _Tp& __y) const
         {return __x < __y;}
@@ -373,7 +383,9 @@
 
 template <class _Tp>
 class _LIBCPP_TEMPLATE_VIS reference_wrapper
+#if _LIBCPP_STD_VER <= 17 || !defined(_LIBCPP_ABI_NO_BINDER_BASES)
     : public __weak_result_type<_Tp>
+#endif
 {
 public:
     // types
diff --git a/include/__memory/shared_ptr.h b/include/__memory/shared_ptr.h
index e7f9af6..f325362 100644
--- a/include/__memory/shared_ptr.h
+++ b/include/__memory/shared_ptr.h
@@ -1594,11 +1594,20 @@
 template <class _Tp> struct owner_less;
 #endif
 
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <class _Tp>
 struct _LIBCPP_TEMPLATE_VIS owner_less<shared_ptr<_Tp> >
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
     : binary_function<shared_ptr<_Tp>, shared_ptr<_Tp>, bool>
+#endif
 {
-    typedef bool result_type;
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef shared_ptr<_Tp> first_argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef shared_ptr<_Tp> second_argument_type;
+#endif
     _LIBCPP_INLINE_VISIBILITY
     bool operator()(shared_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT
         {return __x.owner_before(__y);}
@@ -1610,11 +1619,19 @@
         {return __x.owner_before(__y);}
 };
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <class _Tp>
 struct _LIBCPP_TEMPLATE_VIS owner_less<weak_ptr<_Tp> >
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
     : binary_function<weak_ptr<_Tp>, weak_ptr<_Tp>, bool>
+#endif
 {
-    typedef bool result_type;
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef weak_ptr<_Tp> first_argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef weak_ptr<_Tp> second_argument_type;
+#endif
     _LIBCPP_INLINE_VISIBILITY
     bool operator()(  weak_ptr<_Tp> const& __x,   weak_ptr<_Tp> const& __y) const _NOEXCEPT
         {return __x.owner_before(__y);}
@@ -1690,11 +1707,13 @@
 template <class _Tp>
 struct _LIBCPP_TEMPLATE_VIS hash<shared_ptr<_Tp> >
 {
-    typedef shared_ptr<_Tp>      argument_type;
-    typedef size_t               result_type;
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef shared_ptr<_Tp> argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t          result_type;
+#endif
 
     _LIBCPP_INLINE_VISIBILITY
-    result_type operator()(const argument_type& __ptr) const _NOEXCEPT
+    size_t operator()(const shared_ptr<_Tp>& __ptr) const _NOEXCEPT
     {
         return hash<typename shared_ptr<_Tp>::element_type*>()(__ptr.get());
     }
diff --git a/include/__memory/unique_ptr.h b/include/__memory/unique_ptr.h
index 8148fad..7585a91 100644
--- a/include/__memory/unique_ptr.h
+++ b/include/__memory/unique_ptr.h
@@ -750,12 +750,15 @@
     unique_ptr<_Tp, _Dp>, typename unique_ptr<_Tp, _Dp>::pointer> >
 #endif
 {
-    typedef unique_ptr<_Tp, _Dp> argument_type;
-    typedef size_t               result_type;
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef unique_ptr<_Tp, _Dp> argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t               result_type;
+#endif
+
     _LIBCPP_INLINE_VISIBILITY
-    result_type operator()(const argument_type& __ptr) const
+    size_t operator()(const unique_ptr<_Tp, _Dp>& __ptr) const
     {
-        typedef typename argument_type::pointer pointer;
+        typedef typename unique_ptr<_Tp, _Dp>::pointer pointer;
         return hash<pointer>()(__ptr.get());
     }
 };
diff --git a/include/functional b/include/functional
index 62e9b89..89ee2a0 100644
--- a/include/functional
+++ b/include/functional
@@ -76,116 +76,97 @@
 template <class T> using unwrap_ref_decay_t = typename unwrap_ref_decay<T>::type; // since C++20
 
 template <class T> // <class T=void> in C++14
-struct plus : binary_function<T, T, T>
-{
+struct plus {
     T operator()(const T& x, const T& y) const;
 };
 
 template <class T> // <class T=void> in C++14
-struct minus : binary_function<T, T, T>
-{
+struct minus {
     T operator()(const T& x, const T& y) const;
 };
 
 template <class T> // <class T=void> in C++14
-struct multiplies : binary_function<T, T, T>
-{
+struct multiplies {
     T operator()(const T& x, const T& y) const;
 };
 
 template <class T> // <class T=void> in C++14
-struct divides : binary_function<T, T, T>
-{
+struct divides {
     T operator()(const T& x, const T& y) const;
 };
 
 template <class T> // <class T=void> in C++14
-struct modulus : binary_function<T, T, T>
-{
+struct modulus {
     T operator()(const T& x, const T& y) const;
 };
 
 template <class T> // <class T=void> in C++14
-struct negate : unary_function<T, T>
-{
+struct negate {
     T operator()(const T& x) const;
 };
 
 template <class T> // <class T=void> in C++14
-struct equal_to : binary_function<T, T, bool>
-{
+struct equal_to {
     bool operator()(const T& x, const T& y) const;
 };
 
 template <class T> // <class T=void> in C++14
-struct not_equal_to : binary_function<T, T, bool>
-{
+struct not_equal_to {
     bool operator()(const T& x, const T& y) const;
 };
 
 template <class T> // <class T=void> in C++14
-struct greater : binary_function<T, T, bool>
-{
+struct greater {
     bool operator()(const T& x, const T& y) const;
 };
 
 template <class T> // <class T=void> in C++14
-struct less : binary_function<T, T, bool>
-{
+struct less {
     bool operator()(const T& x, const T& y) const;
 };
 
 template <class T> // <class T=void> in C++14
-struct greater_equal : binary_function<T, T, bool>
-{
+struct greater_equal {
     bool operator()(const T& x, const T& y) const;
 };
 
 template <class T> // <class T=void> in C++14
-struct less_equal : binary_function<T, T, bool>
-{
+struct less_equal {
     bool operator()(const T& x, const T& y) const;
 };
 
 template <class T> // <class T=void> in C++14
-struct logical_and : binary_function<T, T, bool>
-{
+struct logical_and {
     bool operator()(const T& x, const T& y) const;
 };
 
 template <class T> // <class T=void> in C++14
-struct logical_or : binary_function<T, T, bool>
-{
+struct logical_or {
     bool operator()(const T& x, const T& y) const;
 };
 
 template <class T> // <class T=void> in C++14
-struct logical_not : unary_function<T, bool>
-{
+struct logical_not {
     bool operator()(const T& x) const;
 };
 
 template <class T> // <class T=void> in C++14
-struct bit_and : binary_function<T, T, T>
-{
+struct bit_and {
     T operator()(const T& x, const T& y) const;
 };
 
 template <class T> // <class T=void> in C++14
-struct bit_or : binary_function<T, T, T>
-{
+struct bit_or {
     T operator()(const T& x, const T& y) const;
 };
 
 template <class T> // <class T=void> in C++14
-struct bit_xor : binary_function<T, T, T>
-{
+struct bit_xor {
     T operator()(const T& x, const T& y) const;
 };
 
 template <class T=void> // C++14
-struct bit_not : unary_function<T, T>
-{
+struct bit_not {
     T operator()(const T& x) const;
 };
 
@@ -524,14 +505,24 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 #if _LIBCPP_STD_VER > 11
 template <class _Tp = void>
 #else
 template <class _Tp>
 #endif
-struct _LIBCPP_TEMPLATE_VIS plus : binary_function<_Tp, _Tp, _Tp>
+struct _LIBCPP_TEMPLATE_VIS plus
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : binary_function<_Tp, _Tp, _Tp>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
     typedef _Tp __result_type;  // used by valarray
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
+#endif
     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
     _Tp operator()(const _Tp& __x, const _Tp& __y) const
         {return __x + __y;}
@@ -552,14 +543,24 @@
 #endif
 
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 #if _LIBCPP_STD_VER > 11
 template <class _Tp = void>
 #else
 template <class _Tp>
 #endif
-struct _LIBCPP_TEMPLATE_VIS minus : binary_function<_Tp, _Tp, _Tp>
+struct _LIBCPP_TEMPLATE_VIS minus
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : binary_function<_Tp, _Tp, _Tp>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
     typedef _Tp __result_type;  // used by valarray
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
+#endif
     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
     _Tp operator()(const _Tp& __x, const _Tp& __y) const
         {return __x - __y;}
@@ -580,14 +581,24 @@
 #endif
 
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 #if _LIBCPP_STD_VER > 11
 template <class _Tp = void>
 #else
 template <class _Tp>
 #endif
-struct _LIBCPP_TEMPLATE_VIS multiplies : binary_function<_Tp, _Tp, _Tp>
+struct _LIBCPP_TEMPLATE_VIS multiplies
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : binary_function<_Tp, _Tp, _Tp>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
     typedef _Tp __result_type;  // used by valarray
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
+#endif
     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
     _Tp operator()(const _Tp& __x, const _Tp& __y) const
         {return __x * __y;}
@@ -608,14 +619,24 @@
 #endif
 
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 #if _LIBCPP_STD_VER > 11
 template <class _Tp = void>
 #else
 template <class _Tp>
 #endif
-struct _LIBCPP_TEMPLATE_VIS divides : binary_function<_Tp, _Tp, _Tp>
+struct _LIBCPP_TEMPLATE_VIS divides
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : binary_function<_Tp, _Tp, _Tp>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
     typedef _Tp __result_type;  // used by valarray
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
+#endif
     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
     _Tp operator()(const _Tp& __x, const _Tp& __y) const
         {return __x / __y;}
@@ -636,14 +657,24 @@
 #endif
 
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 #if _LIBCPP_STD_VER > 11
 template <class _Tp = void>
 #else
 template <class _Tp>
 #endif
-struct _LIBCPP_TEMPLATE_VIS modulus : binary_function<_Tp, _Tp, _Tp>
+struct _LIBCPP_TEMPLATE_VIS modulus
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : binary_function<_Tp, _Tp, _Tp>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
     typedef _Tp __result_type;  // used by valarray
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
+#endif
     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
     _Tp operator()(const _Tp& __x, const _Tp& __y) const
         {return __x % __y;}
@@ -664,14 +695,23 @@
 #endif
 
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 #if _LIBCPP_STD_VER > 11
 template <class _Tp = void>
 #else
 template <class _Tp>
 #endif
-struct _LIBCPP_TEMPLATE_VIS negate : unary_function<_Tp, _Tp>
+struct _LIBCPP_TEMPLATE_VIS negate
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : unary_function<_Tp, _Tp>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
     typedef _Tp __result_type;  // used by valarray
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type;
+#endif
     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
     _Tp operator()(const _Tp& __x) const
         {return -__x;}
@@ -692,14 +732,24 @@
 #endif
 
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 #if _LIBCPP_STD_VER > 11
 template <class _Tp = void>
 #else
 template <class _Tp>
 #endif
-struct _LIBCPP_TEMPLATE_VIS equal_to : binary_function<_Tp, _Tp, bool>
+struct _LIBCPP_TEMPLATE_VIS equal_to
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : binary_function<_Tp, _Tp, bool>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
     typedef bool __result_type;  // used by valarray
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
+#endif
     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
     bool operator()(const _Tp& __x, const _Tp& __y) const
         {return __x == __y;}
@@ -720,14 +770,24 @@
 #endif
 
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 #if _LIBCPP_STD_VER > 11
 template <class _Tp = void>
 #else
 template <class _Tp>
 #endif
-struct _LIBCPP_TEMPLATE_VIS not_equal_to : binary_function<_Tp, _Tp, bool>
+struct _LIBCPP_TEMPLATE_VIS not_equal_to
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : binary_function<_Tp, _Tp, bool>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
     typedef bool __result_type;  // used by valarray
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
+#endif
     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
     bool operator()(const _Tp& __x, const _Tp& __y) const
         {return __x != __y;}
@@ -748,14 +808,24 @@
 #endif
 
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 #if _LIBCPP_STD_VER > 11
 template <class _Tp = void>
 #else
 template <class _Tp>
 #endif
-struct _LIBCPP_TEMPLATE_VIS greater : binary_function<_Tp, _Tp, bool>
+struct _LIBCPP_TEMPLATE_VIS greater
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : binary_function<_Tp, _Tp, bool>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
     typedef bool __result_type;  // used by valarray
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
+#endif
     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
     bool operator()(const _Tp& __x, const _Tp& __y) const
         {return __x > __y;}
@@ -778,14 +848,25 @@
 
 // less in <__functional_base>
 
+
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 #if _LIBCPP_STD_VER > 11
 template <class _Tp = void>
 #else
 template <class _Tp>
 #endif
-struct _LIBCPP_TEMPLATE_VIS greater_equal : binary_function<_Tp, _Tp, bool>
+struct _LIBCPP_TEMPLATE_VIS greater_equal
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : binary_function<_Tp, _Tp, bool>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
     typedef bool __result_type;  // used by valarray
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
+#endif
     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
     bool operator()(const _Tp& __x, const _Tp& __y) const
         {return __x >= __y;}
@@ -806,14 +887,24 @@
 #endif
 
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 #if _LIBCPP_STD_VER > 11
 template <class _Tp = void>
 #else
 template <class _Tp>
 #endif
-struct _LIBCPP_TEMPLATE_VIS less_equal : binary_function<_Tp, _Tp, bool>
+struct _LIBCPP_TEMPLATE_VIS less_equal
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : binary_function<_Tp, _Tp, bool>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
     typedef bool __result_type;  // used by valarray
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
+#endif
     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
     bool operator()(const _Tp& __x, const _Tp& __y) const
         {return __x <= __y;}
@@ -834,14 +925,24 @@
 #endif
 
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 #if _LIBCPP_STD_VER > 11
 template <class _Tp = void>
 #else
 template <class _Tp>
 #endif
-struct _LIBCPP_TEMPLATE_VIS logical_and : binary_function<_Tp, _Tp, bool>
+struct _LIBCPP_TEMPLATE_VIS logical_and
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : binary_function<_Tp, _Tp, bool>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
     typedef bool __result_type;  // used by valarray
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
+#endif
     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
     bool operator()(const _Tp& __x, const _Tp& __y) const
         {return __x && __y;}
@@ -862,14 +963,24 @@
 #endif
 
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 #if _LIBCPP_STD_VER > 11
 template <class _Tp = void>
 #else
 template <class _Tp>
 #endif
-struct _LIBCPP_TEMPLATE_VIS logical_or : binary_function<_Tp, _Tp, bool>
+struct _LIBCPP_TEMPLATE_VIS logical_or
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : binary_function<_Tp, _Tp, bool>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
     typedef bool __result_type;  // used by valarray
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
+#endif
     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
     bool operator()(const _Tp& __x, const _Tp& __y) const
         {return __x || __y;}
@@ -890,14 +1001,23 @@
 #endif
 
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 #if _LIBCPP_STD_VER > 11
 template <class _Tp = void>
 #else
 template <class _Tp>
 #endif
-struct _LIBCPP_TEMPLATE_VIS logical_not : unary_function<_Tp, bool>
+struct _LIBCPP_TEMPLATE_VIS logical_not
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : unary_function<_Tp, bool>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
     typedef bool __result_type;  // used by valarray
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type;
+#endif
     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
     bool operator()(const _Tp& __x) const
         {return !__x;}
@@ -918,14 +1038,24 @@
 #endif
 
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 #if _LIBCPP_STD_VER > 11
 template <class _Tp = void>
 #else
 template <class _Tp>
 #endif
-struct _LIBCPP_TEMPLATE_VIS bit_and : binary_function<_Tp, _Tp, _Tp>
+struct _LIBCPP_TEMPLATE_VIS bit_and
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : binary_function<_Tp, _Tp, _Tp>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
     typedef _Tp __result_type;  // used by valarray
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
+#endif
     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
     _Tp operator()(const _Tp& __x, const _Tp& __y) const
         {return __x & __y;}
@@ -946,14 +1076,24 @@
 #endif
 
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 #if _LIBCPP_STD_VER > 11
 template <class _Tp = void>
 #else
 template <class _Tp>
 #endif
-struct _LIBCPP_TEMPLATE_VIS bit_or : binary_function<_Tp, _Tp, _Tp>
+struct _LIBCPP_TEMPLATE_VIS bit_or
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : binary_function<_Tp, _Tp, _Tp>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
     typedef _Tp __result_type;  // used by valarray
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
+#endif
     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
     _Tp operator()(const _Tp& __x, const _Tp& __y) const
         {return __x | __y;}
@@ -974,14 +1114,24 @@
 #endif
 
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 #if _LIBCPP_STD_VER > 11
 template <class _Tp = void>
 #else
 template <class _Tp>
 #endif
-struct _LIBCPP_TEMPLATE_VIS bit_xor : binary_function<_Tp, _Tp, _Tp>
+struct _LIBCPP_TEMPLATE_VIS bit_xor
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : binary_function<_Tp, _Tp, _Tp>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
     typedef _Tp __result_type;  // used by valarray
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type;
+#endif
     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
     _Tp operator()(const _Tp& __x, const _Tp& __y) const
         {return __x ^ __y;}
@@ -1003,9 +1153,18 @@
 
 
 #if _LIBCPP_STD_VER > 11
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <class _Tp = void>
-struct _LIBCPP_TEMPLATE_VIS bit_not : unary_function<_Tp, _Tp>
+struct _LIBCPP_TEMPLATE_VIS bit_not
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
+    : unary_function<_Tp, _Tp>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type;
+#endif
     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
     _Tp operator()(const _Tp& __x) const
         {return ~__x;}
@@ -1307,7 +1466,9 @@
 
 template <class _Tp>
 class __mem_fn
+#if _LIBCPP_STD_VER <= 17 || !defined(_LIBCPP_ABI_NO_BINDER_BASES)
     : public __weak_result_type<_Tp>
+#endif
 {
 public:
     // types
@@ -2354,8 +2515,10 @@
 
 template<class _Rp, class ..._ArgTypes>
 class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)>
+#if _LIBCPP_STD_VER <= 17 || !defined(_LIBCPP_ABI_NO_BINDER_BASES)
     : public __function::__maybe_derive_from_unary_function<_Rp(_ArgTypes...)>,
       public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)>
+#endif
 {
 #ifndef _LIBCPP_ABI_OPTIMIZED_FUNCTION
     typedef __function::__value_func<_Rp(_ArgTypes...)> __func;
@@ -2884,7 +3047,9 @@
 
 template<class _Fp, class ..._BoundArgs>
 class __bind
+#if _LIBCPP_STD_VER <= 17 || !defined(_LIBCPP_ABI_NO_BINDER_BASES)
     : public __weak_result_type<typename decay<_Fp>::type>
+#endif
 {
 protected:
     typedef typename decay<_Fp>::type _Fd;
diff --git a/include/map b/include/map
index 22376f3..c7f7df2 100644
--- a/include/map
+++ b/include/map
@@ -43,7 +43,6 @@
     typedef INSERT_RETURN_TYPE<iterator, node_type>  insert_return_type;     // C++17
 
     class value_compare
-        : public binary_function<value_type, value_type, bool>
     {
         friend class map;
     protected:
@@ -51,6 +50,9 @@
 
         value_compare(key_compare c);
     public:
+        typedef bool result_type;  // deprecated in C++17, removed in C++20
+        typedef value_type first_argument_type;  // deprecated in C++17, removed in C++20
+        typedef value_type second_argument_type;  // deprecated in C++17, removed in C++20
         bool operator()(const value_type& x, const value_type& y) const;
     };
 
@@ -287,13 +289,15 @@
     typedef unspecified                              node_type;              // C++17
 
     class value_compare
-        : public binary_function<value_type,value_type,bool>
     {
         friend class multimap;
     protected:
         key_compare comp;
         value_compare(key_compare c);
     public:
+        typedef bool result_type;  // deprecated in C++17, removed in C++20
+        typedef value_type first_argument_type;  // deprecated in C++17, removed in C++20
+        typedef value_type second_argument_type;  // deprecated in C++17, removed in C++20
         bool operator()(const value_type& x, const value_type& y) const;
     };
 
@@ -922,15 +926,24 @@
     static_assert((is_same<typename allocator_type::value_type, value_type>::value),
                   "Allocator::value_type must be same type as value_type");
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
     class _LIBCPP_TEMPLATE_VIS value_compare
+#if defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
         : public binary_function<value_type, value_type, bool>
+#endif
     {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
         friend class map;
     protected:
         key_compare comp;
 
         _LIBCPP_INLINE_VISIBILITY value_compare(key_compare c) : comp(c) {}
     public:
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+        _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
+        _LIBCPP_DEPRECATED_IN_CXX17 typedef value_type first_argument_type;
+        _LIBCPP_DEPRECATED_IN_CXX17 typedef value_type second_argument_type;
+#endif
         _LIBCPP_INLINE_VISIBILITY
         bool operator()(const value_type& __x, const value_type& __y) const
             {return comp(__x.first, __y.first);}
@@ -1696,9 +1709,13 @@
     static_assert((is_same<typename allocator_type::value_type, value_type>::value),
                   "Allocator::value_type must be same type as value_type");
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
     class _LIBCPP_TEMPLATE_VIS value_compare
+#if defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
         : public binary_function<value_type, value_type, bool>
+#endif
     {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
         friend class multimap;
     protected:
         key_compare comp;
@@ -1706,6 +1723,11 @@
         _LIBCPP_INLINE_VISIBILITY
         value_compare(key_compare c) : comp(c) {}
     public:
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+        _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
+        _LIBCPP_DEPRECATED_IN_CXX17 typedef value_type first_argument_type;
+        _LIBCPP_DEPRECATED_IN_CXX17 typedef value_type second_argument_type;
+#endif
         _LIBCPP_INLINE_VISIBILITY
         bool operator()(const value_type& __x, const value_type& __y) const
             {return comp(__x.first, __y.first);}
diff --git a/include/optional b/include/optional
index 8a291a6..0e6c1b8 100644
--- a/include/optional
+++ b/include/optional
@@ -1407,11 +1407,13 @@
     __enable_hash_helper<optional<_Tp>, remove_const_t<_Tp>>
 >
 {
-    typedef optional<_Tp> argument_type;
-    typedef size_t        result_type;
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef optional<_Tp> argument_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t        result_type;
+#endif
 
     _LIBCPP_INLINE_VISIBILITY
-    result_type operator()(const argument_type& __opt) const
+    size_t operator()(const optional<_Tp>& __opt) const
     {
         return static_cast<bool>(__opt) ? hash<remove_const_t<_Tp>>()(*__opt) : 0;
     }
diff --git a/include/utility b/include/utility
index d895cfe..1060b5c 100644
--- a/include/utility
+++ b/include/utility
@@ -1298,10 +1298,18 @@
 template <class _Tp, size_t = sizeof(_Tp) / sizeof(size_t)>
 struct __scalar_hash;
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <class _Tp>
 struct __scalar_hash<_Tp, 0>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
     : public unary_function<_Tp, size_t>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type;
+#endif
     _LIBCPP_INLINE_VISIBILITY
     size_t operator()(_Tp __v) const _NOEXCEPT
     {
@@ -1316,10 +1324,18 @@
     }
 };
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <class _Tp>
 struct __scalar_hash<_Tp, 1>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
     : public unary_function<_Tp, size_t>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type;
+#endif
     _LIBCPP_INLINE_VISIBILITY
     size_t operator()(_Tp __v) const _NOEXCEPT
     {
@@ -1333,10 +1349,18 @@
     }
 };
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <class _Tp>
 struct __scalar_hash<_Tp, 2>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
     : public unary_function<_Tp, size_t>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type;
+#endif
     _LIBCPP_INLINE_VISIBILITY
     size_t operator()(_Tp __v) const _NOEXCEPT
     {
@@ -1354,10 +1378,18 @@
     }
 };
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <class _Tp>
 struct __scalar_hash<_Tp, 3>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
     : public unary_function<_Tp, size_t>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type;
+#endif
     _LIBCPP_INLINE_VISIBILITY
     size_t operator()(_Tp __v) const _NOEXCEPT
     {
@@ -1376,10 +1408,18 @@
     }
 };
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <class _Tp>
 struct __scalar_hash<_Tp, 4>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
     : public unary_function<_Tp, size_t>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type;
+#endif
     _LIBCPP_INLINE_VISIBILITY
     size_t operator()(_Tp __v) const _NOEXCEPT
     {
@@ -1411,10 +1451,18 @@
     return _HashT()(__p);
 }
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template<class _Tp>
 struct _LIBCPP_TEMPLATE_VIS hash<_Tp*>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
     : public unary_function<_Tp*, size_t>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp* argument_type;
+#endif
     _LIBCPP_INLINE_VISIBILITY
     size_t operator()(_Tp* __v) const _NOEXCEPT
     {
@@ -1428,44 +1476,83 @@
     }
 };
 
-
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <>
 struct _LIBCPP_TEMPLATE_VIS hash<bool>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
     : public unary_function<bool, size_t>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef bool argument_type;
+#endif
     _LIBCPP_INLINE_VISIBILITY
     size_t operator()(bool __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
 };
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <>
 struct _LIBCPP_TEMPLATE_VIS hash<char>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
     : public unary_function<char, size_t>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef char argument_type;
+#endif
     _LIBCPP_INLINE_VISIBILITY
     size_t operator()(char __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
 };
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <>
 struct _LIBCPP_TEMPLATE_VIS hash<signed char>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
     : public unary_function<signed char, size_t>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef signed char argument_type;
+#endif
     _LIBCPP_INLINE_VISIBILITY
     size_t operator()(signed char __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
 };
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <>
 struct _LIBCPP_TEMPLATE_VIS hash<unsigned char>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
     : public unary_function<unsigned char, size_t>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef unsigned char argument_type;
+#endif
     _LIBCPP_INLINE_VISIBILITY
     size_t operator()(unsigned char __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
 };
 
 #ifndef _LIBCPP_HAS_NO_CHAR8_T
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <>
 struct _LIBCPP_TEMPLATE_VIS hash<char8_t>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
     : public unary_function<char8_t, size_t>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef char8_t argument_type;
+#endif
     _LIBCPP_INLINE_VISIBILITY
     size_t operator()(char8_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
 };
@@ -1473,76 +1560,148 @@
 
 #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <>
 struct _LIBCPP_TEMPLATE_VIS hash<char16_t>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
     : public unary_function<char16_t, size_t>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef char16_t argument_type;
+#endif
     _LIBCPP_INLINE_VISIBILITY
     size_t operator()(char16_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
 };
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <>
 struct _LIBCPP_TEMPLATE_VIS hash<char32_t>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
     : public unary_function<char32_t, size_t>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef char32_t argument_type;
+#endif
     _LIBCPP_INLINE_VISIBILITY
     size_t operator()(char32_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
 };
 
 #endif // _LIBCPP_HAS_NO_UNICODE_CHARS
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <>
 struct _LIBCPP_TEMPLATE_VIS hash<wchar_t>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
     : public unary_function<wchar_t, size_t>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef wchar_t argument_type;
+#endif
     _LIBCPP_INLINE_VISIBILITY
     size_t operator()(wchar_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
 };
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <>
 struct _LIBCPP_TEMPLATE_VIS hash<short>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
     : public unary_function<short, size_t>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef short argument_type;
+#endif
     _LIBCPP_INLINE_VISIBILITY
     size_t operator()(short __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
 };
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <>
 struct _LIBCPP_TEMPLATE_VIS hash<unsigned short>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
     : public unary_function<unsigned short, size_t>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef unsigned short argument_type;
+#endif
     _LIBCPP_INLINE_VISIBILITY
     size_t operator()(unsigned short __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
 };
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <>
 struct _LIBCPP_TEMPLATE_VIS hash<int>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
     : public unary_function<int, size_t>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef int argument_type;
+#endif
     _LIBCPP_INLINE_VISIBILITY
     size_t operator()(int __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
 };
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <>
 struct _LIBCPP_TEMPLATE_VIS hash<unsigned int>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
     : public unary_function<unsigned int, size_t>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef unsigned int argument_type;
+#endif
     _LIBCPP_INLINE_VISIBILITY
     size_t operator()(unsigned int __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
 };
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <>
 struct _LIBCPP_TEMPLATE_VIS hash<long>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
     : public unary_function<long, size_t>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef long argument_type;
+#endif
     _LIBCPP_INLINE_VISIBILITY
     size_t operator()(long __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
 };
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <>
 struct _LIBCPP_TEMPLATE_VIS hash<unsigned long>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
     : public unary_function<unsigned long, size_t>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef unsigned long argument_type;
+#endif
     _LIBCPP_INLINE_VISIBILITY
     size_t operator()(unsigned long __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
 };
@@ -1655,10 +1814,18 @@
 
 #if _LIBCPP_STD_VER > 11
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <class _Tp, bool = is_enum<_Tp>::value>
 struct _LIBCPP_TEMPLATE_VIS __enum_hash
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
     : public unary_function<_Tp, size_t>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type;
+#endif
     _LIBCPP_INLINE_VISIBILITY
     size_t operator()(_Tp __v) const _NOEXCEPT
     {
@@ -1681,14 +1848,22 @@
 
 #if _LIBCPP_STD_VER > 14
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <>
 struct _LIBCPP_TEMPLATE_VIS hash<nullptr_t>
+#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
   : public unary_function<nullptr_t, size_t>
+#endif
 {
-  _LIBCPP_INLINE_VISIBILITY
-  size_t operator()(nullptr_t) const _NOEXCEPT {
-    return 662607004ull;
-  }
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
+    _LIBCPP_DEPRECATED_IN_CXX17 typedef nullptr_t argument_type;
+#endif
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(nullptr_t) const _NOEXCEPT {
+        return 662607004ull;
+    }
 };
 #endif