Hi, tested x86_64-darwin, committed to mainline.
Paolo. ///////////
2011-03-22 Paolo Carlini <paolo.carl...@oracle.com> * include/bits/shared_ptr.h (operator>, operator<=, operator>=): Add, per DR 1401. (operator==, operator!=, operator<): Fix per the letter of DR 1401. * include/bits/shared_ptr_base.h: Likewise for __shared_ptr. * include/bits/unique_ptr.h (operator==, operator!=, operator<, operator<=, operator>, operator>=): Fix per the letter of DR 1401. * testsuite/20_util/shared_ptr/comparison/dr1401.cc: New. * testsuite/20_util/unique_ptr/comparison/dr1401.cc: Likewise. * testsuite/20_util/weak_ptr/comparison/cmp_neg.cc: Adjust.
Index: include/bits/shared_ptr.h =================================================================== --- include/bits/shared_ptr.h (revision 171282) +++ include/bits/shared_ptr.h (working copy) @@ -321,40 +321,104 @@ // 20.8.13.2.7 shared_ptr comparisons template<typename _Tp1, typename _Tp2> inline bool - operator==(const shared_ptr<_Tp1>& __a, const shared_ptr<_Tp2>& __b) + operator==(const shared_ptr<_Tp1>& __a, + const shared_ptr<_Tp2>& __b) noexcept { return __a.get() == __b.get(); } template<typename _Tp> inline bool - operator==(const shared_ptr<_Tp>& __a, nullptr_t) - { return __a.get() == nullptr; } + operator==(const shared_ptr<_Tp>& __a, nullptr_t) noexcept + { return !__a; } template<typename _Tp> inline bool - operator==(nullptr_t, const shared_ptr<_Tp>& __b) - { return nullptr == __b.get(); } + operator==(nullptr_t, const shared_ptr<_Tp>& __a) noexcept + { return !__a; } template<typename _Tp1, typename _Tp2> inline bool - operator!=(const shared_ptr<_Tp1>& __a, const shared_ptr<_Tp2>& __b) + operator!=(const shared_ptr<_Tp1>& __a, + const shared_ptr<_Tp2>& __b) noexcept { return __a.get() != __b.get(); } template<typename _Tp> inline bool - operator!=(const shared_ptr<_Tp>& __a, nullptr_t) - { return __a.get() != nullptr; } + operator!=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept + { return (bool)__a; } template<typename _Tp> inline bool - operator!=(nullptr_t, const shared_ptr<_Tp>& __b) - { return nullptr != __b.get(); } + operator!=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept + { return (bool)__a; } template<typename _Tp1, typename _Tp2> inline bool - operator<(const shared_ptr<_Tp1>& __a, const shared_ptr<_Tp2>& __b) - { return __a.get() < __b.get(); } + operator<(const shared_ptr<_Tp1>& __a, + const shared_ptr<_Tp2>& __b) noexcept + { + typedef typename std::common_type<_Tp1*, _Tp2*>::type _CT; + return std::less<_CT>()(__a.get(), __b.get()); + } template<typename _Tp> + inline bool + operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept + { return std::less<_Tp*>()(__a.get(), nullptr); } + + template<typename _Tp> + inline bool + operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept + { return std::less<_Tp*>()(nullptr, __a.get()); } + + template<typename _Tp1, typename _Tp2> + inline bool + operator<=(const shared_ptr<_Tp1>& __a, + const shared_ptr<_Tp2>& __b) noexcept + { return !(__b < __a); } + + template<typename _Tp> + inline bool + operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept + { return !(nullptr < __a); } + + template<typename _Tp> + inline bool + operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept + { return !(__a < nullptr); } + + template<typename _Tp1, typename _Tp2> + inline bool + operator>(const shared_ptr<_Tp1>& __a, + const shared_ptr<_Tp2>& __b) noexcept + { return (__b < __a); } + + template<typename _Tp> + inline bool + operator>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept + { return std::less<_Tp*>()(nullptr, __a.get()); } + + template<typename _Tp> + inline bool + operator>(nullptr_t, const shared_ptr<_Tp>& __a) noexcept + { return std::less<_Tp*>()(__a.get(), nullptr); } + + template<typename _Tp1, typename _Tp2> + inline bool + operator>=(const shared_ptr<_Tp1>& __a, + const shared_ptr<_Tp2>& __b) noexcept + { return !(__a < __b); } + + template<typename _Tp> + inline bool + operator>=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept + { return !(__a < nullptr); } + + template<typename _Tp> + inline bool + operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept + { return !(nullptr < __a); } + + template<typename _Tp> struct less<shared_ptr<_Tp>> : public _Sp_less<shared_ptr<_Tp>> { }; Index: include/bits/unique_ptr.h =================================================================== --- include/bits/unique_ptr.h (revision 171282) +++ include/bits/unique_ptr.h (working copy) @@ -435,59 +435,108 @@ template<typename _Tp, typename _Dp> inline bool - operator==(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) - { return __x.get() == nullptr; } + operator==(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept + { return !__x; } template<typename _Tp, typename _Dp> inline bool - operator==(nullptr_t, const unique_ptr<_Tp, _Dp>& __y) - { return nullptr == __y.get(); } + operator==(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept + { return !__x; } template<typename _Tp, typename _Dp, typename _Up, typename _Ep> inline bool operator!=(const unique_ptr<_Tp, _Dp>& __x, const unique_ptr<_Up, _Ep>& __y) - { return !(__x.get() == __y.get()); } + { return __x.get() != __y.get(); } template<typename _Tp, typename _Dp> inline bool - operator!=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) - { return __x.get() != nullptr; } + operator!=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept + { return (bool)__x; } template<typename _Tp, typename _Dp> inline bool - operator!=(nullptr_t, const unique_ptr<_Tp, _Dp>& __y) - { return nullptr != __y.get(); } + operator!=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept + { return (bool)__x; } template<typename _Tp, typename _Dp, typename _Up, typename _Ep> inline bool operator<(const unique_ptr<_Tp, _Dp>& __x, const unique_ptr<_Up, _Ep>& __y) - { return __x.get() < __y.get(); } + { + typedef typename + std::common_type<typename unique_ptr<_Tp, _Dp>::pointer, + typename unique_ptr<_Up, _Ep>::pointer>::type _CT; + return std::less<_CT>()(__x.get(), __y.get()); + } + template<typename _Tp, typename _Dp> + inline bool + operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) + { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(), + nullptr); } + + template<typename _Tp, typename _Dp> + inline bool + operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) + { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr, + __x.get()); } + template<typename _Tp, typename _Dp, typename _Up, typename _Ep> inline bool operator<=(const unique_ptr<_Tp, _Dp>& __x, const unique_ptr<_Up, _Ep>& __y) - { return !(__y.get() < __x.get()); } + { return !(__y < __x); } + template<typename _Tp, typename _Dp> + inline bool + operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) + { return !(nullptr < __x); } + + template<typename _Tp, typename _Dp> + inline bool + operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) + { return !(__x < nullptr); } + template<typename _Tp, typename _Dp, typename _Up, typename _Ep> inline bool operator>(const unique_ptr<_Tp, _Dp>& __x, const unique_ptr<_Up, _Ep>& __y) - { return __y.get() < __x.get(); } + { return (__y < __x); } + template<typename _Tp, typename _Dp> + inline bool + operator>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) + { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr, + __x.get()); } + + template<typename _Tp, typename _Dp> + inline bool + operator>(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) + { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(), + nullptr); } + template<typename _Tp, typename _Dp, typename _Up, typename _Ep> inline bool operator>=(const unique_ptr<_Tp, _Dp>& __x, const unique_ptr<_Up, _Ep>& __y) - { return !(__x.get() < __y.get()); } + { return !(__x < __y); } + template<typename _Tp, typename _Dp> + inline bool + operator>=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) + { return !(__x < nullptr); } + + template<typename _Tp, typename _Dp> + inline bool + operator>=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) + { return !(nullptr < __x); } + /// std::hash specialization for unique_ptr. template<typename _Tp, typename _Dp> struct hash<unique_ptr<_Tp, _Dp>> Index: include/bits/shared_ptr_base.h =================================================================== --- include/bits/shared_ptr_base.h (revision 171282) +++ include/bits/shared_ptr_base.h (working copy) @@ -1051,41 +1051,102 @@ template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> inline bool operator==(const __shared_ptr<_Tp1, _Lp>& __a, - const __shared_ptr<_Tp2, _Lp>& __b) + const __shared_ptr<_Tp2, _Lp>& __b) noexcept { return __a.get() == __b.get(); } template<typename _Tp, _Lock_policy _Lp> inline bool - operator==(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) - { return __a.get() == nullptr; } + operator==(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept + { return !__a; } template<typename _Tp, _Lock_policy _Lp> inline bool - operator==(nullptr_t, const __shared_ptr<_Tp, _Lp>& __b) - { return nullptr == __b.get(); } + operator==(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept + { return !__a; } template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> inline bool operator!=(const __shared_ptr<_Tp1, _Lp>& __a, - const __shared_ptr<_Tp2, _Lp>& __b) + const __shared_ptr<_Tp2, _Lp>& __b) noexcept { return __a.get() != __b.get(); } template<typename _Tp, _Lock_policy _Lp> inline bool - operator!=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) - { return __a.get() != nullptr; } + operator!=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept + { return (bool)__a; } template<typename _Tp, _Lock_policy _Lp> inline bool - operator!=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __b) - { return nullptr != __b.get(); } + operator!=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept + { return (bool)__a; } template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> inline bool operator<(const __shared_ptr<_Tp1, _Lp>& __a, - const __shared_ptr<_Tp2, _Lp>& __b) - { return __a.get() < __b.get(); } + const __shared_ptr<_Tp2, _Lp>& __b) noexcept + { + typedef typename std::common_type<_Tp1*, _Tp2*>::type _CT; + return std::less<_CT>()(__a.get(), __b.get()); + } + template<typename _Tp, _Lock_policy _Lp> + inline bool + operator<(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept + { return std::less<_Tp*>()(__a.get(), nullptr); } + + template<typename _Tp, _Lock_policy _Lp> + inline bool + operator<(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept + { return std::less<_Tp*>()(nullptr, __a.get()); } + + template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> + inline bool + operator<=(const __shared_ptr<_Tp1, _Lp>& __a, + const __shared_ptr<_Tp2, _Lp>& __b) noexcept + { return !(__b < __a); } + + template<typename _Tp, _Lock_policy _Lp> + inline bool + operator<=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept + { return !(nullptr < __a); } + + template<typename _Tp, _Lock_policy _Lp> + inline bool + operator<=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept + { return !(__a < nullptr); } + + template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> + inline bool + operator>(const __shared_ptr<_Tp1, _Lp>& __a, + const __shared_ptr<_Tp2, _Lp>& __b) noexcept + { return (__b < __a); } + + template<typename _Tp, _Lock_policy _Lp> + inline bool + operator>(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept + { return std::less<_Tp*>()(nullptr, __a.get()); } + + template<typename _Tp, _Lock_policy _Lp> + inline bool + operator>(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept + { return std::less<_Tp*>()(__a.get(), nullptr); } + + template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> + inline bool + operator>=(const __shared_ptr<_Tp1, _Lp>& __a, + const __shared_ptr<_Tp2, _Lp>& __b) noexcept + { return !(__a < __b); } + + template<typename _Tp, _Lock_policy _Lp> + inline bool + operator>=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept + { return !(__a < nullptr); } + + template<typename _Tp, _Lock_policy _Lp> + inline bool + operator>=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept + { return !(nullptr < __a); } + template<typename _Sp> struct _Sp_less : public binary_function<_Sp, _Sp, bool> { Index: testsuite/20_util/shared_ptr/comparison/dr1401.cc =================================================================== --- testsuite/20_util/shared_ptr/comparison/dr1401.cc (revision 0) +++ testsuite/20_util/shared_ptr/comparison/dr1401.cc (revision 0) @@ -0,0 +1,65 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do compile } + +// Copyright (C) 2011 Free Software Foundation +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// 20.7.2.2 Class template shared_ptr [util.smartptr.shared] + +#include <memory> + +// DR 1401 +void test01() +{ + std::shared_ptr<int> ptr1, ptr2; + if (ptr1 == ptr2) + { } + if (ptr1 == nullptr) + { } + if (nullptr == ptr1) + { } + if (ptr1 != ptr2) + { } + if (ptr1 != nullptr) + { } + if (nullptr != ptr1) + { } + if (ptr1 < ptr2) + { } + if (ptr1 < nullptr) + { } + if (nullptr < ptr1) + { } + if (ptr1 <= ptr2) + { } + if (ptr1 <= nullptr) + { } + if (nullptr <= ptr1) + { } + if (ptr1 > ptr2) + { } + if (ptr1 > nullptr) + { } + if (nullptr > ptr1) + { } + if (ptr1 >= ptr2) + { } + if (ptr1 >= nullptr) + { } + if (nullptr >= ptr1) + { } +} Index: testsuite/20_util/unique_ptr/comparison/dr1401.cc =================================================================== --- testsuite/20_util/unique_ptr/comparison/dr1401.cc (revision 0) +++ testsuite/20_util/unique_ptr/comparison/dr1401.cc (revision 0) @@ -0,0 +1,65 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do compile } + +// Copyright (C) 2011 Free Software Foundation +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// 20.7.1 Class template unique_ptr [unique.ptr] + +#include <memory> + +// DR 1401 +void test01() +{ + std::unique_ptr<int> ptr1, ptr2; + if (ptr1 == ptr2) + { } + if (ptr1 == nullptr) + { } + if (nullptr == ptr1) + { } + if (ptr1 != ptr2) + { } + if (ptr1 != nullptr) + { } + if (nullptr != ptr1) + { } + if (ptr1 < ptr2) + { } + if (ptr1 < nullptr) + { } + if (nullptr < ptr1) + { } + if (ptr1 <= ptr2) + { } + if (ptr1 <= nullptr) + { } + if (nullptr <= ptr1) + { } + if (ptr1 > ptr2) + { } + if (ptr1 > nullptr) + { } + if (nullptr > ptr1) + { } + if (ptr1 >= ptr2) + { } + if (ptr1 >= nullptr) + { } + if (nullptr >= ptr1) + { } +} Index: testsuite/20_util/weak_ptr/comparison/cmp_neg.cc =================================================================== --- testsuite/20_util/weak_ptr/comparison/cmp_neg.cc (revision 171282) +++ testsuite/20_util/weak_ptr/comparison/cmp_neg.cc (working copy) @@ -42,12 +42,18 @@ return 0; } -// { dg-warning "note" "" { target *-*-* } 354 } +// { dg-warning "note" "" { target *-*-* } 370 } +// { dg-warning "note" "" { target *-*-* } 365 } +// { dg-warning "note" "" { target *-*-* } 357 } +// { dg-warning "note" "" { target *-*-* } 1099 } +// { dg-warning "note" "" { target *-*-* } 1094 } // { dg-warning "note" "" { target *-*-* } 1086 } +// { dg-warning "note" "" { target *-*-* } 483 } +// { dg-warning "note" "" { target *-*-* } 477 } // { dg-warning "note" "" { target *-*-* } 467 } // { dg-warning "note" "" { target *-*-* } 587 } +// { dg-warning "note" "" { target *-*-* } 1056 } // { dg-warning "note" "" { target *-*-* } 1050 } -// { dg-warning "note" "" { target *-*-* } 1056 } // { dg-warning "note" "" { target *-*-* } 342 } // { dg-warning "note" "" { target *-*-* } 292 } // { dg-warning "note" "" { target *-*-* } 207 }