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// unique_ptr
13
14// Test unique_ptr(pointer) ctor
15
16#include <memory>
17#include <cassert>
18
19// unique_ptr(pointer) ctor shouldn't require complete type
20
21struct A;
22
23class Deleter
24{
25    int state_;
26
27    Deleter(Deleter&);
28    Deleter& operator=(Deleter&);
29
30public:
31    Deleter() : state_(5) {}
32
33    int state() const {return state_;}
34
35    void operator()(A* p);
36};
37
38void check(int i);
39
40template <class D = std::default_delete<A> >
41struct B
42{
43    std::unique_ptr<A, D> a_;
44    explicit B(A*);
45    ~B();
46
47    A* get() const {return a_.get();}
48    D& get_deleter() {return a_.get_deleter();}
49};
50
51A* get();
52
53int main()
54{
55    {
56    A* p = get();
57    check(1);
58    B<> s(p);
59    assert(s.get() == p);
60    }
61    check(0);
62    {
63    A* p = get();
64    check(1);
65    B<Deleter> s(p);
66    assert(s.get() == p);
67    assert(s.get_deleter().state() == 5);
68    }
69    check(0);
70}
71
72struct A
73{
74    static int count;
75    A() {++count;}
76    A(const A&) {++count;}
77    ~A() {--count;}
78};
79
80int A::count = 0;
81
82A* get() {return new A;}
83
84void Deleter::operator()(A* p) {delete p;}
85
86void check(int i)
87{
88    assert(A::count == i);
89}
90
91template <class D>
92B<D>::B(A* a) : a_(a) {}
93
94template <class D>
95B<D>::~B() {}
96