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 /libstdc++-v3/include | |
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
Diffstat (limited to 'libstdc++-v3/include')
-rw-r--r-- | libstdc++-v3/include/bits/shared_ptr.h | 93 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/shared_ptr_base.h | 11 |
2 files changed, 95 insertions, 9 deletions
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; |