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// weak_ptr
13
14// template<class Y> weak_ptr(const weak_ptr<Y>& r);
15// template<class Y> weak_ptr(weak_ptr<Y> &&r);
16
17#include <memory>
18#include <type_traits>
19#include <cassert>
20
21struct B
22{
23    static int count;
24
25    B() {++count;}
26    B(const B&) {++count;}
27    virtual ~B() {--count;}
28};
29
30int B::count = 0;
31
32struct A
33    : public B
34{
35    static int count;
36
37    A() {++count;}
38    A(const A&) {++count;}
39    ~A() {--count;}
40};
41
42int A::count = 0;
43
44struct C
45{
46    static int count;
47
48    C() {++count;}
49    C(const C&) {++count;}
50    virtual ~C() {--count;}
51};
52
53int C::count = 0;
54
55template <class T>
56std::weak_ptr<T> source (std::shared_ptr<T> p) { return std::weak_ptr<T>(p); }
57
58template <class T>
59void sink (std::weak_ptr<T> &&) {}
60
61int main()
62{
63    static_assert(( std::is_convertible<std::weak_ptr<A>, std::weak_ptr<B> >::value), "");
64    static_assert((!std::is_convertible<std::weak_ptr<B>, std::weak_ptr<A> >::value), "");
65    static_assert((!std::is_convertible<std::weak_ptr<A>, std::weak_ptr<C> >::value), "");
66    {
67        const std::weak_ptr<A> pA(std::shared_ptr<A>(new A));
68        assert(pA.use_count() == 0);
69        assert(B::count == 0);
70        assert(A::count == 0);
71        {
72            std::weak_ptr<B> pB(pA);
73            assert(B::count == 0);
74            assert(A::count == 0);
75            assert(pB.use_count() == 0);
76            assert(pA.use_count() == 0);
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::weak_ptr<A> pA;
86        assert(pA.use_count() == 0);
87        assert(B::count == 0);
88        assert(A::count == 0);
89        {
90            std::weak_ptr<B> pB(pA);
91            assert(B::count == 0);
92            assert(A::count == 0);
93            assert(pB.use_count() == 0);
94            assert(pA.use_count() == 0);
95        }
96        assert(pA.use_count() == 0);
97        assert(B::count == 0);
98        assert(A::count == 0);
99    }
100    assert(B::count == 0);
101    assert(A::count == 0);
102
103    {
104        std::shared_ptr<A> ps(new A);
105        std::weak_ptr<A> pA = source(ps);
106        std::weak_ptr<B> pB(std::move(pA));
107        assert(pB.use_count() == 1);
108    }
109    assert(B::count == 0);
110    assert(A::count == 0);
111}
112