aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/include
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2019-05-23 22:41:02 +0100
committerJonathan Wakely <redi@gcc.gnu.org>2019-05-23 22:41:02 +0100
commitfb3fc4bded8d934b603a7f07ab3cfe3b644ee971 (patch)
tree67451d2c9a410bc5b50675eb33d8405ddc6aa134 /libstdc++-v3/include
parent9a0af7e3fb425ae2c0e044d044feb81ef493ce2c (diff)
downloadgcc-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.h93
-rw-r--r--libstdc++-v3/include/bits/shared_ptr_base.h11
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;