1//===----------------------------------------------------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// <memory>
11
12// shared_ptr
13
14// template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r);
15
16#include <memory>
17#include <type_traits>
18#include <cassert>
19
20struct B
21{
22    static int count;
23
24    B() {++count;}
25    B(const B&) {++count;}
26    virtual ~B() {--count;}
27};
28
29int B::count = 0;
30
31struct A
32    : public B
33{
34    static int count;
35
36    A() {++count;}
37    A(const A&) {++count;}
38    ~A() {--count;}
39};
40
41int A::count = 0;
42
43int main()
44{
45#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
46    {
47        std::shared_ptr<A> pA(new A);
48        A* ptrA = pA.get();
49        {
50            std::shared_ptr<B> pB(new B);
51            pB = std::move(pA);
52            assert(B::count == 1);
53            assert(A::count == 1);
54            assert(pB.use_count() == 1);
55            assert(pA.use_count() == 0);
56            assert(pA.get() == 0);
57            assert(pB.get() == ptrA);
58        }
59        assert(pA.use_count() == 0);
60        assert(B::count == 0);
61        assert(A::count == 0);
62    }
63    assert(B::count == 0);
64    assert(A::count == 0);
65    {
66        std::shared_ptr<A> pA;
67        A* ptrA = pA.get();
68        {
69            std::shared_ptr<B> pB(new B);
70            pB = std::move(pA);
71            assert(B::count == 0);
72            assert(A::count == 0);
73            assert(pB.use_count() == 0);
74            assert(pA.use_count() == 0);
75            assert(pA.get() == 0);
76            assert(pB.get() == ptrA);
77        }
78        assert(pA.use_count() == 0);
79        assert(B::count == 0);
80        assert(A::count == 0);
81    }
82    assert(B::count == 0);
83    assert(A::count == 0);
84    {
85        std::shared_ptr<A> pA(new A);
86        A* ptrA = pA.get();
87        {
88            std::shared_ptr<B> pB;
89            pB = std::move(pA);
90            assert(B::count == 1);
91            assert(A::count == 1);
92            assert(pB.use_count() == 1);
93            assert(pA.use_count() == 0);
94            assert(pA.get() == 0);
95            assert(pB.get() == ptrA);
96        }
97        assert(pA.use_count() == 0);
98        assert(B::count == 0);
99        assert(A::count == 0);
100    }
101    assert(B::count == 0);
102    assert(A::count == 0);
103    {
104        std::shared_ptr<A> pA;
105        A* ptrA = pA.get();
106        {
107            std::shared_ptr<B> pB;
108            pB = std::move(pA);
109            assert(B::count == 0);
110            assert(A::count == 0);
111            assert(pB.use_count() == 0);
112            assert(pA.use_count() == 0);
113            assert(pA.get() == 0);
114            assert(pB.get() == ptrA);
115        }
116        assert(pA.use_count() == 0);
117        assert(B::count == 0);
118        assert(A::count == 0);
119    }
120    assert(B::count == 0);
121    assert(A::count == 0);
122#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
123}
124