From b25029437e2141fc74062d8331f3c355bfdfe0f6 Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Mon, 27 Nov 2017 15:51:36 +0000 Subject: Implement LWG#2948: unique_ptr does not define operator<< for stream output git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@319038 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/memory | 3 +++ include/ostream | 12 +++++++++ .../unique.ptr/unique.ptr.special/io.fail.cpp | 31 ++++++++++++++++++++++ .../unique.ptr/unique.ptr.special/io.pass.cpp | 29 ++++++++++++++++++++ www/cxx2a_status.html | 4 +-- 5 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 test/std/utilities/memory/unique.ptr/unique.ptr.special/io.fail.cpp create mode 100644 test/std/utilities/memory/unique.ptr/unique.ptr.special/io.pass.cpp diff --git a/include/memory b/include/memory index 30cb79eb5..5c109df1c 100644 --- a/include/memory +++ b/include/memory @@ -387,6 +387,9 @@ template unique_ptr make_unique(Args&&... args); template unique_ptr make_unique(size_t n); // C++14 template unspecified make_unique(Args&&...) = delete; // C++14, T == U[N] +template + basic_ostream& operator<< (basic_ostream& os, unique_ptr const& p); + template class shared_ptr { diff --git a/include/ostream b/include/ostream index 9bf8d3cdc..92f7f4dfb 100644 --- a/include/ostream +++ b/include/ostream @@ -1071,6 +1071,18 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, shared_ptr<_Yp> const& __p) return __os << __p.get(); } +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_same&>() << declval<_Yp>())>::type>::value, + basic_ostream<_CharT, _Traits>& +>::type +operator<<(basic_ostream<_CharT, _Traits>& __os, unique_ptr<_Yp, _Dp> const& __p) +{ + return __os << __p.get(); +} + template basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, const bitset<_Size>& __x) diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.special/io.fail.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.special/io.fail.cpp new file mode 100644 index 000000000..1a4c0bd82 --- /dev/null +++ b/test/std/utilities/memory/unique.ptr/unique.ptr.special/io.fail.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// unique_ptr + +// template +// basic_ostream& +// operator<<(basic_ostream& os, const unique_ptr& p); + +// -?- Remarks: This function shall not participate in overload resolution unless os << p.get() is a valid expression. + +#include +#include +#include + +class A {}; + +int main() +{ + std::unique_ptr p(new A); + std::ostringstream os; + os << p; +} diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.special/io.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.special/io.pass.cpp new file mode 100644 index 000000000..81a1c368a --- /dev/null +++ b/test/std/utilities/memory/unique.ptr/unique.ptr.special/io.pass.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// unique_ptr + +// template +// basic_ostream& +// operator<<(basic_ostream& os, const unique_ptr& p); + +#include +#include +#include + +int main() +{ + std::unique_ptr p(new int(3)); + std::ostringstream os; + assert(os.str().empty()); + os << p; + assert(!os.str().empty()); +} diff --git a/www/cxx2a_status.html b/www/cxx2a_status.html index 3a2a66d58..d7b584c19 100644 --- a/www/cxx2a_status.html +++ b/www/cxx2a_status.html @@ -65,7 +65,7 @@ P0439R0LWGMake std::memory_order a scoped enumerationAlbuquerque P0457R2LWGString Prefix and Suffix CheckingAlbuquerque P0550R2LWGTransformation Trait remove_cvrefAlbuquerqueComplete6.0 - P0600R1LWGnodiscard in the LibraryAlbuquerque + P0600R1LWGnodiscard in the LibraryAlbuquerqueIn Progress P0616R0LWGde-pessimize legacy algorithms with std::moveAlbuquerque P0653R2LWGUtility to convert a pointer to a raw pointerAlbuquerqueComplete6.0 P0718R2LWGAtomic shared_ptrAlbuquerque @@ -106,7 +106,7 @@ 2941[thread.req.timing] wording should apply to both member and namespace-level functionsAlbuquerqueNothing to do 2944LWG 2905 accidentally removed requirement that construction of the deleter doesn't throw an exceptionAlbuquerqueNothing to do 2945Order of template parameters in optional comparisonsAlbuquerqueComplete - 2948unique_ptr does not define operator<< for stream outputAlbuquerque + 2948unique_ptr does not define operator<< for stream outputAlbuquerqueComplete 2950std::byte operations are misspecifiedAlbuquerqueComplete 2952iterator_traits should work for pointers to cv TAlbuquerqueComplete 2953LWG 2853 should apply to deque::erase tooAlbuquerque -- cgit v1.2.3