blob: 7136253f33e88401b1195df42ce618f2ffe5ba26 [file] [log] [blame]
Eric Fiselier76581dc2015-07-31 02:43:52 +00001//===----------------------------------------------------------------------===//
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
11// <memory>
12
13// unique_ptr
14
15// Test unique_ptr converting move ctor
16
17// NOTE: unique_ptr does not provide converting constructors in c++03
18// XFAIL: c++98, c++03
19
20
21#include <memory>
22#include <type_traits>
23#include <utility>
24#include <cassert>
25
26#include "../../deleter.h"
27
28// test converting move ctor. Should only require a MoveConstructible deleter, or if
29// deleter is a reference, not even that.
30// Explicit version
31
32struct A
33{
34 static int count;
35 A() {++count;}
36 A(const A&) {++count;}
37 virtual ~A() {--count;}
38};
39
40int A::count = 0;
41
42struct B
43 : public A
44{
45 static int count;
46 B() {++count;}
47 B(const B&) {++count;}
48 virtual ~B() {--count;}
49};
50
51int B::count = 0;
52
Dan Albert1d4a1ed2016-05-25 22:36:09 -070053template <class OrigPtr, class NewPtr>
54void checkDeleter(OrigPtr& O, NewPtr& N, int OrigState, int NewState) {
55 typedef typename NewPtr::deleter_type NewDel;
56 if (std::is_reference<NewDel>::value) {
57 O.get_deleter().set_state(42);
58 assert(O.get_deleter().state() == 42);
59 assert(N.get_deleter().state() == 42);
60 O.get_deleter().set_state(99);
61 assert(O.get_deleter().state() == 99);
62 assert(N.get_deleter().state() == 99);
63 } else {
64 // TODO(EricWF) Enable this?
65 // assert(OrigState != NewState);
66 assert(O.get_deleter().state() == OrigState);
67 assert(N.get_deleter().state() == NewState);
68 }
Eric Fiselier76581dc2015-07-31 02:43:52 +000069}
70
Dan Albert1d4a1ed2016-05-25 22:36:09 -070071template <class APtr, class BPtr>
72void testMoveConvertExplicit()
73{
74 { // Test explicit constructor
75 BPtr s(new B);
76 A* p = s.get();
77 APtr s2(std::move(s));
78 assert(s2.get() == p);
79 assert(s.get() == 0);
80 assert(A::count == 1);
81 assert(B::count == 1);
82 }
Eric Fiselier76581dc2015-07-31 02:43:52 +000083 assert(A::count == 0);
84 assert(B::count == 0);
85}
86
Dan Albert1d4a1ed2016-05-25 22:36:09 -070087template <class APtr, class BPtr>
88void testMoveConvertImplicit() {
89
90 { // Test implicit constructor
91 BPtr s(new B);
92 A* p = s.get();
93 APtr s2 = std::move(s);
94 assert(s2.get() == p);
95 assert(s.get() == 0);
96 assert(A::count == 1);
97 assert(B::count == 1);
98 }
99 assert(A::count == 0);
100 assert(B::count == 0);
101}
102
103template <class APtr, class BPtr, class Deleter>
104#if TEST_STD_VER >= 11
105void testMoveConvertExplicit(Deleter&& del) {
106#else
107void testMoveConvert(Deleter& del) {
108#endif
109 int old_val = del.state();
110 { // Test Explicit constructor
111 BPtr s(new B, std::forward<Deleter>(del));
112 A* p = s.get();
113 APtr s2(std::move(s));
114 assert(s2.get() == p);
115 assert(s.get() == 0);
116 checkDeleter(s, s2, del.state(), old_val);
117 assert(A::count == 1);
118 assert(B::count == 1);
119 }
120 assert(A::count == 0);
121 assert(B::count == 0);
122}
123
124
125template <class APtr, class BPtr, class Deleter>
126#if TEST_STD_VER >= 11
127void testMoveConvertImplicit(Deleter&& del) {
128#else
129void testMoveConvertImplicit(Deleter& del) {
130#endif
131 int old_val = del.state();
132 { // Test Implicit constructor
133 BPtr s(new B, std::forward<Deleter>(del));
134 A* p = s.get();
135 APtr s2 = std::move(s);
136 assert(s2.get() == p);
137 assert(s.get() == 0);
138 checkDeleter(s, s2, del.state(), old_val);
139 assert(A::count == 1);
140 assert(B::count == 1);
141 }
142 assert(A::count == 0);
143 assert(B::count == 0);
144}
Eric Fiselier76581dc2015-07-31 02:43:52 +0000145int main()
146{
147 {
148 typedef std::unique_ptr<A> APtr;
149 typedef std::unique_ptr<B> BPtr;
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700150 testMoveConvertExplicit<APtr, BPtr>();
151 testMoveConvertImplicit<APtr, BPtr>();
Eric Fiselier76581dc2015-07-31 02:43:52 +0000152 }
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700153 {
Eric Fiselier76581dc2015-07-31 02:43:52 +0000154 typedef std::unique_ptr<A, Deleter<A> > APtr;
155 typedef std::unique_ptr<B, Deleter<B> > BPtr;
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700156 Deleter<B> del(5);
157 testMoveConvertExplicit<APtr, BPtr>(std::move(del));
158 del.set_state(5);
159 testMoveConvertImplicit<APtr, BPtr>(std::move(del));
Eric Fiselier76581dc2015-07-31 02:43:52 +0000160 }
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700161 {
Eric Fiselier76581dc2015-07-31 02:43:52 +0000162 typedef std::unique_ptr<A, NCDeleter<A>& > APtr;
163 typedef std::unique_ptr<B, NCDeleter<A>& > BPtr;
164 NCDeleter<A> del(5);
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700165 testMoveConvertExplicit<APtr, BPtr>(del);
166 testMoveConvertImplicit<APtr, BPtr>(del);
Eric Fiselier76581dc2015-07-31 02:43:52 +0000167 }
168 {
169 typedef std::unique_ptr<A, CDeleter<A> > APtr;
170 typedef std::unique_ptr<B, CDeleter<B>& > BPtr;
171 CDeleter<B> del(5);
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700172 testMoveConvertImplicit<APtr, BPtr>(del);
173 testMoveConvertExplicit<APtr, BPtr>(del);
Eric Fiselier76581dc2015-07-31 02:43:52 +0000174 }
175}