forked from OSchip/llvm-project
Implement P0033R1 - Re-enabling shared_from_this
Summary: See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0033r1.html Reviewers: mclow.lists Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D19254 llvm-svn: 271449
This commit is contained in:
parent
d063c5a181
commit
88f5bfdc5b
|
@ -4120,7 +4120,7 @@ private:
|
|||
void
|
||||
__enable_weak_this(const enable_shared_from_this<_Yp>* __e) _NOEXCEPT
|
||||
{
|
||||
if (__e)
|
||||
if (__e && __e->__weak_this_.expired())
|
||||
{
|
||||
__e->__weak_this_.__ptr_ = const_cast<_Yp*>(static_cast<const _Yp*>(__e));
|
||||
__e->__weak_this_.__cntrl_ = __cntrl_;
|
||||
|
@ -5432,6 +5432,16 @@ public:
|
|||
shared_ptr<_Tp const> shared_from_this() const
|
||||
{return shared_ptr<const _Tp>(__weak_this_);}
|
||||
|
||||
#if _LIBCPP_STD_VER > 14
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
weak_ptr<_Tp> weak_from_this() _NOEXCEPT
|
||||
{ return __weak_this_; }
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
weak_ptr<const _Tp> weak_from_this() const _NOEXCEPT
|
||||
{ return __weak_this_; }
|
||||
#endif // _LIBCPP_STD_VER > 14
|
||||
|
||||
template <class _Up> friend class shared_ptr;
|
||||
};
|
||||
|
||||
|
|
|
@ -18,11 +18,15 @@
|
|||
// public:
|
||||
// shared_ptr<T> shared_from_this();
|
||||
// shared_ptr<T const> shared_from_this() const;
|
||||
// weak_ptr<T> weak_from_this() noexcept; // C++17
|
||||
// weak_ptr<T const> weak_from_this() const noexecpt; // C++17
|
||||
// };
|
||||
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
struct T
|
||||
: public std::enable_shared_from_this<T>
|
||||
{
|
||||
|
@ -32,6 +36,8 @@ struct Y : T {};
|
|||
|
||||
struct Z : Y {};
|
||||
|
||||
void nullDeleter(void*) {}
|
||||
|
||||
int main()
|
||||
{
|
||||
{ // https://llvm.org/bugs/show_bug.cgi?id=18843
|
||||
|
@ -50,4 +56,84 @@ int main()
|
|||
assert(p == q);
|
||||
assert(!p.owner_before(q) && !q.owner_before(p)); // p and q share ownership
|
||||
}
|
||||
// Test LWG issue 2529. Only reset '__weak_ptr_' when it's already expired.
|
||||
// http://cplusplus.github.io/LWG/lwg-active.html#2529.
|
||||
// Test two different ways:
|
||||
// * Using 'weak_from_this().expired()' in C++17.
|
||||
// * Using 'shared_from_this()' in all dialects.
|
||||
{
|
||||
|
||||
T* ptr = new T;
|
||||
std::shared_ptr<T> s(ptr);
|
||||
{
|
||||
// Don't re-initialize the "enabled_shared_from_this" base
|
||||
// because it already references a non-expired shared_ptr.
|
||||
std::shared_ptr<T> s2(ptr, &nullDeleter);
|
||||
}
|
||||
#if TEST_STD_VER > 14
|
||||
// The enabled_shared_from_this base should still be referencing
|
||||
// the original shared_ptr.
|
||||
assert(!ptr->weak_from_this().expired());
|
||||
#endif
|
||||
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||
{
|
||||
try {
|
||||
std::shared_ptr<T> new_s = ptr->shared_from_this();
|
||||
assert(new_s == s);
|
||||
} catch (std::bad_weak_ptr const&) {
|
||||
assert(false);
|
||||
} catch (...) {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
// Test LWG issue 2529 again. This time check that an expired pointer
|
||||
// is replaced.
|
||||
{
|
||||
T* ptr = new T;
|
||||
std::weak_ptr<T> weak;
|
||||
{
|
||||
std::shared_ptr<T> s(ptr, &nullDeleter);
|
||||
assert(ptr->shared_from_this() == s);
|
||||
weak = s;
|
||||
assert(!weak.expired());
|
||||
}
|
||||
assert(weak.expired());
|
||||
weak.reset();
|
||||
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||
try {
|
||||
ptr->shared_from_this();
|
||||
assert(false);
|
||||
} catch (std::bad_weak_ptr const&) {
|
||||
} catch (...) { assert(false); }
|
||||
#endif
|
||||
{
|
||||
std::shared_ptr<T> s2(ptr, &nullDeleter);
|
||||
assert(ptr->shared_from_this() == s2);
|
||||
}
|
||||
delete ptr;
|
||||
}
|
||||
// Test weak_from_this_methods
|
||||
#if TEST_STD_VER > 14
|
||||
{
|
||||
T* ptr = new T;
|
||||
const T* cptr = ptr;
|
||||
|
||||
static_assert(noexcept(ptr->weak_from_this()), "Operation must be noexcept");
|
||||
static_assert(noexcept(cptr->weak_from_this()), "Operation must be noexcept");
|
||||
|
||||
std::weak_ptr<T> my_weak = ptr->weak_from_this();
|
||||
assert(my_weak.expired());
|
||||
|
||||
std::weak_ptr<T const> my_const_weak = cptr->weak_from_this();
|
||||
assert(my_const_weak.expired());
|
||||
|
||||
// Enable shared_from_this with ptr.
|
||||
std::shared_ptr<T> sptr(ptr);
|
||||
my_weak = ptr->weak_from_this();
|
||||
assert(!my_weak.expired());
|
||||
assert(my_weak.lock().get() == ptr);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@
|
|||
<tr><td><a href="http://wg21.link/P0226R1">P0226R1</a></td><td>LWG</td><td>Mathematical Special Functions for C++17</td><td>Jacksonville</td><td></td><td></td></tr>
|
||||
<tr><td><a href="http://wg21.link/P0220R1">P0220R1</a></td><td>LWG</td><td>Adopt Library Fundamentals V1 TS Components for C++17</td><td>Jacksonville</td><td></td><td></td></tr>
|
||||
<tr><td><a href="http://wg21.link/P0218R1">P0218R1</a></td><td>LWG</td><td>Adopt the File System TS for C++17</td><td>Jacksonville</td><td></td><td></td></tr>
|
||||
<tr><td><a href="http://wg21.link/P0033R1">P0033R1</a></td><td>LWG</td><td>Re-enabling shared_from_this</td><td>Jacksonville</td><td></td><td></td></tr>
|
||||
<tr><td><a href="http://wg21.link/P0033R1">P0033R1</a></td><td>LWG</td><td>Re-enabling shared_from_this</td><td>Jacksonville</td><td>Complete</td><td>3.9</td></tr>
|
||||
<tr><td><a href="http://wg21.link/P0005R4">P0005R4</a></td><td>LWG</td><td>Adopt not_fn from Library Fundamentals 2 for C++17</td><td>Jacksonville</td><td></td><td></td></tr>
|
||||
<tr><td><a href="http://wg21.link/P0152R1">P0152R1</a></td><td>LWG</td><td>constexpr atomic::is_always_lock_free</td><td>Jacksonville</td><td>Complete</td><td>3.9</td></tr>
|
||||
<tr><td><a href="http://wg21.link/P0185R1">P0185R1</a></td><td>LWG</td><td>Adding [nothrow-]swappable traits</td><td>Jacksonville</td><td>Complete</td><td>3.9</td></tr>
|
||||
|
|
Loading…
Reference in New Issue