diff --git a/include/__functional_base b/include/__functional_base index ed7d21b5..63aa41d5 100644 --- a/include/__functional_base +++ b/include/__functional_base @@ -50,6 +50,13 @@ public: 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 ee0424d0..8f912fb0 100644 --- a/include/functional +++ b/include/functional @@ -536,12 +536,7 @@ struct _LIBCPP_VISIBLE greater : binary_function<_Tp, _Tp, bool> {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 e841b2cf..e3dd467b 100644 --- a/include/memory +++ b/include/memory @@ -2964,7 +2964,13 @@ operator!=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {re 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 @@ inline _LIBCPP_INLINE_VISIBILITY 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 @@ inline _LIBCPP_INLINE_VISIBILITY 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> diff --git a/test/utilities/memory/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp b/test/utilities/memory/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp new file mode 100644 index 00000000..deb615ec --- /dev/null +++ b/test/utilities/memory/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp @@ -0,0 +1,71 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <memory> + +// shared_ptr + +// template <class T, class D> +// bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept; +// template <class T, class D> +// bool operator==(nullptr_t, const unique_ptr<T, D>& y) noexcept; +// template <class T, class D> +// bool operator!=(const unique_ptr<T, D>& x, nullptr_t) noexcept; +// template <class T, class D> +// bool operator!=(nullptr_t, const unique_ptr<T, D>& y) noexcept; +// template <class T, class D> +// bool operator<(const unique_ptr<T, D>& x, nullptr_t) noexcept; +// template <class T, class D> +// bool operator<(nullptr_t, const unique_ptr<T, D>& y) noexcept; +// template <class T, class D> +// bool operator<=(const unique_ptr<T, D>& x, nullptr_t) noexcept; +// template <class T, class D> +// bool operator<=(nullptr_t, const unique_ptr<T, D>& y) noexcept; +// template <class T, class D> +// bool operator>(const unique_ptr<T, D>& x, nullptr_t) noexcept; +// template <class T, class D> +// bool operator>(nullptr_t, const unique_ptr<T, D>& y) noexcept; +// template <class T, class D> +// bool operator>=(const unique_ptr<T, D>& x, nullptr_t) noexcept; +// template <class T, class D> +// bool operator>=(nullptr_t, const unique_ptr<T, D>& y) noexcept; + +#include <memory> +#include <cassert> + +void do_nothing(int*) {} + +int main() +{ + int* ptr1(new int); + int* ptr2(new int); + const std::unique_ptr<int> p1(new int(1)); + assert(!(p1 == nullptr)); + assert(!(nullptr == p1)); + assert(!(p1 < nullptr)); + assert( (nullptr < p1)); + assert(!(p1 <= nullptr)); + assert( (nullptr <= p1)); + assert( (p1 > nullptr)); + assert(!(nullptr > p1)); + assert( (p1 >= nullptr)); + assert(!(nullptr >= p1)); + + const std::unique_ptr<int> p2; + assert( (p2 == nullptr)); + assert( (nullptr == p2)); + assert(!(p2 < nullptr)); + assert(!(nullptr < p2)); + assert( (p2 <= nullptr)); + assert( (nullptr <= p2)); + assert(!(p2 > nullptr)); + assert(!(nullptr > p2)); + assert( (p2 >= nullptr)); + assert( (nullptr >= p2)); +} diff --git a/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cmp/cmp_nullptr.pass.cpp b/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cmp/cmp_nullptr.pass.cpp new file mode 100644 index 00000000..d8d3113f --- /dev/null +++ b/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cmp/cmp_nullptr.pass.cpp @@ -0,0 +1,71 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <memory> + +// shared_ptr + +// template <class T> +// bool operator==(const shared_ptr<T>& x, nullptr_t) noexcept; +// template <class T> +// bool operator==(nullptr_t, const shared_ptr<T>& y) noexcept; +// template <class T> +// bool operator!=(const shared_ptr<T>& x, nullptr_t) noexcept; +// template <class T> +// bool operator!=(nullptr_t, const shared_ptr<T>& y) noexcept; +// template <class T> +// bool operator<(const shared_ptr<T>& x, nullptr_t) noexcept; +// template <class T> +// bool operator<(nullptr_t, const shared_ptr<T>& y) noexcept; +// template <class T> +// bool operator<=(const shared_ptr<T>& x, nullptr_t) noexcept; +// template <class T> +// bool operator<=(nullptr_t, const shared_ptr<T>& y) noexcept; +// template <class T> +// bool operator>(const shared_ptr<T>& x, nullptr_t) noexcept; +// template <class T> +// bool operator>(nullptr_t, const shared_ptr<T>& y) noexcept; +// template <class T> +// bool operator>=(const shared_ptr<T>& x, nullptr_t) noexcept; +// template <class T> +// bool operator>=(nullptr_t, const shared_ptr<T>& y) noexcept; + +#include <memory> +#include <cassert> + +void do_nothing(int*) {} + +int main() +{ + int* ptr1(new int); + int* ptr2(new int); + const std::shared_ptr<int> p1(new int(1)); + assert(!(p1 == nullptr)); + assert(!(nullptr == p1)); + assert(!(p1 < nullptr)); + assert( (nullptr < p1)); + assert(!(p1 <= nullptr)); + assert( (nullptr <= p1)); + assert( (p1 > nullptr)); + assert(!(nullptr > p1)); + assert( (p1 >= nullptr)); + assert(!(nullptr >= p1)); + + const std::shared_ptr<int> p2; + assert( (p2 == nullptr)); + assert( (nullptr == p2)); + assert(!(p2 < nullptr)); + assert(!(nullptr < p2)); + assert( (p2 <= nullptr)); + assert( (nullptr <= p2)); + assert(!(p2 > nullptr)); + assert(!(nullptr > p2)); + assert( (p2 >= nullptr)); + assert( (nullptr >= p2)); +}