diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2019-05-23 22:41:02 +0100 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2019-05-23 22:41:02 +0100 |
commit | fb3fc4bded8d934b603a7f07ab3cfe3b644ee971 (patch) | |
tree | 67451d2c9a410bc5b50675eb33d8405ddc6aa134 | |
parent | 9a0af7e3fb425ae2c0e044d044feb81ef493ce2c (diff) | |
download | gcc-fb3fc4bded8d934b603a7f07ab3cfe3b644ee971.zip gcc-fb3fc4bded8d934b603a7f07ab3cfe3b644ee971.tar.gz gcc-fb3fc4bded8d934b603a7f07ab3cfe3b644ee971.tar.bz2 |
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
-rw-r--r-- | libstdc++-v3/ChangeLog | 16 | ||||
-rw-r--r-- | libstdc++-v3/doc/html/manual/api.html | 3 | ||||
-rw-r--r-- | libstdc++-v3/doc/html/manual/bugs.html | 10 | ||||
-rw-r--r-- | libstdc++-v3/doc/xml/manual/intro.xml | 8 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/shared_ptr.h | 93 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/shared_ptr_base.h | 11 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/shared_ptr/casts/1.cc | 55 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/shared_ptr/casts/reinterpret.cc | 33 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/shared_ptr/casts/rval.cc | 101 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/shared_ptr/cons/alias-rval.cc | 101 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/shared_ptr/cons/alias.cc | 14 |
11 files changed, 416 insertions, 29 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index e230f24..48b519e 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -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 diff --git a/libstdc++-v3/doc/html/manual/api.html b/libstdc++-v3/doc/html/manual/api.html index bb131d3..345c588 100644 --- a/libstdc++-v3/doc/html/manual/api.html +++ b/libstdc++-v3/doc/html/manual/api.html @@ -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>
\ No newline at end of file diff --git a/libstdc++-v3/doc/html/manual/bugs.html b/libstdc++-v3/doc/html/manual/bugs.html index f72404b..db30048 100644 --- a/libstdc++-v3/doc/html/manual/bugs.html +++ b/libstdc++-v3/doc/html/manual/bugs.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> diff --git a/libstdc++-v3/doc/xml/manual/intro.xml b/libstdc++-v3/doc/xml/manual/intro.xml index a216256..4a5d25f 100644 --- a/libstdc++-v3/doc/xml/manual/intro.xml +++ b/libstdc++-v3/doc/xml/manual/intro.xml @@ -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> diff --git a/libstdc++-v3/include/bits/shared_ptr.h b/libstdc++-v3/include/bits/shared_ptr.h index 8f219e7..41f6b12 100644 --- a/libstdc++-v3/include/bits/shared_ptr.h +++ b/libstdc++-v3/include/bits/shared_ptr.h @@ -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 // @} diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h index 968cc96..4acec1c 100644 --- a/libstdc++-v3/include/bits/shared_ptr_base.h +++ b/libstdc++-v3/include/bits/shared_ptr_base.h @@ -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; diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/casts/1.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/casts/1.cc index d689daf..f2b8a26 100644 --- a/libstdc++-v3/testsuite/20_util/shared_ptr/casts/1.cc +++ b/libstdc++-v3/testsuite/20_util/shared_ptr/casts/1.cc @@ -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(); } diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/casts/reinterpret.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/casts/reinterpret.cc index b16ac04..eae050f 100644 --- a/libstdc++-v3/testsuite/20_util/shared_ptr/casts/reinterpret.cc +++ b/libstdc++-v3/testsuite/20_util/shared_ptr/casts/reinterpret.cc @@ -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(); } diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/casts/rval.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/casts/rval.cc new file mode 100644 index 0000000..6f102b2 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/shared_ptr/casts/rval.cc @@ -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(); +} diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/alias-rval.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/alias-rval.cc new file mode 100644 index 0000000..205587c --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/alias-rval.cc @@ -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(); +} diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/alias.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/alias.cc index 841a51e..134a058 100644 --- a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/alias.cc +++ b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/alias.cc @@ -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; } |