shared_ptr.h (operator>, [...]): Add, per DR 1401.
[gcc.git] / libstdc++-v3 / include / bits / unique_ptr.h
index ff1a9251dbcc48d8dbd44e980278f18b9151a8a2..1afc75bcb3f14dbfedc6a5e2b7a3b1ceea01334c 100644 (file)
@@ -1,6 +1,6 @@
 // unique_ptr implementation -*- C++ -*-
 
-// Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+// Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
 //
 // 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
@@ -22,9 +22,9 @@
 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 // <http://www.gnu.org/licenses/>.
 
-/** @file unique_ptr.h
+/** @file bits/unique_ptr.h
  *  This is an internal header file, included by other library headers.
- *  You should not attempt to use it directly.
+ *  Do not attempt to use it directly. @headername{memory}
  */
 
 #ifndef _UNIQUE_PTR_H
@@ -36,7 +36,9 @@
 #include <utility>
 #include <tuple>
 
-_GLIBCXX_BEGIN_NAMESPACE(std)
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   /**
    * @addtogroup pointer_abstractions
@@ -47,7 +49,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
   template<typename _Tp>
     struct default_delete
     {
-      constexpr default_delete() { }
+      constexpr default_delete() = default;
 
       template<typename _Up, typename = typename
               std::enable_if<std::is_convertible<_Up*, _Tp*>::value>::type>
@@ -68,7 +70,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
   template<typename _Tp>
     struct default_delete<_Tp[]>
     {
-      constexpr default_delete() { }
+      constexpr default_delete() = default;
 
       void
       operator()(_Tp* __ptr) const
@@ -109,7 +111,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
       // Constructors.
       constexpr unique_ptr()
       : _M_t()
-      { }
+      { static_assert(!std::is_pointer<deleter_type>::value,
+                    "constructed with null function pointer deleter"); }
 
       explicit
       unique_ptr(pointer __p)
@@ -130,7 +133,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
 
       constexpr unique_ptr(nullptr_t)
       : _M_t()
-      { }
+      { static_assert(!std::is_pointer<deleter_type>::value,
+                    "constructed with null function pointer deleter"); }
 
       // Move constructors.
       unique_ptr(unique_ptr&& __u)
@@ -150,7 +154,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
        : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter()))
        { }
 
-#if _GLIBCXX_DEPRECATED
+#if _GLIBCXX_USE_DEPRECATED
       template<typename _Up, typename = typename
        std::enable_if<std::is_convertible<_Up*, _Tp*>::value
                       && std::is_same<_Dp,
@@ -269,7 +273,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
       // Constructors.
       constexpr unique_ptr()
       : _M_t()
-      { }
+      { static_assert(!std::is_pointer<deleter_type>::value,
+                    "constructed with null function pointer deleter"); }
 
       explicit
       unique_ptr(pointer __p)
@@ -288,10 +293,10 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
       { static_assert(!std::is_reference<deleter_type>::value,
                      "rvalue deleter bound to reference"); }
 
-      /* TODO: use delegating constructor */
       constexpr unique_ptr(nullptr_t)
       : _M_t()
-      { }
+      { static_assert(!std::is_pointer<deleter_type>::value,
+                    "constructed with null function pointer deleter"); }
 
       // Move constructors.
       unique_ptr(unique_ptr&& __u)
@@ -430,58 +435,107 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
 
   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>
@@ -498,6 +552,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
 
   // @} group pointer_abstractions
 
-_GLIBCXX_END_NAMESPACE
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
 
 #endif /* _UNIQUE_PTR_H */