From 23df853421a9517038d778f41d41e4b4bc2035ee Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Thu, 20 Dec 2012 21:02:33 +0000 Subject: [PATCH] functional (_Require): Move to ... * include/std/functional (_Require): Move to ... * include/std/type_traits (_Require): ... here. * include/bits/shared_ptr_base.h (__shared_count::_S_create_from_up): Handle unique_ptr for arrays or with custom pointer types. (__shared_ptr::__shared_ptr(unique_ptr<_Tp1, _Del>&&): Likewise. * include/bits/unique_ptr.h (unique_ptr<_Tp[], _Dp>): Use _Dp::pointer if defined. Implement proposed resolution of LWG 2118. * testsuite/20_util/shared_ptr/cons/unique_ptr_array.cc: New. * testsuite/20_util/unique_ptr/assign/cv_qual.cc: New. * testsuite/20_util/unique_ptr/cons/array_convertible_neg.cc: New. * testsuite/20_util/unique_ptr/cons/convertible_neg.cc: New. * testsuite/20_util/unique_ptr/cons/cv_qual.cc: New. * testsuite/20_util/unique_ptr/modifiers/cv_qual.cc: New. * testsuite/20_util/unique_ptr/requirements/pointer_type_array.cc: New. * testsuite/20_util/shared_ptr/cons/unique_ptr.cc: Adjust comments. * testsuite/20_util/unique_ptr/cons/pointer_array_convertible_neg.cc: Likewise. * testsuite/20_util/unique_ptr/requirements/pointer_type.cc: Likewise. * testsuite/20_util/bind/ref_neg.cc: Adjust dg-error line number. * testsuite/20_util/declval/requirements/1_neg.cc: Likewise. * testsuite/20_util/default_delete/48631_neg.cc: Likewise. * testsuite/20_util/shared_ptr/cons/43820_neg.cc: Likewise. * testsuite/20_util/unique_ptr/assign/48635_neg.cc: Likewise. * testsuite/20_util/unique_ptr/modifiers/reset_neg.cc: Adjust dg-error text. * testsuite/20_util/unique_ptr/cons/ptr_deleter_neg.cc: Use different instantiations so static_assert fails for each. From-SVN: r194651 --- libstdc++-v3/ChangeLog | 30 +++ libstdc++-v3/include/bits/shared_ptr_base.h | 8 +- libstdc++-v3/include/bits/unique_ptr.h | 194 +++++++++++------- libstdc++-v3/include/std/functional | 3 - libstdc++-v3/include/std/type_traits | 2 + .../testsuite/20_util/bind/ref_neg.cc | 8 +- .../20_util/declval/requirements/1_neg.cc | 2 +- .../20_util/default_delete/48631_neg.cc | 2 +- .../20_util/shared_ptr/cons/43820_neg.cc | 2 +- .../20_util/shared_ptr/cons/unique_ptr.cc | 8 +- .../shared_ptr/cons/unique_ptr_array.cc | 59 ++++++ .../20_util/unique_ptr/assign/48635_neg.cc | 4 +- .../20_util/unique_ptr/assign/cv_qual.cc | 89 ++++++++ .../unique_ptr/cons/array_convertible_neg.cc | 58 ++++++ .../unique_ptr/cons/convertible_neg.cc | 38 ++++ .../20_util/unique_ptr/cons/cv_qual.cc | 115 +++++++++++ .../cons/pointer_array_convertible_neg.cc | 6 +- .../unique_ptr/cons/ptr_deleter_neg.cc | 13 +- .../20_util/unique_ptr/modifiers/cv_qual.cc | 79 +++++++ .../20_util/unique_ptr/modifiers/reset_neg.cc | 4 +- .../unique_ptr/requirements/pointer_type.cc | 7 +- .../requirements/pointer_type_array.cc | 49 +++++ 22 files changed, 668 insertions(+), 112 deletions(-) create mode 100644 libstdc++-v3/testsuite/20_util/shared_ptr/cons/unique_ptr_array.cc create mode 100644 libstdc++-v3/testsuite/20_util/unique_ptr/assign/cv_qual.cc create mode 100644 libstdc++-v3/testsuite/20_util/unique_ptr/cons/array_convertible_neg.cc create mode 100644 libstdc++-v3/testsuite/20_util/unique_ptr/cons/convertible_neg.cc create mode 100644 libstdc++-v3/testsuite/20_util/unique_ptr/cons/cv_qual.cc create mode 100644 libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/cv_qual.cc create mode 100644 libstdc++-v3/testsuite/20_util/unique_ptr/requirements/pointer_type_array.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 41649b7c7e3..07caf0a4e33 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,33 @@ +2012-12-20 Jonathan Wakely + + * include/std/functional (_Require): Move to ... + * include/std/type_traits (_Require): ... here. + * include/bits/shared_ptr_base.h (__shared_count::_S_create_from_up): + Handle unique_ptr for arrays or with custom pointer types. + (__shared_ptr::__shared_ptr(unique_ptr<_Tp1, _Del>&&): Likewise. + * include/bits/unique_ptr.h (unique_ptr<_Tp[], _Dp>): Use + _Dp::pointer if defined. Implement proposed resolution of LWG 2118. + * testsuite/20_util/shared_ptr/cons/unique_ptr_array.cc: New. + * testsuite/20_util/unique_ptr/assign/cv_qual.cc: New. + * testsuite/20_util/unique_ptr/cons/array_convertible_neg.cc: New. + * testsuite/20_util/unique_ptr/cons/convertible_neg.cc: New. + * testsuite/20_util/unique_ptr/cons/cv_qual.cc: New. + * testsuite/20_util/unique_ptr/modifiers/cv_qual.cc: New. + * testsuite/20_util/unique_ptr/requirements/pointer_type_array.cc: New. + * testsuite/20_util/shared_ptr/cons/unique_ptr.cc: Adjust comments. + * testsuite/20_util/unique_ptr/cons/pointer_array_convertible_neg.cc: + Likewise. + * testsuite/20_util/unique_ptr/requirements/pointer_type.cc: Likewise. + * testsuite/20_util/bind/ref_neg.cc: Adjust dg-error line number. + * testsuite/20_util/declval/requirements/1_neg.cc: Likewise. + * testsuite/20_util/default_delete/48631_neg.cc: Likewise. + * testsuite/20_util/shared_ptr/cons/43820_neg.cc: Likewise. + * testsuite/20_util/unique_ptr/assign/48635_neg.cc: Likewise. + * testsuite/20_util/unique_ptr/modifiers/reset_neg.cc: Adjust + dg-error text. + * testsuite/20_util/unique_ptr/cons/ptr_deleter_neg.cc: Use + different instantiations so static_assert fails for each. + 2012-12-20 Jonathan Wakely PR libstdc++/55741 diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h index ead37284aa1..9d9fecb48fe 100644 --- a/libstdc++-v3/include/bits/shared_ptr_base.h +++ b/libstdc++-v3/include/bits/shared_ptr_base.h @@ -616,7 +616,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _S_create_from_up(std::unique_ptr<_Tp, _Del>&& __r, typename std::enable_if::value>::type* = 0) { - return new _Sp_counted_deleter<_Tp*, _Del, std::allocator, + typedef typename unique_ptr<_Tp, _Del>::pointer _Ptr; + return new _Sp_counted_deleter<_Ptr, _Del, std::allocator, _Lp>(__r.get(), __r.get_deleter()); } @@ -625,9 +626,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _S_create_from_up(std::unique_ptr<_Tp, _Del>&& __r, typename std::enable_if::value>::type* = 0) { + typedef typename unique_ptr<_Tp, _Del>::pointer _Ptr; typedef typename std::remove_reference<_Del>::type _Del1; typedef std::reference_wrapper<_Del1> _Del2; - return new _Sp_counted_deleter<_Tp*, _Del2, std::allocator, + return new _Sp_counted_deleter<_Ptr, _Del2, std::allocator, _Lp>(__r.get(), std::ref(__r.get_deleter())); } @@ -846,7 +848,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : _M_ptr(__r.get()), _M_refcount() { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) - _Tp1* __tmp = __r.get(); + auto __tmp = std::__addressof(*__r.get()); _M_refcount = __shared_count<_Lp>(std::move(__r)); __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp); } diff --git a/libstdc++-v3/include/bits/unique_ptr.h b/libstdc++-v3/include/bits/unique_ptr.h index 37eae257232..e17a4dc33c2 100644 --- a/libstdc++-v3/include/bits/unique_ptr.h +++ b/libstdc++-v3/include/bits/unique_ptr.h @@ -56,7 +56,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr default_delete() noexcept = default; template::value>::type> + enable_if::value>::type> default_delete(const default_delete<_Up>&) noexcept { } void @@ -74,8 +74,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template struct default_delete<_Tp[]> { + private: + template + using __remove_cv = typename remove_cv<_Up>::type; + + // Like is_base_of<_Tp, _Up> but false if unqualified types are the same + template + using __is_derived_Tp + = __and_< is_base_of<_Tp, _Up>, + __not_, __remove_cv<_Up>>> >; + + public: constexpr default_delete() noexcept = default; + template::value>::type> + default_delete(const default_delete<_Up[]>&) noexcept { } + void operator()(_Tp* __ptr) const { @@ -84,7 +99,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION delete [] __ptr; } - template void operator()(_Up*) const = delete; + template + typename enable_if<__is_derived_Tp<_Up>::value>::type + operator()(_Up*) const = delete; }; /// 20.7.1.2 unique_ptr for single objects. @@ -103,7 +120,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef typename remove_reference<_Dp>::type _Del; public: - typedef decltype( __test<_Del>(0)) type; + typedef decltype(__test<_Del>(0)) type; }; typedef std::tuple __tuple_type; @@ -117,54 +134,45 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Constructors. constexpr unique_ptr() noexcept : _M_t() - { static_assert(!std::is_pointer::value, + { static_assert(!is_pointer::value, "constructed with null function pointer deleter"); } explicit unique_ptr(pointer __p) noexcept : _M_t(__p, deleter_type()) - { static_assert(!std::is_pointer::value, + { static_assert(!is_pointer::value, "constructed with null function pointer deleter"); } unique_ptr(pointer __p, - typename std::conditional::value, + typename conditional::value, deleter_type, const deleter_type&>::type __d) noexcept : _M_t(__p, __d) { } unique_ptr(pointer __p, - typename std::remove_reference::type&& __d) noexcept + typename remove_reference::type&& __d) noexcept : _M_t(std::move(__p), std::move(__d)) { static_assert(!std::is_reference::value, "rvalue deleter bound to reference"); } - constexpr unique_ptr(nullptr_t) noexcept - : _M_t() - { static_assert(!std::is_pointer::value, - "constructed with null function pointer deleter"); } + constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { } // Move constructors. unique_ptr(unique_ptr&& __u) noexcept : _M_t(__u.release(), std::forward(__u.get_deleter())) { } - template::pointer, - pointer>::value - && !std::is_array<_Up>::value - && ((std::is_reference<_Dp>::value - && std::is_same<_Ep, _Dp>::value) - || (!std::is_reference<_Dp>::value - && std::is_convertible<_Ep, _Dp>::value))> - ::type> + template::pointer, pointer>, + __not_>, + typename conditional::value, + is_same<_Ep, _Dp>, + is_convertible<_Ep, _Dp>>::type>> unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter())) { } #if _GLIBCXX_USE_DEPRECATED - template::value - && std::is_same<_Dp, - default_delete<_Tp>>::value>::type> + template, is_same<_Dp, default_delete<_Tp>>>> unique_ptr(auto_ptr<_Up>&& __u) noexcept; #endif @@ -186,12 +194,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return *this; } - template::pointer, - pointer>::value - && !std::is_array<_Up>::value>::type> - unique_ptr& + template + typename enable_if< __and_< + is_convertible::pointer, pointer>, + __not_> + >::value, + unique_ptr&>::type operator=(unique_ptr<_Up, _Ep>&& __u) noexcept { reset(__u.release()); @@ -207,7 +215,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } // Observers. - typename std::add_lvalue_reference::type + typename add_lvalue_reference::type operator*() const { _GLIBCXX_DEBUG_ASSERT(get() != pointer()); @@ -273,11 +281,47 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template class unique_ptr<_Tp[], _Dp> { - typedef std::tuple<_Tp*, _Dp> __tuple_type; - __tuple_type _M_t; + // use SFINAE to determine whether _Del::pointer exists + class _Pointer + { + template + static typename _Up::pointer __test(typename _Up::pointer*); + + template + static _Tp* __test(...); + + typedef typename remove_reference<_Dp>::type _Del; + + public: + typedef decltype(__test<_Del>(0)) type; + }; + + typedef std::tuple __tuple_type; + __tuple_type _M_t; + + template + using __remove_cv = typename remove_cv<_Up>::type; + + // like is_base_of<_Tp, _Up> but false if unqualified types are the same + template + using __is_derived_Tp + = __and_< is_base_of<_Tp, _Up>, + __not_, __remove_cv<_Up>>> >; + + template::pointer> + using __safe_conversion = __and_< + is_convertible<_Up_pointer, _Tp_pointer>, + is_array<_Up>, + __or_<__not_>, + __not_>, + __not_<__is_derived_Tp::type>> + > + >; public: - typedef _Tp* pointer; + typedef typename _Pointer::type pointer; typedef _Tp element_type; typedef _Dp deleter_type; @@ -285,35 +329,42 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr unique_ptr() noexcept : _M_t() { static_assert(!std::is_pointer::value, - "constructed with null function pointer deleter"); } + "constructed with null function pointer deleter"); } explicit unique_ptr(pointer __p) noexcept : _M_t(__p, deleter_type()) - { static_assert(!std::is_pointer::value, - "constructed with null function pointer deleter"); } + { static_assert(!is_pointer::value, + "constructed with null function pointer deleter"); } + + template, + is_convertible<_Up*, pointer>, __is_derived_Tp<_Up>>> + explicit + unique_ptr(_Up* __p) = delete; unique_ptr(pointer __p, - typename std::conditional::value, + typename conditional::value, deleter_type, const deleter_type&>::type __d) noexcept : _M_t(__p, __d) { } unique_ptr(pointer __p, typename - std::remove_reference::type && __d) noexcept + remove_reference::type&& __d) noexcept : _M_t(std::move(__p), std::move(__d)) - { static_assert(!std::is_reference::value, + { static_assert(!is_reference::value, "rvalue deleter bound to reference"); } - constexpr unique_ptr(nullptr_t) noexcept - : _M_t() - { static_assert(!std::is_pointer::value, - "constructed with null function pointer deleter"); } - - // Move constructors. + // Move constructor. unique_ptr(unique_ptr&& __u) noexcept : _M_t(__u.release(), std::forward(__u.get_deleter())) { } - template + constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { } + + template, + typename conditional::value, + is_same<_Ep, _Dp>, + is_convertible<_Ep, _Dp>>::type + >> unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter())) { } @@ -337,7 +388,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template - unique_ptr& + typename + enable_if<__safe_conversion<_Up, _Ep>::value, unique_ptr&>::type operator=(unique_ptr<_Up, _Ep>&& __u) noexcept { reset(__u.release()); @@ -385,7 +437,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } void - reset(pointer __p = pointer()) noexcept + reset() noexcept + { reset(pointer()); } + + void + reset(pointer __p) noexcept { using std::swap; swap(std::get<0>(_M_t), __p); @@ -393,18 +449,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION get_deleter()(__p); } - void - reset(nullptr_t) noexcept - { - pointer __p = get(); - std::get<0>(_M_t) = pointer(); - if (__p != nullptr) - get_deleter()(__p); - } - - // DR 821. - template - void reset(_Up) = delete; + template, + is_convertible<_Up*, pointer>, __is_derived_Tp<_Up>>> + void reset(_Up*) = delete; void swap(unique_ptr& __u) noexcept @@ -418,23 +465,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION unique_ptr& operator=(const unique_ptr&) = delete; // Disable construction from convertible pointer types. - // (N2315 - 20.7.1.3.1) - template + template, + is_convertible<_Up*, pointer>, __is_derived_Tp<_Up>>> unique_ptr(_Up*, typename - std::conditional::value, - deleter_type, const deleter_type&>::type, - typename std::enable_if::value>::type* = 0) = delete; + conditional::value, + deleter_type, const deleter_type&>::type) = delete; - template - unique_ptr(_Up*, typename std::remove_reference::type&&, - typename std::enable_if::value>::type* = 0) = delete; - - template - explicit - unique_ptr(_Up*, typename std::enable_if::value>::type* = 0) = delete; + template, + is_convertible<_Up*, pointer>, __is_derived_Tp<_Up>>> + unique_ptr(_Up*, typename + remove_reference::type&&) = delete; }; template diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional index 604481b20c4..3ec2e1ea4ed 100644 --- a/libstdc++-v3/include/std/functional +++ b/libstdc++-v3/include/std/functional @@ -501,9 +501,6 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type) // @} group functors - template - using _Require = typename enable_if<__and_<_Cond...>::value>::type; - template struct _Pack : integral_constant { }; diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits index cd7d72811bd..e2747276257 100644 --- a/libstdc++-v3/include/std/type_traits +++ b/libstdc++-v3/include/std/type_traits @@ -1771,6 +1771,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct enable_if { typedef _Tp type; }; + template + using _Require = typename enable_if<__and_<_Cond...>::value>::type; // Primary template. /// Define a member typedef @c type to one of two argument types. diff --git a/libstdc++-v3/testsuite/20_util/bind/ref_neg.cc b/libstdc++-v3/testsuite/20_util/bind/ref_neg.cc index bae0a861d21..98541765479 100644 --- a/libstdc++-v3/testsuite/20_util/bind/ref_neg.cc +++ b/libstdc++-v3/testsuite/20_util/bind/ref_neg.cc @@ -30,10 +30,10 @@ void test01() { const int dummy = 0; std::bind(&inc, _1)(0); // { dg-error "no match" } - // { dg-error "rvalue|const" "" { target *-*-* } 1349 } - // { dg-error "rvalue|const" "" { target *-*-* } 1363 } - // { dg-error "rvalue|const" "" { target *-*-* } 1377 } - // { dg-error "rvalue|const" "" { target *-*-* } 1391 } + // { dg-error "rvalue|const" "" { target *-*-* } 1346 } + // { dg-error "rvalue|const" "" { target *-*-* } 1360 } + // { dg-error "rvalue|const" "" { target *-*-* } 1374 } + // { dg-error "rvalue|const" "" { target *-*-* } 1388 } std::bind(&inc, std::ref(dummy))(); // { dg-error "no match" } } diff --git a/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc b/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc index 91d3553bb1d..015f39efd72 100644 --- a/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc +++ b/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc @@ -19,7 +19,7 @@ // with this library; see the file COPYING3. If not see // . -// { dg-error "static assertion failed" "" { target *-*-* } 1869 } +// { dg-error "static assertion failed" "" { target *-*-* } 1871 } #include diff --git a/libstdc++-v3/testsuite/20_util/default_delete/48631_neg.cc b/libstdc++-v3/testsuite/20_util/default_delete/48631_neg.cc index a9bba978787..fa2e3d11770 100644 --- a/libstdc++-v3/testsuite/20_util/default_delete/48631_neg.cc +++ b/libstdc++-v3/testsuite/20_util/default_delete/48631_neg.cc @@ -27,4 +27,4 @@ struct D : B { }; D d; std::default_delete db; typedef decltype(db(&d)) type; // { dg-error "use of deleted function" } -// { dg-error "declared here" "" { target *-*-* } 87 } +// { dg-error "declared here" "" { target *-*-* } 104 } diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc index 179932f6e32..380861c9df1 100644 --- a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc +++ b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc @@ -32,7 +32,7 @@ void test01() { X* px = 0; std::shared_ptr p1(px); // { dg-error "here" } - // { dg-error "incomplete" "" { target *-*-* } 769 } + // { dg-error "incomplete" "" { target *-*-* } 771 } std::shared_ptr p9(ap()); // { dg-error "here" } // { dg-error "incomplete" "" { target *-*-* } 307 } diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/unique_ptr.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/unique_ptr.cc index cfca90d9075..d6a25a0f0cb 100644 --- a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/unique_ptr.cc +++ b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/unique_ptr.cc @@ -1,6 +1,6 @@ -// { dg-options "-std=gnu++0x" } +// { dg-options "-std=gnu++11" } -// Copyright (C) 2008, 2009 Free Software Foundation +// Copyright (C) 2008-2012 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 @@ -17,14 +17,14 @@ // with this library; see the file COPYING3. If not see // . -// 20.7.12.2 Template class shared_ptr [util.smartptr.shared] +// 20.7.2.2 Class template shared_ptr [util.smartptr.shared] #include #include struct A { }; -// 20.7.12.2.1 shared_ptr constructors [util.smartptr.shared.const] +// 20.7.2.2.1 shared_ptr constructors [util.smartptr.shared.const] // Construction from unique_ptr int diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/unique_ptr_array.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/unique_ptr_array.cc new file mode 100644 index 00000000000..dc07920574e --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/unique_ptr_array.cc @@ -0,0 +1,59 @@ +// { dg-options "-std=gnu++11" } + +// Copyright (C) 2012 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 +// . + +// 20.7.2.2 Class template shared_ptr [util.smartptr.shared] + +#include +#include + +int destroyed = 0; + +struct A : std::enable_shared_from_this +{ + ~A() { ++destroyed; } +}; + +// 20.7.2.2.1 shared_ptr constructors [util.smartptr.shared.const] + +// Construction from unique_ptr +int +test01() +{ + bool test __attribute__((unused)) = true; + + std::unique_ptr up(new A[2]); + std::shared_ptr sp(std::move(up)); + VERIFY( up.get() == 0 ); + VERIFY( sp.get() != 0 ); + VERIFY( sp.use_count() == 1 ); + + VERIFY( sp->shared_from_this() != nullptr ); + + sp.reset(); + VERIFY( destroyed == 2 ); + + return 0; +} + +int +main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/20_util/unique_ptr/assign/48635_neg.cc b/libstdc++-v3/testsuite/20_util/unique_ptr/assign/48635_neg.cc index 3a4f9b48a58..624c225649e 100644 --- a/libstdc++-v3/testsuite/20_util/unique_ptr/assign/48635_neg.cc +++ b/libstdc++-v3/testsuite/20_util/unique_ptr/assign/48635_neg.cc @@ -41,10 +41,10 @@ void f() std::unique_ptr ub(nullptr, b); std::unique_ptr ud(nullptr, d); ub = std::move(ud); -// { dg-error "use of deleted function" "" { target *-*-* } 198 } +// { dg-error "use of deleted function" "" { target *-*-* } 206 } std::unique_ptr uba(nullptr, b); std::unique_ptr uda(nullptr, d); uba = std::move(uda); -// { dg-error "use of deleted function" "" { target *-*-* } 344 } +// { dg-error "use of deleted function" "" { target *-*-* } 396 } } diff --git a/libstdc++-v3/testsuite/20_util/unique_ptr/assign/cv_qual.cc b/libstdc++-v3/testsuite/20_util/unique_ptr/assign/cv_qual.cc new file mode 100644 index 00000000000..1b47a9f5695 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/unique_ptr/assign/cv_qual.cc @@ -0,0 +1,89 @@ +// { dg-options "-std=gnu++11" } +// { dg-do compile } + +// Copyright (C) 2012 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 +// . + +// 20.7.1 Class template unique_ptr [unique.ptr] + +#include + +struct A { virtual ~A() = default; }; + +struct B : A { }; + +// Assignment from objects with different cv-qualification + +void +test01() +{ + std::unique_ptr upA; + + std::unique_ptr cA; + cA = std::move(upA); + std::unique_ptr vA; + vA = std::move(upA); + std::unique_ptr cvA; + cvA = std::move(upA); +} + +void +test02() +{ + std::unique_ptr upB; + + std::unique_ptr cA; + cA = std::move(upB); + std::unique_ptr vA; + vA = std::move(upB); + std::unique_ptr cvA; + cvA = std::move(upB); +} + +void +test03() +{ + std::unique_ptr upA; + + std::unique_ptr cA; + cA = std::move(upA); + std::unique_ptr vA; + vA = std::move(upA); + std::unique_ptr cvA; + cvA = std::move(upA); +} + +struct A_pointer { operator A*() const { return nullptr; } }; + +template +struct deleter +{ + deleter() = default; + template + deleter(const deleter) { } + typedef T pointer; + void operator()(T) const { } +}; + +void +test04() +{ + // Allow conversions from user-defined pointer-like types + std::unique_ptr> p; + std::unique_ptr> upA; + upA = std::move(p); +} diff --git a/libstdc++-v3/testsuite/20_util/unique_ptr/cons/array_convertible_neg.cc b/libstdc++-v3/testsuite/20_util/unique_ptr/cons/array_convertible_neg.cc new file mode 100644 index 00000000000..15a1f317a5e --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/unique_ptr/cons/array_convertible_neg.cc @@ -0,0 +1,58 @@ +// { dg-do compile } +// { dg-options "-std=gnu++11" } + +// Copyright (C) 2012 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 +// . + +#include + +struct A +{ +}; + +struct B : A +{ + virtual ~B() { } +}; + +// 20.7.1.3 unique_ptr for array objects [unique.ptr.runtime] + +struct D +{ + template + void operator()(const T* p) const { delete[] p; } +}; + +// Conversion from different type of unique_ptr +void +test01() +{ + std::unique_ptr b(new B[1]); + std::unique_ptr a(std::move(b)); //{ dg-error "no matching function" } + a = std::move(b); //{ dg-error "no match" } +} + +// Conversion from non-array form of unique_ptr +void +test02() +{ + std::unique_ptr nonarray(new A); + std::unique_ptr array(std::move(nonarray)); //{ dg-error "no matching function" } + array = std::move(nonarray); //{ dg-error "no match" } +} + +// { dg-prune-output "include" } diff --git a/libstdc++-v3/testsuite/20_util/unique_ptr/cons/convertible_neg.cc b/libstdc++-v3/testsuite/20_util/unique_ptr/cons/convertible_neg.cc new file mode 100644 index 00000000000..5e6591d8857 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/unique_ptr/cons/convertible_neg.cc @@ -0,0 +1,38 @@ +// { dg-do compile } +// { dg-options "-std=gnu++11" } + +// Copyright (C) 2012 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 +// . + +#include + +struct A +{ +}; + +// 20.7.1.3 unique_ptr for array objects [unique.ptr.runtime] + +// Conversion to non-array form of unique_ptr +void +test01() +{ + std::unique_ptr array(new A[1]); + std::unique_ptr nonarray(std::move(array)); //{ dg-error "no matching function" } + nonarray = std::move(array); //{ dg-error "no match" } +} + +// { dg-prune-output "include" } diff --git a/libstdc++-v3/testsuite/20_util/unique_ptr/cons/cv_qual.cc b/libstdc++-v3/testsuite/20_util/unique_ptr/cons/cv_qual.cc new file mode 100644 index 00000000000..c1d3dadd485 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/unique_ptr/cons/cv_qual.cc @@ -0,0 +1,115 @@ +// { dg-options "-std=gnu++11" } +// { dg-do compile } + +// Copyright (C) 2012 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 +// . + +// 20.7.1 Class template unique_ptr [unique.ptr] + +#include + +struct A { virtual ~A() = default; }; + +struct B : A { }; + +// Construction from objects with different cv-qualification + +void +test01() +{ + std::unique_ptr cA(new A); + std::unique_ptr vA(new A); + std::unique_ptr cvA(new A); +} + +void +test02() +{ + std::unique_ptr cB(new B); + std::unique_ptr vB(new B); + std::unique_ptr cvB(new B); +} + +void +test03() +{ + std::unique_ptr upA; + + std::unique_ptr cA(std::move(upA)); + std::unique_ptr vA(std::move(upA)); + std::unique_ptr cvA(std::move(upA)); +} + +void +test04() +{ + std::unique_ptr upB; + + std::unique_ptr cA(std::move(upB)); + std::unique_ptr vA(std::move(upB)); + std::unique_ptr cvA(std::move(upB)); +} + +void +test05() +{ + std::unique_ptr cA(new A[1]); + std::unique_ptr vA(new A[1]); + std::unique_ptr cvA(new A[1]); +} + +void +test06() +{ + std::unique_ptr upA; + + std::unique_ptr cA(std::move(upA)); + std::unique_ptr vA(std::move(upA)); + std::unique_ptr cvA(std::move(upA)); +} + +struct A_pointer { operator A*() const { return nullptr; } }; + +void +test07() +{ + // Allow conversions from user-defined pointer-like types + A_pointer p; + std::unique_ptr upA(p); + std::unique_ptr cA(p); + std::unique_ptr vA(p); + std::unique_ptr cvA(p); +} + +template +struct deleter +{ + deleter() = default; + template + deleter(const deleter) { } + typedef T pointer; + void operator()(T) const { } +}; + +void +test08() +{ + // Allow conversions from user-defined pointer-like types + std::unique_ptr> p; + std::unique_ptr> upA(std::move(p)); +} + diff --git a/libstdc++-v3/testsuite/20_util/unique_ptr/cons/pointer_array_convertible_neg.cc b/libstdc++-v3/testsuite/20_util/unique_ptr/cons/pointer_array_convertible_neg.cc index 2a4a89b4037..42f1eca8bb6 100644 --- a/libstdc++-v3/testsuite/20_util/unique_ptr/cons/pointer_array_convertible_neg.cc +++ b/libstdc++-v3/testsuite/20_util/unique_ptr/cons/pointer_array_convertible_neg.cc @@ -1,7 +1,7 @@ // { dg-do compile } -// { dg-options "-std=gnu++0x" } +// { dg-options "-std=gnu++11" } -// Copyright (C) 2008, 2009 Free Software Foundation +// Copyright (C) 2008-2012 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 @@ -29,7 +29,7 @@ struct B : A virtual ~B() { } }; -// 20.4.5.1 unique_ptr constructors [unique.ptr.cons] +// 20.7.1.3.1 unique_ptr constructors [unique.ptr.runtime.ctor] // Construction from pointer of derived type void diff --git a/libstdc++-v3/testsuite/20_util/unique_ptr/cons/ptr_deleter_neg.cc b/libstdc++-v3/testsuite/20_util/unique_ptr/cons/ptr_deleter_neg.cc index 312ecbe338e..e2be1054653 100644 --- a/libstdc++-v3/testsuite/20_util/unique_ptr/cons/ptr_deleter_neg.cc +++ b/libstdc++-v3/testsuite/20_util/unique_ptr/cons/ptr_deleter_neg.cc @@ -1,7 +1,7 @@ // { dg-options "-std=gnu++0x" } // { dg-do compile } -// Copyright (C) 2010 Free Software Foundation +// Copyright (C) 2010-2012 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 @@ -18,10 +18,9 @@ // with this library; see the file COPYING3. If not see // . -// 20.6.11 Template class unique_ptr [unique.ptr] +// 20.7.1 Class template unique_ptr [unique.ptr] #include -#include using std::unique_ptr; @@ -30,9 +29,9 @@ using std::unique_ptr; void test01() { - unique_ptr p1; // { dg-error "here" } + unique_ptr p1; // { dg-error "here" } - unique_ptr p2(nullptr); // { dg-error "here" } + unique_ptr p2(nullptr); // { dg-error "here" } unique_ptr p3(new int); // { dg-error "here" } } @@ -40,9 +39,9 @@ test01() void test02() { - unique_ptr p1; // { dg-error "here" } + unique_ptr p1; // { dg-error "here" } - unique_ptr p2(nullptr); // { dg-error "here" } + unique_ptr p2(nullptr); // { dg-error "here" } unique_ptr p3(new int[1]); // { dg-error "here" } } diff --git a/libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/cv_qual.cc b/libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/cv_qual.cc new file mode 100644 index 00000000000..c5afa7ea59a --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/cv_qual.cc @@ -0,0 +1,79 @@ +// { dg-options "-std=gnu++11" } +// { dg-do compile } + +// Copyright (C) 2012 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 +// . + +// 20.7.1 Class template unique_ptr [unique.ptr] + +#include + +struct A { virtual ~A() = default; }; + +struct B : A { }; + +// Construction from objects with different cv-qualification + +void +test01() +{ + std::unique_ptr cA; + cA.reset(new A); + std::unique_ptr vA; + vA.reset(new A); + std::unique_ptr cvA; + cvA.reset(new A); +} + +void +test02() +{ + std::unique_ptr cB; + cB.reset(new B); + std::unique_ptr vB; + vB.reset(new B); + std::unique_ptr cvB; + cvB.reset(new B); +} + +void +test03() +{ + std::unique_ptr cA; + cA.reset(new A[1]); + std::unique_ptr vA; + vA.reset(new A[1]); + std::unique_ptr cvA; + cvA.reset(new A[1]); +} + +struct A_pointer { operator A*() const { return nullptr; } }; + +void +test07() +{ + // Allow conversions from user-defined pointer-like types + A_pointer p; + std::unique_ptr upA; + upA.reset(p); + std::unique_ptr cA; + cA.reset(p); + std::unique_ptr vA; + vA.reset(p); + std::unique_ptr cvA; + cvA.reset(p); +} diff --git a/libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/reset_neg.cc b/libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/reset_neg.cc index 29bb57d22b2..2f5e639b055 100644 --- a/libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/reset_neg.cc +++ b/libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/reset_neg.cc @@ -1,7 +1,7 @@ // { dg-do compile } // { dg-options "-std=gnu++0x" } -// Copyright (C) 2008, 2009, 2010 Free Software Foundation +// Copyright (C) 2008-2012 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 @@ -32,7 +32,7 @@ struct B : A void test01() { std::unique_ptr up; - up.reset(new A[3]); // { dg-error "deleted" } + up.reset(new A[3]); // { dg-error "invalid conversion" } } // { dg-prune-output "include" } diff --git a/libstdc++-v3/testsuite/20_util/unique_ptr/requirements/pointer_type.cc b/libstdc++-v3/testsuite/20_util/unique_ptr/requirements/pointer_type.cc index 55f28caaaf8..ee2105d1cc0 100644 --- a/libstdc++-v3/testsuite/20_util/unique_ptr/requirements/pointer_type.cc +++ b/libstdc++-v3/testsuite/20_util/unique_ptr/requirements/pointer_type.cc @@ -1,7 +1,7 @@ // { dg-do compile } -// { dg-options "-std=gnu++0x" } +// { dg-options "-std=gnu++11" } -// Copyright (C) 2010, 2011 Free Software Foundation +// Copyright (C) 2010-2012 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 @@ -18,10 +18,9 @@ // with this library; see the file COPYING3. If not see // . -// 20.6.11 Template class unique_ptr [unique.ptr.single] +// 20.7.1.2 unique_ptr for single objects [unique.ptr.single] #include -#include struct A { diff --git a/libstdc++-v3/testsuite/20_util/unique_ptr/requirements/pointer_type_array.cc b/libstdc++-v3/testsuite/20_util/unique_ptr/requirements/pointer_type_array.cc new file mode 100644 index 00000000000..0f1a8e51a97 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/unique_ptr/requirements/pointer_type_array.cc @@ -0,0 +1,49 @@ +// { dg-do compile } +// { dg-options "-std=gnu++11" } + +// Copyright (C) 2010-2012 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 +// . + +// 20.7.1.3 unique_ptr for array objects [unique.ptr.runtime] + +#include + +struct A +{ + void operator()(void*) const { } +}; + +struct B +{ + typedef char* pointer; + void operator()(pointer) const { } +}; + +int main() +{ + typedef std::unique_ptr up; + typedef std::unique_ptr upA; + typedef std::unique_ptr upB; + typedef std::unique_ptr upAr; + typedef std::unique_ptr upBr; + + static_assert( std::is_same< up::pointer, int*>::value, "" ); + static_assert( std::is_same< upA::pointer, int*>::value, "" ); + static_assert( std::is_same< upB::pointer, char*>::value, "" ); + static_assert( std::is_same< upAr::pointer, int*>::value, "" ); + static_assert( std::is_same< upBr::pointer, char*>::value, "" ); +}