LWG 2996 add rvalue overloads for shared_ptr aliasing and casting
* doc/xml/manual/intro.xml: Document LWG DR 2996 change. * doc/html/*: Regenerate. * include/bits/shared_ptr.h (shared_ptr(shared_ptr&&, T*)): Add rvalue aliasing constructor. (static_pointer_cast, const_pointer, dynamic_pointer_cast) (reinterpret_pointer_cast): Add overloads taking rvalues. * include/bits/shared_ptr_base.h (__shared_ptr(__shared_ptr&&, T*)): Add rvalue aliasing constructor. * testsuite/20_util/shared_ptr/casts/1.cc: Change "compile" test to "run" and check return values as well as types. * testsuite/20_util/shared_ptr/casts/reinterpret.cc: Likewise. * testsuite/20_util/shared_ptr/casts/rval.cc: New test. * testsuite/20_util/shared_ptr/cons/alias-rval.cc: New test. * testsuite/20_util/shared_ptr/cons/alias.cc: Remove unused return values. From-SVN: r271583
This commit is contained in:
parent
9a0af7e3fb
commit
fb3fc4bded
|
@ -1,5 +1,21 @@
|
|||
2019-05-23 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
* doc/xml/manual/intro.xml: Document LWG DR 2996 change.
|
||||
* doc/html/*: Regenerate.
|
||||
* include/bits/shared_ptr.h (shared_ptr(shared_ptr&&, T*)): Add
|
||||
rvalue aliasing constructor.
|
||||
(static_pointer_cast, const_pointer, dynamic_pointer_cast)
|
||||
(reinterpret_pointer_cast): Add overloads taking rvalues.
|
||||
* include/bits/shared_ptr_base.h (__shared_ptr(__shared_ptr&&, T*)):
|
||||
Add rvalue aliasing constructor.
|
||||
* testsuite/20_util/shared_ptr/casts/1.cc: Change "compile" test to
|
||||
"run" and check return values as well as types.
|
||||
* testsuite/20_util/shared_ptr/casts/reinterpret.cc: Likewise.
|
||||
* testsuite/20_util/shared_ptr/casts/rval.cc: New test.
|
||||
* testsuite/20_util/shared_ptr/cons/alias-rval.cc: New test.
|
||||
* testsuite/20_util/shared_ptr/cons/alias.cc: Remove unused return
|
||||
values.
|
||||
|
||||
* doc/xml/manual/evolution.xml: Document LWG DR 2921 change.
|
||||
* doc/xml/manual/intro.xml: Likewise.
|
||||
* include/std/future (__create_task_state): Add default arguments
|
||||
|
|
|
@ -393,4 +393,7 @@ now defaults to zero.
|
|||
<code class="filename"><experimental/timer></code>.
|
||||
</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="api.rel_101"></a><code class="constant">10</code></h3></div></div></div><p> Deprecated features removed:
|
||||
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"> Profile Mode </li><li class="listitem"><code class="classname">__gnu_cxx::array_allocator</code></li></ul></div><p>
|
||||
</p><p>
|
||||
The <code class="classname">std::packaged_task</code> constructors taking
|
||||
an allocator argument are only defined for C++11 and C++14.
|
||||
</p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="abi.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="appendix_porting.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="backwards.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ABI Policy and Guidelines </td><td width="20%" align="center"><a accesskey="h" href="../index.html">Home</a></td><td width="40%" align="right" valign="top"> Backwards Compatibility</td></tr></table></div></body></html>
|
|
@ -565,11 +565,21 @@
|
|||
<span class="emphasis"><em><code class="code">shared_ptr</code> constructor requirements for a deleter
|
||||
</em></span>
|
||||
</span></dt><dd><p>Use rvalues for deleters.
|
||||
</p></dd><dt><a id="manual.bugs.dr2921"></a><span class="term"><a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2921" target="_top">2921</a>:
|
||||
<span class="emphasis"><em><code class="code">packaged_task</code> and type-erased allocators
|
||||
</em></span>
|
||||
</span></dt><dd><p>For C++17 mode, remove the constructors taking
|
||||
an allocator argument.
|
||||
</p></dd><dt><a id="manual.bugs.dr2942"></a><span class="term"><a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2942" target="_top">2942</a>:
|
||||
<span class="emphasis"><em>LWG 2873's resolution missed
|
||||
<code class="code">weak_ptr::owner_before</code>
|
||||
</em></span>
|
||||
</span></dt><dd><p>Add noexcept.
|
||||
</p></dd><dt><a id="manual.bugs.dr2996"></a><span class="term"><a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2996" target="_top">2996</a>:
|
||||
<span class="emphasis"><em>Missing rvalue overloads for
|
||||
<code class="code">shared_ptr</code> operations
|
||||
</em></span>
|
||||
</span></dt><dd><p>Add additional constructor and cast overloads.
|
||||
</p></dd><dt><a id="manual.bugs.dr2993"></a><span class="term"><a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2993" target="_top">2993</a>:
|
||||
<span class="emphasis"><em><code class="code">reference_wrapper<T></code> conversion from <code class="code">T&&</code>
|
||||
</em></span>
|
||||
|
|
|
@ -1237,6 +1237,14 @@ requirements of the license of GCC.
|
|||
<listitem><para>Add noexcept.
|
||||
</para></listitem></varlistentry>
|
||||
|
||||
<varlistentry xml:id="manual.bugs.dr2996"><term><link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="&DR;#2996">2996</link>:
|
||||
<emphasis>Missing rvalue overloads for
|
||||
<code>shared_ptr</code> operations
|
||||
</emphasis>
|
||||
</term>
|
||||
<listitem><para>Add additional constructor and cast overloads.
|
||||
</para></listitem></varlistentry>
|
||||
|
||||
<varlistentry xml:id="manual.bugs.dr2993"><term><link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="&DR;#2993">2993</link>:
|
||||
<emphasis><code>reference_wrapper<T></code> conversion from <code>T&&</code>
|
||||
</emphasis>
|
||||
|
|
|
@ -235,17 +235,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
// Aliasing constructor
|
||||
|
||||
/**
|
||||
* @brief Constructs a %shared_ptr instance that stores @a __p
|
||||
* and shares ownership with @a __r.
|
||||
* @param __r A %shared_ptr.
|
||||
* @param __p A pointer that will remain valid while @a *__r is valid.
|
||||
* @post get() == __p && use_count() == __r.use_count()
|
||||
* @brief Constructs a `shared_ptr` instance that stores `__p`
|
||||
* and shares ownership with `__r`.
|
||||
* @param __r A `shared_ptr`.
|
||||
* @param __p A pointer that will remain valid while `*__r` is valid.
|
||||
* @post `get() == __p && use_count() == __r.use_count()`
|
||||
*
|
||||
* This can be used to construct a @c shared_ptr to a sub-object
|
||||
* of an object managed by an existing @c shared_ptr.
|
||||
* This can be used to construct a `shared_ptr` to a sub-object
|
||||
* of an object managed by an existing `shared_ptr`. The complete
|
||||
* object will remain valid while any `shared_ptr` owns it, even
|
||||
* if they don't store a pointer to the complete object.
|
||||
*
|
||||
* @code
|
||||
* shared_ptr< pair<int,int> > pii(new pair<int,int>());
|
||||
* shared_ptr<pair<int,int>> pii(new pair<int,int>());
|
||||
* shared_ptr<int> pi(pii, &pii->first);
|
||||
* assert(pii.use_count() == 2);
|
||||
* @endcode
|
||||
|
@ -254,6 +256,33 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) noexcept
|
||||
: __shared_ptr<_Tp>(__r, __p) { }
|
||||
|
||||
#if __cplusplus > 201703L
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 2996. Missing rvalue overloads for shared_ptr operations
|
||||
/**
|
||||
* @brief Constructs a `shared_ptr` instance that stores `__p`
|
||||
* and shares ownership with `__r`.
|
||||
* @param __r A `shared_ptr`.
|
||||
* @param __p A pointer that will remain valid while `*__r` is valid.
|
||||
* @post `get() == __p && !__r.use_count() && !__r.get()`
|
||||
*
|
||||
* This can be used to construct a `shared_ptr` to a sub-object
|
||||
* of an object managed by an existing `shared_ptr`. The complete
|
||||
* object will remain valid while any `shared_ptr` owns it, even
|
||||
* if they don't store a pointer to the complete object.
|
||||
*
|
||||
* @code
|
||||
* shared_ptr<pair<int,int>> pii(new pair<int,int>());
|
||||
* shared_ptr<int> pi1(pii, &pii->first);
|
||||
* assert(pii.use_count() == 2);
|
||||
* shared_ptr<int> pi2(std::move(pii), &pii->second);
|
||||
* assert(pii.use_count() == 0);
|
||||
* @endcode
|
||||
*/
|
||||
template<typename _Yp>
|
||||
shared_ptr(shared_ptr<_Yp>&& __r, element_type* __p) noexcept
|
||||
: __shared_ptr<_Tp>(std::move(__r), __p) { }
|
||||
#endif
|
||||
/**
|
||||
* @brief If @a __r is empty, constructs an empty %shared_ptr;
|
||||
* otherwise construct a %shared_ptr that shares ownership
|
||||
|
@ -568,7 +597,53 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
using _Sp = shared_ptr<_Tp>;
|
||||
return _Sp(__r, reinterpret_cast<typename _Sp::element_type*>(__r.get()));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if __cplusplus > 201703L
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 2996. Missing rvalue overloads for shared_ptr operations
|
||||
|
||||
/// Convert type of `shared_ptr` rvalue, via `static_cast`
|
||||
template<typename _Tp, typename _Up>
|
||||
inline shared_ptr<_Tp>
|
||||
static_pointer_cast(shared_ptr<_Up>&& __r) noexcept
|
||||
{
|
||||
using _Sp = shared_ptr<_Tp>;
|
||||
return _Sp(std::move(__r),
|
||||
static_cast<typename _Sp::element_type*>(__r.get()));
|
||||
}
|
||||
|
||||
/// Convert type of `shared_ptr` rvalue, via `const_cast`
|
||||
template<typename _Tp, typename _Up>
|
||||
inline shared_ptr<_Tp>
|
||||
const_pointer_cast(shared_ptr<_Up>&& __r) noexcept
|
||||
{
|
||||
using _Sp = shared_ptr<_Tp>;
|
||||
return _Sp(std::move(__r),
|
||||
const_cast<typename _Sp::element_type*>(__r.get()));
|
||||
}
|
||||
|
||||
/// Convert type of `shared_ptr` rvalue, via `dynamic_cast`
|
||||
template<typename _Tp, typename _Up>
|
||||
inline shared_ptr<_Tp>
|
||||
dynamic_pointer_cast(shared_ptr<_Up>&& __r) noexcept
|
||||
{
|
||||
using _Sp = shared_ptr<_Tp>;
|
||||
if (auto* __p = dynamic_cast<typename _Sp::element_type*>(__r.get()))
|
||||
return _Sp(std::move(__r), __p);
|
||||
return _Sp();
|
||||
}
|
||||
|
||||
/// Convert type of `shared_ptr` rvalue, via `reinterpret_cast`
|
||||
template<typename _Tp, typename _Up>
|
||||
inline shared_ptr<_Tp>
|
||||
reinterpret_pointer_cast(shared_ptr<_Up>&& __r) noexcept
|
||||
{
|
||||
using _Sp = shared_ptr<_Tp>;
|
||||
return _Sp(std::move(__r),
|
||||
reinterpret_cast<typename _Sp::element_type*>(__r.get()));
|
||||
}
|
||||
#endif // C++20
|
||||
#endif // C++17
|
||||
|
||||
// @}
|
||||
|
||||
|
|
|
@ -1158,12 +1158,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
: _M_ptr(0), _M_refcount(__p, std::move(__d), std::move(__a))
|
||||
{ }
|
||||
|
||||
// Aliasing constructor
|
||||
template<typename _Yp>
|
||||
__shared_ptr(const __shared_ptr<_Yp, _Lp>& __r,
|
||||
element_type* __p) noexcept
|
||||
: _M_ptr(__p), _M_refcount(__r._M_refcount) // never throws
|
||||
{ }
|
||||
|
||||
// Aliasing constructor
|
||||
template<typename _Yp>
|
||||
__shared_ptr(__shared_ptr<_Yp, _Lp>&& __r,
|
||||
element_type* __p) noexcept
|
||||
: _M_ptr(__p), _M_refcount()
|
||||
{
|
||||
_M_refcount._M_swap(__r._M_refcount);
|
||||
__r._M_ptr = 0;
|
||||
}
|
||||
|
||||
__shared_ptr(const __shared_ptr&) noexcept = default;
|
||||
__shared_ptr& operator=(const __shared_ptr&) noexcept = default;
|
||||
~__shared_ptr() = default;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// { dg-do compile { target c++11 } }
|
||||
// { dg-do run { target c++11 } }
|
||||
|
||||
// Copyright (C) 2006-2019 Free Software Foundation, Inc.
|
||||
//
|
||||
|
@ -20,12 +20,14 @@
|
|||
// 20.6.6.2.10 shared_ptr casts [util.smartptr.shared.cast]
|
||||
|
||||
#include <memory>
|
||||
#include <testsuite_hooks.h>
|
||||
#include <testsuite_tr1.h>
|
||||
|
||||
struct MyP { virtual ~MyP() { }; };
|
||||
struct MyDP : MyP { };
|
||||
|
||||
int main()
|
||||
void
|
||||
test01()
|
||||
{
|
||||
using __gnu_test::check_ret_type;
|
||||
using std::shared_ptr;
|
||||
|
@ -37,7 +39,50 @@ int main()
|
|||
shared_ptr<const int> spci;
|
||||
shared_ptr<MyP> spa;
|
||||
|
||||
check_ret_type<shared_ptr<void> >(static_pointer_cast<void>(spd));
|
||||
check_ret_type<shared_ptr<int> >(const_pointer_cast<int>(spci));
|
||||
check_ret_type<shared_ptr<MyDP> >(static_pointer_cast<MyDP>(spa));
|
||||
check_ret_type<shared_ptr<void>>(static_pointer_cast<void>(spd));
|
||||
check_ret_type<shared_ptr<int>>(const_pointer_cast<int>(spci));
|
||||
check_ret_type<shared_ptr<MyDP>>(dynamic_pointer_cast<MyDP>(spa));
|
||||
}
|
||||
|
||||
void
|
||||
test02()
|
||||
{
|
||||
using std::shared_ptr;
|
||||
using std::static_pointer_cast;
|
||||
using std::const_pointer_cast;
|
||||
using std::dynamic_pointer_cast;
|
||||
|
||||
int* ptr = new int(1);
|
||||
shared_ptr<const void> pcv(ptr);
|
||||
auto pci = static_pointer_cast<const int>(pcv);
|
||||
VERIFY(pci.use_count() == 2);
|
||||
VERIFY(pcv.use_count() == 2);
|
||||
VERIFY(pci.get() == ptr);
|
||||
VERIFY(pcv.get() == ptr);
|
||||
auto pi = const_pointer_cast<int>(pci);
|
||||
VERIFY(pi.use_count() == 3);
|
||||
VERIFY(pcv.use_count() == 3);
|
||||
VERIFY(pi.get() == ptr);
|
||||
VERIFY(pci.get() == ptr);
|
||||
|
||||
MyP* pptr = new MyP;
|
||||
shared_ptr<MyP> pp(pptr);
|
||||
auto pdp = dynamic_pointer_cast<MyDP>(pp);
|
||||
VERIFY(pp.use_count() == 1);
|
||||
VERIFY(pdp.use_count() == 0);
|
||||
VERIFY(pdp.get() == nullptr);
|
||||
VERIFY(pp.get() == pptr);
|
||||
pptr = new MyDP;
|
||||
pp.reset(pptr);
|
||||
pdp = dynamic_pointer_cast<MyDP>(pp);
|
||||
VERIFY(pp.use_count() == 2);
|
||||
VERIFY(pdp.use_count() == 2);
|
||||
VERIFY(pdp.get() == pptr);
|
||||
VERIFY(pp.get() == pptr);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// { dg-options "-std=gnu++17" }
|
||||
// { dg-do compile { target c++17 } }
|
||||
// { dg-do run { target c++17 } }
|
||||
|
||||
// Copyright (C) 2016-2019 Free Software Foundation, Inc.
|
||||
//
|
||||
|
@ -21,12 +21,14 @@
|
|||
// 20.11.2.2.9 shared_ptr casts [util.smartptr.shared.cast]
|
||||
|
||||
#include <memory>
|
||||
#include <testsuite_hooks.h>
|
||||
#include <testsuite_tr1.h>
|
||||
|
||||
struct MyP { virtual ~MyP() { }; };
|
||||
struct MyDP : MyP { };
|
||||
|
||||
int main()
|
||||
void
|
||||
test01()
|
||||
{
|
||||
using __gnu_test::check_ret_type;
|
||||
using std::shared_ptr;
|
||||
|
@ -36,7 +38,28 @@ int main()
|
|||
shared_ptr<const int> spci;
|
||||
shared_ptr<MyP> spa;
|
||||
|
||||
check_ret_type<shared_ptr<void> >(reinterpret_pointer_cast<void>(spd));
|
||||
check_ret_type<shared_ptr<const short> >(reinterpret_pointer_cast<const short>(spci));
|
||||
check_ret_type<shared_ptr<MyDP> >(reinterpret_pointer_cast<MyDP>(spa));
|
||||
check_ret_type<shared_ptr<void>>(reinterpret_pointer_cast<void>(spd));
|
||||
check_ret_type<shared_ptr<const short>>(reinterpret_pointer_cast<const short>(spci));
|
||||
check_ret_type<shared_ptr<MyDP>>(reinterpret_pointer_cast<MyDP>(spa));
|
||||
}
|
||||
|
||||
void
|
||||
test02()
|
||||
{
|
||||
using std::shared_ptr;
|
||||
using std::reinterpret_pointer_cast;
|
||||
|
||||
int* ptr = new int(2);
|
||||
shared_ptr<int> pi(ptr);
|
||||
auto pl = reinterpret_pointer_cast<long>(pi);
|
||||
VERIFY(pi.use_count() == 2);
|
||||
VERIFY(pl.use_count() == 2);
|
||||
VERIFY(pi.get() == ptr);
|
||||
VERIFY(reinterpret_cast<int*>(pl.get()) == ptr);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
// { dg-options "-std=gnu++2a" }
|
||||
// { dg-do run { target c++2a } }
|
||||
|
||||
// Copyright (C) 2019 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/>.
|
||||
|
||||
// shared_ptr casts [util.smartptr.shared.cast]
|
||||
|
||||
#include <memory>
|
||||
#include <testsuite_hooks.h>
|
||||
#include <testsuite_tr1.h>
|
||||
|
||||
struct MyP { virtual ~MyP() { }; };
|
||||
struct MyDP : MyP { };
|
||||
|
||||
void test01()
|
||||
{
|
||||
using __gnu_test::check_ret_type;
|
||||
using std::shared_ptr;
|
||||
using std::static_pointer_cast;
|
||||
using std::const_pointer_cast;
|
||||
using std::dynamic_pointer_cast;
|
||||
using std::reinterpret_pointer_cast;
|
||||
|
||||
shared_ptr<double> spd;
|
||||
shared_ptr<const int> spci;
|
||||
shared_ptr<MyP> spa;
|
||||
|
||||
check_ret_type<shared_ptr<void>>(static_pointer_cast<void>(std::move(spd)));
|
||||
check_ret_type<shared_ptr<int>>(const_pointer_cast<int>(std::move(spci)));
|
||||
check_ret_type<shared_ptr<MyDP>>(dynamic_pointer_cast<MyDP>(std::move(spa)));
|
||||
check_ret_type<shared_ptr<void>>(reinterpret_pointer_cast<void>(std::move(spd)));
|
||||
check_ret_type<shared_ptr<const short>>(reinterpret_pointer_cast<const short>(std::move(spci)));
|
||||
check_ret_type<shared_ptr<MyDP>>(reinterpret_pointer_cast<MyDP>(std::move(spa)));
|
||||
}
|
||||
|
||||
void
|
||||
test02()
|
||||
{
|
||||
using std::shared_ptr;
|
||||
using std::static_pointer_cast;
|
||||
using std::const_pointer_cast;
|
||||
using std::dynamic_pointer_cast;
|
||||
using std::reinterpret_pointer_cast;
|
||||
|
||||
int* ptr = new int(1);
|
||||
shared_ptr<const void> pcv(ptr);
|
||||
auto pci = static_pointer_cast<const int>(std::move(pcv));
|
||||
VERIFY(pci.use_count() == 1);
|
||||
VERIFY(pcv.use_count() == 0);
|
||||
VERIFY(pci.get() == ptr);
|
||||
VERIFY(pcv.get() == nullptr);
|
||||
auto pi = const_pointer_cast<int>(std::move(pci));
|
||||
VERIFY(pi.use_count() == 1);
|
||||
VERIFY(pci.use_count() == 0);
|
||||
VERIFY(pi.get() == ptr);
|
||||
VERIFY(pci.get() == nullptr);
|
||||
|
||||
MyP* pptr = new MyP;
|
||||
shared_ptr<MyP> pp(pptr);
|
||||
auto pdp = dynamic_pointer_cast<MyDP>(std::move(pp));
|
||||
VERIFY(pdp.use_count() == 0);
|
||||
VERIFY(pp.use_count() == 1);
|
||||
VERIFY(pdp.get() == nullptr);
|
||||
VERIFY(pp.get() == pptr);
|
||||
pptr = new MyDP;
|
||||
pp.reset(pptr);
|
||||
pdp = dynamic_pointer_cast<MyDP>(std::move(pp));
|
||||
VERIFY(pdp.use_count() == 1);
|
||||
VERIFY(pp.use_count() == 0);
|
||||
VERIFY(pdp.get() == pptr);
|
||||
VERIFY(pp.get() == nullptr);
|
||||
|
||||
ptr = new int(2);
|
||||
pi.reset(ptr);
|
||||
auto pl = reinterpret_pointer_cast<long>(std::move(pi));
|
||||
VERIFY(pl.use_count() == 1);
|
||||
VERIFY(pi.use_count() == 0);
|
||||
VERIFY(reinterpret_cast<int*>(pl.get()) == ptr);
|
||||
VERIFY(pi.get() == nullptr);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
// { dg-options "-std=gnu++2a" }
|
||||
// { dg-do run { target c++2a } }
|
||||
|
||||
// Copyright (C) 2019 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/>.
|
||||
|
||||
// Template class shared_ptr [util.smartptr.shared]
|
||||
|
||||
#include <memory>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
struct A
|
||||
{
|
||||
A() : i() { }
|
||||
virtual ~A() { }
|
||||
int i;
|
||||
};
|
||||
|
||||
struct B : A
|
||||
{
|
||||
B() : A(), a() { }
|
||||
virtual ~B() { }
|
||||
A a;
|
||||
};
|
||||
|
||||
void deletefunc(A* p) { delete p; }
|
||||
|
||||
// 20.6.6.2.1 shared_ptr constructors [util.smartptr.shared.const]
|
||||
|
||||
// Aliasing constructors
|
||||
|
||||
void
|
||||
test01()
|
||||
{
|
||||
bool test = true;
|
||||
|
||||
std::shared_ptr<A> a;
|
||||
std::shared_ptr<bool> b1(std::move(a), &test);
|
||||
VERIFY( b1.use_count() == 0 );
|
||||
VERIFY( b1.get() == &test );
|
||||
VERIFY( a.use_count() == 0 );
|
||||
VERIFY( a == nullptr );
|
||||
|
||||
std::shared_ptr<bool> b2(b1);
|
||||
VERIFY( b2.use_count() == 0 );
|
||||
VERIFY( b1 == b2 );
|
||||
}
|
||||
|
||||
void
|
||||
test02()
|
||||
{
|
||||
std::shared_ptr<A> a(new A);
|
||||
std::shared_ptr<int> i1(std::move(a), &a->i);
|
||||
VERIFY( i1.use_count() == 1 );
|
||||
VERIFY( i1 != nullptr );
|
||||
VERIFY( a.use_count() == 0 );
|
||||
VERIFY( a == nullptr );
|
||||
|
||||
std::shared_ptr<int> i2(i1);
|
||||
VERIFY( i2.use_count() == 2 );
|
||||
VERIFY( i2.get() == &a->i );
|
||||
}
|
||||
|
||||
void
|
||||
test03()
|
||||
{
|
||||
std::shared_ptr<B> b1(new B);
|
||||
std::shared_ptr<B> b2(b1);
|
||||
std::shared_ptr<A> a1(std::move(b1), b1.get());
|
||||
std::shared_ptr<A> a2(b2, &b2->a);
|
||||
VERIFY( a2.use_count() == 2 );
|
||||
VERIFY( a1 != nullptr );
|
||||
VERIFY( a2 != nullptr );
|
||||
VERIFY( a1 != a2 );
|
||||
VERIFY( b1.use_count() == 0 );
|
||||
VERIFY( b2.use_count() == 0 );
|
||||
VERIFY( b1 == nullptr );
|
||||
VERIFY( b2 == nullptr );
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
test03();
|
||||
}
|
|
@ -42,7 +42,8 @@ void deletefunc(A* p) { delete p; }
|
|||
|
||||
// Aliasing constructors
|
||||
|
||||
int test01()
|
||||
void
|
||||
test01()
|
||||
{
|
||||
bool test = true;
|
||||
|
||||
|
@ -55,11 +56,9 @@ int test01()
|
|||
std::shared_ptr<bool> b2(b1);
|
||||
VERIFY( b2.use_count() == 0 );
|
||||
VERIFY( b1.get() == b2.get() );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
void
|
||||
test02()
|
||||
{
|
||||
std::shared_ptr<A> a(new A);
|
||||
|
@ -69,11 +68,9 @@ test02()
|
|||
std::shared_ptr<int> i2(i1);
|
||||
VERIFY( i2.use_count() == 3 );
|
||||
VERIFY( i2.get() == &a->i );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
void
|
||||
test03()
|
||||
{
|
||||
std::shared_ptr<B> b(new B);
|
||||
|
@ -89,8 +86,6 @@ test03()
|
|||
|
||||
a3 = a2;
|
||||
VERIFY( a3.get() == &b->a );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -99,5 +94,4 @@ main()
|
|||
test01();
|
||||
test02();
|
||||
test03();
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue