From patchwork Thu Dec 20 21:14:16 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 207712 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 49EE92C0082 for ; Fri, 21 Dec 2012 08:14:43 +1100 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1356642884; h=Comment: DomainKey-Signature:Received:Received:Received:Received: MIME-Version:Received:Received:Date:Message-ID:Subject:From:To: Cc:Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:Sender:Delivered-To; bh=jWKO497 yaIkaVZz0dGttIeX9z7A=; b=EGOKT4F2HSkwpbeKWo/Ef3nH6I/Hq8TR5kAEebr ELVd1/OEIKg8DpbFyda9G+jEmryBWDgaExn6y4lhtCMCZ8G5SJdtx0li1RKVi+2T T1Lu7cmZKxjgQT/XBjXr3frGDU7GTjS1s+Cl8xpZ/MND+1EfSHxoQyM/ezIRUcG+ KOFo= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:MIME-Version:Received:Received:Date:Message-ID:Subject:From:To:Cc:Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=Jc95sQTWpW7dPdhDeQsb6Fb1yKe5d33zFx44UHk3qqJhkt2cmgEikrkVApqFsm fZzA5RqNg9oyXqJCJgclKzEMbt1WagIIuj9s5KGHeaYhnrIuk30dHCJ5dRBPoxyL 0+MPvPPR/SiwGZvTmf5RLQc50Hvm5bvEMZ2OMMRTOtvbY=; Received: (qmail 12313 invoked by alias); 20 Dec 2012 21:14:32 -0000 Received: (qmail 12293 invoked by uid 22791); 20 Dec 2012 21:14:31 -0000 X-SWARE-Spam-Status: No, hits=-4.5 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, KHOP_RCVD_TRUST, RCVD_IN_DNSWL_LOW, RCVD_IN_HOSTKARMA_YE X-Spam-Check-By: sourceware.org Received: from mail-qc0-f171.google.com (HELO mail-qc0-f171.google.com) (209.85.216.171) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 20 Dec 2012 21:14:20 +0000 Received: by mail-qc0-f171.google.com with SMTP id d1so2163926qca.30 for ; Thu, 20 Dec 2012 13:14:16 -0800 (PST) MIME-Version: 1.0 Received: by 10.224.9.65 with SMTP id k1mr5589514qak.10.1356038056705; Thu, 20 Dec 2012 13:14:16 -0800 (PST) Received: by 10.49.129.70 with HTTP; Thu, 20 Dec 2012 13:14:16 -0800 (PST) Date: Thu, 20 Dec 2012 21:14:16 +0000 Message-ID: Subject: [patch] std::unique_ptr improvements From: Jonathan Wakely To: "libstdc++" , gcc-patches Cc: Geoffrey Romer , Lawrence Crowl Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org This patch started when I noticed that it's not possibly to construct a shared_ptr from unique_ptr, then I discovered we don't use D::pointer if it exists, and there were a number of other non-conformance issues with our std::unique_ptr. I ended up fixing them by implementing Geoffrey's proposed resolution for LWG issue 2118, which isn't official yet but is better than what we had before so is a step in the right direction, even if it ends up needing further revision when 2118 is resolved. * 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. Thanks to Geoffrey and Lawrence for input and test cases. Tested x86_64-linux, committed to trunk. commit 907290c8077e6757c56fc64c9160c4bdaea86b90 Author: Jonathan Wakely Date: Thu Dec 20 17:57:33 2012 +0000 * 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. diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h index ead3728..9d9fecb 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 37eae25..e17a4dc 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,26 +437,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } void - reset(pointer __p = pointer()) noexcept - { - using std::swap; - swap(std::get<0>(_M_t), __p); - if (__p != nullptr) - get_deleter()(__p); - } + reset() noexcept + { reset(pointer()); } void - reset(nullptr_t) noexcept + reset(pointer __p) noexcept { - pointer __p = get(); - std::get<0>(_M_t) = pointer(); + using std::swap; + swap(std::get<0>(_M_t), __p); 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; - - template - unique_ptr(_Up*, typename std::remove_reference::type&&, - typename std::enable_if::value>::type* = 0) = delete; + conditional::value, + deleter_type, const deleter_type&>::type) = 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 604481b..3ec2e1e 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 cd7d728..e274727 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 bae0a86..9854176 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 91d3553..015f39e 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 a9bba97..fa2e3d1 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 179932f..380861c 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 cfca90d..d6a25a0 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 0000000..dc07920 --- /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 3a4f9b4..624c225 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 0000000..1b47a9f --- /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 0000000..15a1f31 --- /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 0000000..5e6591d --- /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 0000000..c1d3dad --- /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 2a4a89b..42f1eca 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 312ecbe..e2be105 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 0000000..c5afa7e --- /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 29bb57d..2f5e639 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 55f28ca..ee2105d 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 0000000..0f1a8e5 --- /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, "" ); +}