diff options
| author | Eric Fiselier <eric@efcs.ca> | 2016-06-02 00:15:35 +0000 |
|---|---|---|
| committer | Eric Fiselier <eric@efcs.ca> | 2016-06-02 00:15:35 +0000 |
| commit | 88f5bfdc5bf6eb82a14f12f132f13feb3646bef8 (patch) | |
| tree | e87cc8b1ad25f252fc23492d2eb58c89aaa5593e /libcxx/test/std/utilities | |
| parent | d063c5a1813f759720d59a571d0b22493a930f1e (diff) | |
| download | bcm5719-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.cpp | 86 |
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 } |

