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.
This commit is contained in:
parent
5fceefeee9
commit
187da2ce31
|
@ -39,6 +39,7 @@
|
|||
#include <bits/functional_hash.h>
|
||||
#if __cplusplus > 201703L
|
||||
# include <compare>
|
||||
# include <ostream>
|
||||
#endif
|
||||
|
||||
namespace std _GLIBCXX_VISIBILITY(default)
|
||||
|
@ -934,7 +935,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
public __uniq_ptr_hash<unique_ptr<_Tp, _Dp>>
|
||||
{ };
|
||||
|
||||
#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<typename _CharT, typename _Traits, typename _Tp, typename _Dp>
|
||||
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
|
||||
|
||||
|
|
|
@ -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
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
// { dg-options "-std=gnu++2a" }
|
||||
// { dg-do run { target c++2a } }
|
||||
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
template<typename S, typename T>
|
||||
concept streamable = requires (S& o, const T& p) { o << p; };
|
||||
|
||||
template<typename T, typename D>
|
||||
bool
|
||||
check(const std::unique_ptr<T, D>& p)
|
||||
{
|
||||
std::ostringstream ss1, ss2;
|
||||
ss1 << p;
|
||||
ss2 << p.get();
|
||||
return ss1.str() == ss2.str();
|
||||
}
|
||||
|
||||
void
|
||||
test01()
|
||||
{
|
||||
static_assert( streamable<std::ostream, std::unique_ptr<int>> );
|
||||
|
||||
std::unique_ptr<int> p;
|
||||
VERIFY( check(p) );
|
||||
p = std::make_unique<int>();
|
||||
VERIFY( check(p) );
|
||||
}
|
||||
|
||||
template<typename>
|
||||
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<typename C, typename Traits>
|
||||
int
|
||||
operator<<(std::basic_ostream<C, Traits>& o, typename deleter<C>::pointer&&)
|
||||
{
|
||||
o << C{'P'};
|
||||
return 1; // no requirement that this operator returns the stream
|
||||
}
|
||||
|
||||
template<typename D>
|
||||
using Unique_ptr = std::unique_ptr<typename D::pointer, D>;
|
||||
|
||||
static_assert( streamable<std::ostream, Unique_ptr<deleter<char>>> );
|
||||
static_assert( ! streamable<std::ostream, Unique_ptr<deleter<wchar_t>>> );
|
||||
static_assert( ! streamable<std::wostream, Unique_ptr<deleter<char>>> );
|
||||
static_assert( streamable<std::wostream, Unique_ptr<deleter<wchar_t>>> );
|
||||
|
||||
void
|
||||
test02()
|
||||
{
|
||||
Unique_ptr<deleter<char>> p;
|
||||
VERIFY( check(p) );
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
}
|
Loading…
Reference in New Issue