From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1984) id 27248398C032; Fri, 17 Jul 2020 15:26:57 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 27248398C032 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1594999617; bh=uNHW/J/RLEvnwSZOe+KopWp6W6CFkZhMkrKgXpejdW0=; h=From:To:Subject:Date:From; b=EVeZ5+eLwoDBJENgZ3jTtcTLlQ/Fb3nn2w8lZJ8TykKC/Xs4T5db8Qa+2lRZTb0Se trqW1eXbE7p53zpyaArLJMPB9e3rNcGQW6gfBx+2cHpWSBE7WWWHjnWyfLHkG2HZt4 mGG8QW4J58//8WMQfNZpcVrh1uQJ9bEyy72pJ1T0= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Tamar Christina To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc(refs/vendors/ARM/heads/arm-struct-reorg-wip)] libstdc++: Implement operator<< for std::unique_ptr (LWG 2948) X-Act-Checkin: gcc X-Git-Author: Jonathan Wakely X-Git-Refname: refs/vendors/ARM/heads/arm-struct-reorg-wip X-Git-Oldrev: 38250e577e26de7aace65b4d32a94a1404f076a9 X-Git-Newrev: 86e99e8e4f07699dc1f2df93cc7ebd4fe568fc7b Message-Id: <20200717152657.27248398C032@sourceware.org> Date: Fri, 17 Jul 2020 15:26:57 +0000 (GMT) X-BeenThere: libstdc++-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libstdc++-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 17 Jul 2020 15:26:57 -0000 https://gcc.gnu.org/g:86e99e8e4f07699dc1f2df93cc7ebd4fe568fc7b commit 86e99e8e4f07699dc1f2df93cc7ebd4fe568fc7b Author: Jonathan Wakely Date: Mon Jun 8 18:08:14 2020 +0100 libstdc++: Implement operator<< for std::unique_ptr (LWG 2948) libstdc++-v3/ChangeLog: * include/bits/unique_ptr.h (operator<<): Define for C++20. * testsuite/20_util/unique_ptr/io/lwg2948.cc: New test. * testsuite/20_util/default_delete/48631_neg.cc: Adjust dg-error line number. * testsuite/20_util/default_delete/void_neg.cc: Likewise. (cherry picked from commit 187da2ce31f13b2f75d5bb780e30ee364ead9d1d) Diff: --- libstdc++-v3/include/bits/unique_ptr.h | 20 ++++- .../testsuite/20_util/default_delete/48631_neg.cc | 2 +- .../testsuite/20_util/default_delete/void_neg.cc | 2 +- .../testsuite/20_util/unique_ptr/io/lwg2948.cc | 91 ++++++++++++++++++++++ 4 files changed, 111 insertions(+), 4 deletions(-) diff --git a/libstdc++-v3/include/bits/unique_ptr.h b/libstdc++-v3/include/bits/unique_ptr.h index 3695214808b..d0e4cefadd7 100644 --- a/libstdc++-v3/include/bits/unique_ptr.h +++ b/libstdc++-v3/include/bits/unique_ptr.h @@ -39,6 +39,7 @@ #include #if __cplusplus > 201703L # include +# include #endif namespace std _GLIBCXX_VISIBILITY(default) @@ -934,7 +935,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION public __uniq_ptr_hash> { }; -#if __cplusplus > 201103L +#if __cplusplus >= 201402L /// @relates unique_ptr @{ #define __cpp_lib_make_unique 201304 @@ -971,7 +972,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline typename _MakeUniq<_Tp>::__invalid_type make_unique(_Args&&...) = delete; // @} relates unique_ptr -#endif +#endif // C++14 + +#if __cplusplus > 201703L && __cpp_concepts + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2948. unique_ptr does not define operator<< for stream output + /// Stream output operator for unique_ptr + template + inline basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, + const unique_ptr<_Tp, _Dp>& __p) + requires requires { __os << __p.get(); } + { + __os << __p.get(); + return __os; + } +#endif // C++20 // @} group pointer_abstractions 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 6da5a52e28b..0e807c7d57a 100644 --- a/libstdc++-v3/testsuite/20_util/default_delete/48631_neg.cc +++ b/libstdc++-v3/testsuite/20_util/default_delete/48631_neg.cc @@ -26,4 +26,4 @@ struct D : B { }; D d; std::default_delete db; typedef decltype(db(&d)) type; // { dg-error "no match" } -// { dg-error "no type" "" { target *-*-* } 115 } +// { dg-error "no type" "" { target *-*-* } 116 } diff --git a/libstdc++-v3/testsuite/20_util/default_delete/void_neg.cc b/libstdc++-v3/testsuite/20_util/default_delete/void_neg.cc index 149b699d106..9f281373b37 100644 --- a/libstdc++-v3/testsuite/20_util/default_delete/void_neg.cc +++ b/libstdc++-v3/testsuite/20_util/default_delete/void_neg.cc @@ -25,5 +25,5 @@ void test01() { std::default_delete d; d(nullptr); // { dg-error "here" } - // { dg-error "incomplete" "" { target *-*-* } 80 } + // { dg-error "incomplete" "" { target *-*-* } 81 } } diff --git a/libstdc++-v3/testsuite/20_util/unique_ptr/io/lwg2948.cc b/libstdc++-v3/testsuite/20_util/unique_ptr/io/lwg2948.cc new file mode 100644 index 00000000000..3f4e4dfabe7 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/unique_ptr/io/lwg2948.cc @@ -0,0 +1,91 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// 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 +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do run { target c++2a } } + +#include +#include +#include + +template + concept streamable = requires (S& o, const T& p) { o << p; }; + +template + bool + check(const std::unique_ptr& p) + { + std::ostringstream ss1, ss2; + ss1 << p; + ss2 << p.get(); + return ss1.str() == ss2.str(); + } + +void +test01() +{ + static_assert( streamable> ); + + std::unique_ptr p; + VERIFY( check(p) ); + p = std::make_unique(); + VERIFY( check(p) ); +} + +template + struct deleter + { + struct pointer + { + pointer() { } + pointer(std::nullptr_t) { } + explicit operator bool() const { return false; } + bool operator==(pointer) const { return true; } + }; + + void operator()(pointer) const { } + }; + +template + int + operator<<(std::basic_ostream& o, typename deleter::pointer&&) + { + o << C{'P'}; + return 1; // no requirement that this operator returns the stream + } + +template + using Unique_ptr = std::unique_ptr; + +static_assert( streamable>> ); +static_assert( ! streamable>> ); +static_assert( ! streamable>> ); +static_assert( streamable>> ); + +void +test02() +{ + Unique_ptr> p; + VERIFY( check(p) ); +} + +int +main() +{ + test01(); + test02(); +}