Modernize relational operators for shared_ptr and unique_ptr.  This includes adding support for nullptr, and using less<T*>.  Fixes http://llvm.org/bugs/show_bug.cgi?id=12056.

llvm-svn: 151084
Cr-Mirrored-From: sso://chromium.googlesource.com/_direct/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: 67f396476609d1eeb10b565f22f02eaa2fc172ea
diff --git a/include/__functional_base b/include/__functional_base
index ed7d21b..63aa41d 100644
--- a/include/__functional_base
+++ b/include/__functional_base
@@ -50,6 +50,13 @@
     static const bool value = sizeof(__test<_Tp>(0)) == 1;
 };
 
+template <class _Tp>
+struct _LIBCPP_VISIBLE less : binary_function<_Tp, _Tp, bool>
+{
+    _LIBCPP_INLINE_VISIBILITY bool operator()(const _Tp& __x, const _Tp& __y) const
+        {return __x < __y;}
+};
+
 #ifdef _LIBCPP_HAS_NO_VARIADICS
 
 #include <__functional_base_03>
diff --git a/include/functional b/include/functional
index ee0424d..8f912fb 100644
--- a/include/functional
+++ b/include/functional
@@ -536,12 +536,7 @@
         {return __x > __y;}
 };
 
-template <class _Tp>
-struct _LIBCPP_VISIBLE less : binary_function<_Tp, _Tp, bool>
-{
-    _LIBCPP_INLINE_VISIBILITY bool operator()(const _Tp& __x, const _Tp& __y) const
-        {return __x < __y;}
-};
+// less in <__functional_base>
 
 template <class _Tp>
 struct _LIBCPP_VISIBLE greater_equal : binary_function<_Tp, _Tp, bool>
diff --git a/include/memory b/include/memory
index e841b2c..e3dd467 100644
--- a/include/memory
+++ b/include/memory
@@ -2964,7 +2964,13 @@
 template <class _T1, class _D1, class _T2, class _D2>
 inline _LIBCPP_INLINE_VISIBILITY
 bool
-operator< (const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return __x.get() < __y.get();}
+operator< (const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y)
+{
+    typedef typename unique_ptr<_T1, _D1>::pointer _P1;
+    typedef typename unique_ptr<_T2, _D2>::pointer _P2;
+    typedef typename common_type<_P1, _P2>::type _V;
+    return less<_V>()(__x.get(), __y.get());
+}
 
 template <class _T1, class _D1, class _T2, class _D2>
 inline _LIBCPP_INLINE_VISIBILITY
@@ -2981,6 +2987,104 @@
 bool
 operator>=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x < __y);}
 
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const unique_ptr<_T1, _D1>& __x, nullptr_t)
+{
+    return !__x;
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(nullptr_t, const unique_ptr<_T1, _D1>& __x)
+{
+    return !__x;
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const unique_ptr<_T1, _D1>& __x, nullptr_t)
+{
+    return static_cast<bool>(__x);
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(nullptr_t, const unique_ptr<_T1, _D1>& __x)
+{
+    return static_cast<bool>(__x);
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<(const unique_ptr<_T1, _D1>& __x, nullptr_t)
+{
+    typedef typename unique_ptr<_T1, _D1>::pointer _P1;
+    return less<_P1>()(__x.get(), nullptr);
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<(nullptr_t, const unique_ptr<_T1, _D1>& __x)
+{
+    typedef typename unique_ptr<_T1, _D1>::pointer _P1;
+    return less<_P1>()(nullptr, __x.get());
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>(const unique_ptr<_T1, _D1>& __x, nullptr_t)
+{
+    return nullptr < __x;
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>(nullptr_t, const unique_ptr<_T1, _D1>& __x)
+{
+    return __x < nullptr;
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const unique_ptr<_T1, _D1>& __x, nullptr_t)
+{
+    return !(nullptr < __x);
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(nullptr_t, const unique_ptr<_T1, _D1>& __x)
+{
+    return !(__x < nullptr);
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const unique_ptr<_T1, _D1>& __x, nullptr_t)
+{
+    return !(__x < nullptr);
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(nullptr_t, const unique_ptr<_T1, _D1>& __x)
+{
+    return !(nullptr < __x);
+}
+
 template <class _Tp> struct hash;
 
 // We use murmur2 when size_t is 32 bits, and cityhash64 when size_t
@@ -4620,7 +4724,128 @@
 bool
 operator<(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
 {
-    return __x.get() < __y.get();
+    typedef typename common_type<_Tp*, _Up*>::type _V;
+    return less<_V>()(__x.get(), __y.get());
+}
+
+template<class _Tp, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
+{
+    return __y < __x;
+}
+
+template<class _Tp, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
+{
+    return !(__y < __x);
+}
+
+template<class _Tp, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
+{
+    return !(__x < __y);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
+{
+    return !__x;
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
+{
+    return !__x;
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
+{
+    return static_cast<bool>(__x);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
+{
+    return static_cast<bool>(__x);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
+{
+    return less<_Tp*>()(__x.get(), nullptr);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
+{
+    return less<_Tp*>()(nullptr, __x.get());
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
+{
+    return nullptr < __x;
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
+{
+    return __x < nullptr;
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
+{
+    return !(nullptr < __x);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
+{
+    return !(__x < nullptr);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
+{
+    return !(__x < nullptr);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
+{
+    return !(nullptr < __x);
 }
 
 template<class _Tp>