]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/pointer.pass.cpp
Vendor import of libc++ 4.0.0 release r297347:
[FreeBSD/FreeBSD.git] / test / std / utilities / memory / unique.ptr / unique.ptr.single / unique.ptr.single.ctor / pointer.pass.cpp
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 //=============================================================================
15 // TESTING std::unique_ptr::unique_ptr()
16 //
17 // Concerns:
18 //   1 The pointer constructor works for any default constructible deleter types.
19 //   2 The pointer constructor accepts pointers to derived types.
20 //   2 The stored type 'T' is allowed to be incomplete.
21 //
22 // Plan
23 //  1 Construct unique_ptr<T, D>'s with a pointer to 'T' and various deleter
24 //   types (C-1)
25 //  2 Construct unique_ptr<T, D>'s with a pointer to 'D' and various deleter
26 //    types where 'D' is derived from 'T'. (C-1,2)
27 //  3 Construct a unique_ptr<T, D> with a pointer to 'T' and various deleter
28 //    types where 'T' is an incomplete type (C-1,3)
29
30 // Test unique_ptr(pointer) ctor
31
32 #include <memory>
33 #include <cassert>
34
35 #include "../../deleter.h"
36
37 // unique_ptr(pointer) ctor should only require default Deleter ctor
38
39 struct A
40 {
41     static int count;
42     A() {++count;}
43     A(const A&) {++count;}
44     virtual ~A() {--count;}
45 };
46
47 int A::count = 0;
48
49
50 struct B
51     : public A
52 {
53     static int count;
54     B() {++count;}
55     B(const B&) {++count;}
56     virtual ~B() {--count;}
57 };
58
59 int B::count = 0;
60
61
62 struct IncompleteT;
63
64 IncompleteT* getIncomplete();
65 void checkNumIncompleteTypeAlive(int i);
66
67 template <class Del = std::default_delete<IncompleteT> >
68 struct StoresIncomplete {
69   std::unique_ptr<IncompleteT, Del> m_ptr;
70   StoresIncomplete() {}
71   explicit StoresIncomplete(IncompleteT* ptr) : m_ptr(ptr) {}
72   ~StoresIncomplete();
73
74   IncompleteT* get() const { return m_ptr.get(); }
75   Del& get_deleter() { return m_ptr.get_deleter(); }
76 };
77
78 void test_pointer()
79 {
80     {
81         A* p = new A;
82         assert(A::count == 1);
83         std::unique_ptr<A> s(p);
84         assert(s.get() == p);
85     }
86     assert(A::count == 0);
87     {
88         A* p = new A;
89         assert(A::count == 1);
90         std::unique_ptr<A, NCDeleter<A> > s(p);
91         assert(s.get() == p);
92         assert(s.get_deleter().state() == 0);
93     }
94     assert(A::count == 0);
95 }
96
97 void test_derived()
98 {
99     {
100         B* p = new B;
101         assert(A::count == 1);
102         assert(B::count == 1);
103         std::unique_ptr<A> s(p);
104         assert(s.get() == p);
105     }
106     assert(A::count == 0);
107     assert(B::count == 0);
108     {
109         B* p = new B;
110         assert(A::count == 1);
111         assert(B::count == 1);
112         std::unique_ptr<A, NCDeleter<A> > s(p);
113         assert(s.get() == p);
114         assert(s.get_deleter().state() == 0);
115     }
116     assert(A::count == 0);
117     assert(B::count == 0);
118 }
119
120 void test_incomplete()
121 {
122     {
123         IncompleteT* p = getIncomplete();
124         checkNumIncompleteTypeAlive(1);
125         StoresIncomplete<> s(p);
126         assert(s.get() == p);
127     }
128     checkNumIncompleteTypeAlive(0);
129     {
130         IncompleteT* p = getIncomplete();
131         checkNumIncompleteTypeAlive(1);
132         StoresIncomplete< NCDeleter<IncompleteT> > s(p);
133         assert(s.get() == p);
134         assert(s.get_deleter().state() == 0);
135     }
136     checkNumIncompleteTypeAlive(0);
137 }
138
139 struct IncompleteT {
140     static int count;
141     IncompleteT() { ++count; }
142     ~IncompleteT() {--count; }
143 };
144
145 int IncompleteT::count = 0;
146
147 IncompleteT* getIncomplete() {
148     return new IncompleteT;
149 }
150
151 void checkNumIncompleteTypeAlive(int i) {
152     assert(IncompleteT::count == i);
153 }
154
155 template <class Del>
156 StoresIncomplete<Del>::~StoresIncomplete() { }
157
158 int main()
159 {
160     test_pointer();
161     test_derived();
162     test_incomplete();
163 }