This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[v3] Unique_ptr tweaks


Hi,

tested x86_64-linux, committed to mainline.

Paolo.

///////////////////////
2008-09-28  Paolo Carlini  <paolo.carlini@oracle.com>

	* include/bits/unique_ptr.h (unique_ptr<_Tp[]>::template<typename U>
	void reset(U)): Add as deleted function, per DR 821 [Ready].
	* include/bits/unique_ptr.h: Prefer everywhere deleted to private
	member function declarations; minor formatting tweaks.
	* testsuite/20_util/unique_ptr/modifiers/reset_neg.cc: New.
	* testsuite/20_util/unique_ptr/assign/assign.cc: Adjust DejaGNU
	directives.
Index: include/bits/unique_ptr.h
===================================================================
*** include/bits/unique_ptr.h	(revision 140731)
--- include/bits/unique_ptr.h	(working copy)
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 84,98 ****
    template <typename _Tp, typename _Tp_Deleter = default_delete<_Tp> > 
      class unique_ptr
      {
!       typedef _Tp* pointer;
!       typedef unique_ptr<_Tp, _Tp_Deleter> __this_type;
!       typedef std::tuple<pointer, _Tp_Deleter> __tuple_type;
!       typedef __tuple_type __this_type::* __unspecified_bool_type;
!       typedef pointer __this_type::* __unspecified_pointer_type;
  
      public:
!       typedef _Tp         element_type;      
!       typedef _Tp_Deleter deleter_type;
  
        // constructors
        unique_ptr()
--- 84,98 ----
    template <typename _Tp, typename _Tp_Deleter = default_delete<_Tp> > 
      class unique_ptr
      {
!       typedef unique_ptr<_Tp, _Tp_Deleter>   __this_type;
!       typedef std::tuple<_Tp*, _Tp_Deleter>  __tuple_type;
!       typedef __tuple_type __this_type::*    __unspecified_bool_type;
!       typedef _Tp* __this_type::*            __unspecified_pointer_type;
  
      public:
!       typedef _Tp*                    pointer;
!       typedef _Tp                element_type;      
!       typedef _Tp_Deleter        deleter_type;
  
        // constructors
        unique_ptr()
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 195,201 ****
        }
  
        void
!       reset(pointer __p = 0) 
        {
  	if (__p != get())
  	  {
--- 195,201 ----
        }
  
        void
!       reset(pointer __p = pointer())
        {
  	if (__p != get())
  	  {
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 206,228 ****
  
        void
        swap(unique_ptr&& __u)
!       { using std::swap;
  	swap(_M_t, __u._M_t);
        }
  
-     private: 
        // disable copy from lvalue
!       unique_ptr(const unique_ptr&);
  
        template<typename _Up, typename _Up_Deleter> 
!         unique_ptr(const unique_ptr<_Up, _Up_Deleter>&);
!       
!       // disable assignment from lvalue
!       unique_ptr& operator=(const unique_ptr&);
  
        template<typename _Up, typename _Up_Deleter> 
!         unique_ptr& operator=(const unique_ptr<_Up, _Up_Deleter>&);
!       
      private:
        __tuple_type _M_t;
    };
--- 206,227 ----
  
        void
        swap(unique_ptr&& __u)
!       {
! 	using std::swap;
  	swap(_M_t, __u._M_t);
        }
  
        // disable copy from lvalue
!       unique_ptr(const unique_ptr&) = delete;
  
        template<typename _Up, typename _Up_Deleter> 
!         unique_ptr(const unique_ptr<_Up, _Up_Deleter>&) = delete;
! 
!       unique_ptr& operator=(const unique_ptr&) = delete;
  
        template<typename _Up, typename _Up_Deleter> 
!         unique_ptr& operator=(const unique_ptr<_Up, _Up_Deleter>&) = delete;
! 
      private:
        __tuple_type _M_t;
    };
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 234,248 ****
    template<typename _Tp, typename _Tp_Deleter> 
      class unique_ptr<_Tp[], _Tp_Deleter>
      {
!       typedef _Tp* pointer;
!       typedef unique_ptr<_Tp[], _Tp_Deleter> __this_type;
!       typedef std::tuple<pointer, _Tp_Deleter> __tuple_type;
!       typedef __tuple_type __this_type::* __unspecified_bool_type;
!       typedef pointer __this_type::* __unspecified_pointer_type;
      public:
!       typedef _Tp         element_type;      
!       typedef _Tp_Deleter deleter_type;
!     
        // constructors
        unique_ptr()
        : _M_t(pointer(), deleter_type())
--- 233,248 ----
    template<typename _Tp, typename _Tp_Deleter> 
      class unique_ptr<_Tp[], _Tp_Deleter>
      {
!       typedef unique_ptr<_Tp[], _Tp_Deleter>  __this_type;
!       typedef std::tuple<_Tp*, _Tp_Deleter>   __tuple_type;
!       typedef __tuple_type __this_type::*     __unspecified_bool_type;
!       typedef _Tp* __this_type::*             __unspecified_pointer_type;
! 
      public:
!       typedef _Tp*                    pointer;
!       typedef _Tp                element_type;      
!       typedef _Tp_Deleter        deleter_type;
! 
        // constructors
        unique_ptr()
        : _M_t(pointer(), deleter_type())
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 338,344 ****
        }
  
        void
!       reset(pointer __p = 0) 
        {
  	if (__p != get())
  	{
--- 338,344 ----
        }
  
        void
!       reset(pointer __p = pointer()) 
        {
  	if (__p != get())
  	{
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 347,352 ****
--- 347,356 ----
  	}
        }
  
+       // DR 821.
+       template<typename _Up>
+         void reset(_Up) = delete;
+ 
        void
        swap(unique_ptr&& __u)
        {
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 354,419 ****
  	swap(_M_t, __u._M_t);
        }
  
-     private:
        // disable copy from lvalue
!       unique_ptr(const unique_ptr&);
!       unique_ptr& operator=(const unique_ptr&);
  
        // disable construction from convertible pointer types
        // (N2315 - 20.6.5.3.1)
!       template<typename _Up> unique_ptr(_Up*,
!         typename std::conditional<std::is_reference<deleter_type>::value, 
!           deleter_type, const deleter_type&>::type,
!             typename std::enable_if<std::is_convertible<_Up*, 
!                 pointer>::value>::type* = 0);
! 
!       template<typename _Up> unique_ptr(_Up*,
!         typename std::remove_reference<deleter_type>::type&&,
!           typename std::enable_if<std::is_convertible<_Up*, 
!               pointer>::value>::type* = 0);
! 
!       template<typename _Up> explicit unique_ptr(_Up*,
!         typename std::enable_if<std::is_convertible<_Up*, 
!             pointer>::value>::type* = 0);
  
-       // disable reset with convertible pointer types (N2315 - 20.6.5.3.3) 
        template<typename _Up>
!         typename std::enable_if<std::is_convertible<_Up*,
!           pointer>::value>::type reset(_Up*);
!           
      private:
        __tuple_type _M_t;
    };
    
    template<typename _Tp, typename _Tp_Deleter> 
      inline void
!     swap(unique_ptr<_Tp, _Tp_Deleter>& __x, 
! 	 unique_ptr<_Tp, _Tp_Deleter>& __y) 
      { __x.swap(__y); }
  
    template<typename _Tp, typename _Tp_Deleter> 
      inline void
!     swap(unique_ptr<_Tp, _Tp_Deleter>&& __x, 
  	 unique_ptr<_Tp, _Tp_Deleter>& __y)
      { __x.swap(__y); }
  
    template<typename _Tp, typename _Tp_Deleter> 
      inline void
!     swap(unique_ptr<_Tp, _Tp_Deleter>& __x, 
  	 unique_ptr<_Tp, _Tp_Deleter>&& __y)
      { __x.swap(__y); }
    
    template<typename _Tp, typename _Tp_Deleter,
  	   typename _Up, typename _Up_Deleter>
      inline bool
!     operator==(const unique_ptr<_Tp, _Tp_Deleter>& __x, 
  	       const unique_ptr<_Up, _Up_Deleter>& __y)
      { return __x.get() == __y.get(); }
  
    template<typename _Tp, typename _Tp_Deleter,
  	   typename _Up, typename _Up_Deleter>
      inline bool
!     operator!=(const unique_ptr<_Tp, _Tp_Deleter>& __x, 
  	       const unique_ptr<_Up, _Up_Deleter>& __y)
      { return !(__x.get() == __y.get()); }
  
--- 358,419 ----
  	swap(_M_t, __u._M_t);
        }
  
        // disable copy from lvalue
!       unique_ptr(const unique_ptr&) = delete;
!       unique_ptr& operator=(const unique_ptr&) = delete;
  
        // disable construction from convertible pointer types
        // (N2315 - 20.6.5.3.1)
!       template<typename _Up>
!         unique_ptr(_Up*, typename
! 		   std::conditional<std::is_reference<deleter_type>::value,
! 		   deleter_type, const deleter_type&>::type,
! 		   typename std::enable_if<std::is_convertible<_Up*, 
! 		   pointer>::value>::type* = 0) = delete;
  
        template<typename _Up>
!         unique_ptr(_Up*, typename std::remove_reference<deleter_type>::type&&,
! 		   typename std::enable_if<std::is_convertible<_Up*, 
! 		   pointer>::value>::type* = 0) = delete;
! 
!       template<typename _Up>
!         explicit
!         unique_ptr(_Up*, typename std::enable_if<std::is_convertible<_Up*, 
! 		   pointer>::value>::type* = 0) = delete;
! 
      private:
        __tuple_type _M_t;
    };
    
    template<typename _Tp, typename _Tp_Deleter> 
      inline void
!     swap(unique_ptr<_Tp, _Tp_Deleter>& __x,
! 	 unique_ptr<_Tp, _Tp_Deleter>& __y)
      { __x.swap(__y); }
  
    template<typename _Tp, typename _Tp_Deleter> 
      inline void
!     swap(unique_ptr<_Tp, _Tp_Deleter>&& __x,
  	 unique_ptr<_Tp, _Tp_Deleter>& __y)
      { __x.swap(__y); }
  
    template<typename _Tp, typename _Tp_Deleter> 
      inline void
!     swap(unique_ptr<_Tp, _Tp_Deleter>& __x,
  	 unique_ptr<_Tp, _Tp_Deleter>&& __y)
      { __x.swap(__y); }
    
    template<typename _Tp, typename _Tp_Deleter,
  	   typename _Up, typename _Up_Deleter>
      inline bool
!     operator==(const unique_ptr<_Tp, _Tp_Deleter>& __x,
  	       const unique_ptr<_Up, _Up_Deleter>& __y)
      { return __x.get() == __y.get(); }
  
    template<typename _Tp, typename _Tp_Deleter,
  	   typename _Up, typename _Up_Deleter>
      inline bool
!     operator!=(const unique_ptr<_Tp, _Tp_Deleter>& __x,
  	       const unique_ptr<_Up, _Up_Deleter>& __y)
      { return !(__x.get() == __y.get()); }
  
Index: testsuite/20_util/unique_ptr/modifiers/reset_neg.cc
===================================================================
*** testsuite/20_util/unique_ptr/modifiers/reset_neg.cc	(revision 0)
--- testsuite/20_util/unique_ptr/modifiers/reset_neg.cc	(revision 0)
***************
*** 0 ****
--- 1,40 ----
+ // { dg-do compile }
+ // { dg-options "-std=gnu++0x" }
+ 
+ // Copyright (C) 2008 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 2, 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 COPYING.  If not, write to the Free
+ // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ // USA.
+ 
+ #include <memory>
+ 
+ struct A
+ {
+ };
+ 
+ struct B : A
+ {
+   virtual ~B() { }
+ };
+ 
+ void test01()
+ {
+   std::unique_ptr<B[]> up;
+   up.reset(new A[3]);
+ }
+ 
+ // { dg-error "used here" "" { target *-*-* } 36 } 
+ // { dg-error "deleted function" "" { target *-*-* } 352 }
Index: testsuite/20_util/unique_ptr/assign/assign.cc
===================================================================
*** testsuite/20_util/unique_ptr/assign/assign.cc	(revision 140731)
--- testsuite/20_util/unique_ptr/assign/assign.cc	(working copy)
*************** void
*** 40,52 ****
  test02()
  {
    std::unique_ptr<int[]> p1(new int(420));
!   std::unique_ptr<int[]> p2 = p1; // { dg-error "within this context" }
  }
  
  void
  test03()
  {
    std::unique_ptr<int[2]> p1(new int[3]);
!   std::unique_ptr<int[2]> p2 = p1; // { dg-error "within this context" }
  }
! // { dg-excess-errors "is private" }
--- 40,59 ----
  test02()
  {
    std::unique_ptr<int[]> p1(new int(420));
!   std::unique_ptr<int[]> p2 = p1;
  }
  
  void
  test03()
  {
    std::unique_ptr<int[2]> p1(new int[3]);
!   std::unique_ptr<int[2]> p2 = p1;
  }
! 
! // { dg-error "used here" "" { target *-*-* } 43 }
! // { dg-error "no matching" "" { target *-*-* } 49 }
! // { dg-error "used here" "" { target *-*-* } 50 }
! // { dg-error "candidates are" "" { target *-*-* } 215 }
! // { dg-error "deleted function" "" { target *-*-* } 215 }
! // { dg-error "deleted function" "" { target *-*-* } 362 }
! // { dg-excess-errors "note" }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]