summaryrefslogtreecommitdiffstats
path: root/libcxx/test/std/utilities
diff options
context:
space:
mode:
authorEric Fiselier <eric@efcs.ca>2016-06-02 00:15:35 +0000
committerEric Fiselier <eric@efcs.ca>2016-06-02 00:15:35 +0000
commit88f5bfdc5bf6eb82a14f12f132f13feb3646bef8 (patch)
treee87cc8b1ad25f252fc23492d2eb58c89aaa5593e /libcxx/test/std/utilities
parentd063c5a1813f759720d59a571d0b22493a930f1e (diff)
downloadbcm5719-llvm-88f5bfdc5bf6eb82a14f12f132f13feb3646bef8.tar.gz
bcm5719-llvm-88f5bfdc5bf6eb82a14f12f132f13feb3646bef8.zip
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
Diffstat (limited to 'libcxx/test/std/utilities')
-rw-r--r--libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.enab/enable_shared_from_this.pass.cpp86
1 files changed, 86 insertions, 0 deletions
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.enab/enable_shared_from_this.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.enab/enable_shared_from_this.pass.cpp
index 77af13fa90d..4233d765320 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.enab/enable_shared_from_this.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.enab/enable_shared_from_this.pass.cpp
@@ -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
}
OpenPOWER on IntegriCloud