This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[v3] Unique_ptr tweaks
- From: Paolo Carlini <paolo dot carlini at oracle dot com>
- To: Gcc Patch List <gcc-patches at gcc dot gnu dot org>
- Cc: libstdc++ <libstdc++ at gcc dot gnu dot org>
- Date: Sun, 28 Sep 2008 17:48:57 +0200
- Subject: [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" }