1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 // <memory>
10
11 // unique_ptr
12
13 // Test unique_ptr move ctor
14
15 #include <memory>
16 #include <utility>
17 #include <cassert>
18
19 #include "test_macros.h"
20 #include "unique_ptr_test_helper.h"
21
22 //=============================================================================
23 // TESTING unique_ptr(unique_ptr&&)
24 //
25 // Concerns
26 // 1 The moved from pointer is empty and the new pointer stores the old value.
27 // 2 The only requirement on the deleter is that it is MoveConstructible
28 // or a reference.
29 // 3 The constructor works for explicitly moved values (i.e. std::move(x))
30 // 4 The constructor works for true temporaries (e.g. a return value)
31 //
32 // Plan
33 // 1 Explicitly construct unique_ptr<T, D> for various deleter types 'D'.
34 // check that the value and deleter have been properly moved. (C-1,2,3)
35 //
36 // 2 Use the expression 'sink(source())' to move construct a unique_ptr<T, D>
37 // from a temporary. 'source' should return the unique_ptr by value and
38 // 'sink' should accept the unique_ptr by value. (C-1,2,4)
39
40 template <class VT>
source1()41 TEST_CONSTEXPR_CXX23 std::unique_ptr<VT> source1() {
42 return std::unique_ptr<VT>(newValue<VT>(1));
43 }
44
45 template <class VT>
source2()46 TEST_CONSTEXPR_CXX23 std::unique_ptr<VT, Deleter<VT> > source2() {
47 return std::unique_ptr<VT, Deleter<VT> >(newValue<VT>(1), Deleter<VT>(5));
48 }
49
50 template <class VT>
source3()51 std::unique_ptr<VT, NCDeleter<VT>&> source3() {
52 static NCDeleter<VT> d(5);
53 return std::unique_ptr<VT, NCDeleter<VT>&>(newValue<VT>(1), d);
54 }
55
56 template <class VT>
sink1(std::unique_ptr<VT> p)57 TEST_CONSTEXPR_CXX23 void sink1(std::unique_ptr<VT> p) {
58 assert(p.get() != nullptr);
59 }
60
61 template <class VT>
sink2(std::unique_ptr<VT,Deleter<VT>> p)62 TEST_CONSTEXPR_CXX23 void sink2(std::unique_ptr<VT, Deleter<VT> > p) {
63 assert(p.get() != nullptr);
64 assert(p.get_deleter().state() == 5);
65 }
66
67 template <class VT>
sink3(std::unique_ptr<VT,NCDeleter<VT> &> p)68 void sink3(std::unique_ptr<VT, NCDeleter<VT>&> p) {
69 assert(p.get() != nullptr);
70 assert(p.get_deleter().state() == 5);
71 assert(&p.get_deleter() == &source3<VT>().get_deleter());
72 }
73
74 template <class ValueT>
test_sfinae()75 TEST_CONSTEXPR_CXX23 void test_sfinae() {
76 typedef std::unique_ptr<ValueT> U;
77 { // Ensure unique_ptr is non-copyable
78 static_assert((!std::is_constructible<U, U const&>::value), "");
79 static_assert((!std::is_constructible<U, U&>::value), "");
80 }
81 }
82
83 template <bool IsArray>
test_basic()84 TEST_CONSTEXPR_CXX23 void test_basic() {
85 typedef typename std::conditional<!IsArray, A, A[]>::type VT;
86 const int expect_alive = IsArray ? 5 : 1;
87 {
88 typedef std::unique_ptr<VT> APtr;
89 APtr s(newValue<VT>(expect_alive));
90 A* p = s.get();
91 APtr s2 = std::move(s);
92 assert(s2.get() == p);
93 assert(s.get() == 0);
94 if (!TEST_IS_CONSTANT_EVALUATED)
95 assert(A::count == expect_alive);
96 }
97 if (!TEST_IS_CONSTANT_EVALUATED)
98 assert(A::count == 0);
99 {
100 typedef Deleter<VT> MoveDel;
101 typedef std::unique_ptr<VT, MoveDel> APtr;
102 MoveDel d(5);
103 APtr s(newValue<VT>(expect_alive), std::move(d));
104 assert(d.state() == 0);
105 assert(s.get_deleter().state() == 5);
106 A* p = s.get();
107 APtr s2 = std::move(s);
108 assert(s2.get() == p);
109 assert(s.get() == 0);
110 if (!TEST_IS_CONSTANT_EVALUATED)
111 assert(A::count == expect_alive);
112 assert(s2.get_deleter().state() == 5);
113 assert(s.get_deleter().state() == 0);
114 }
115 if (!TEST_IS_CONSTANT_EVALUATED)
116 assert(A::count == 0);
117 {
118 typedef NCDeleter<VT> NonCopyDel;
119 typedef std::unique_ptr<VT, NonCopyDel&> APtr;
120
121 NonCopyDel d;
122 APtr s(newValue<VT>(expect_alive), d);
123 A* p = s.get();
124 APtr s2 = std::move(s);
125 assert(s2.get() == p);
126 assert(s.get() == 0);
127 if (!TEST_IS_CONSTANT_EVALUATED)
128 assert(A::count == expect_alive);
129 d.set_state(6);
130 assert(s2.get_deleter().state() == d.state());
131 assert(s.get_deleter().state() == d.state());
132 }
133 if (!TEST_IS_CONSTANT_EVALUATED)
134 assert(A::count == 0);
135 {
136 sink1<VT>(source1<VT>());
137 if (!TEST_IS_CONSTANT_EVALUATED)
138 assert(A::count == 0);
139 sink2<VT>(source2<VT>());
140 if (!TEST_IS_CONSTANT_EVALUATED)
141 assert(A::count == 0);
142 }
143 if (!TEST_IS_CONSTANT_EVALUATED)
144 assert(A::count == 0);
145 }
146
147 template <class VT>
test_noexcept()148 TEST_CONSTEXPR_CXX23 void test_noexcept() {
149 #if TEST_STD_VER >= 11
150 {
151 typedef std::unique_ptr<VT> U;
152 static_assert(std::is_nothrow_move_constructible<U>::value, "");
153 }
154 {
155 typedef std::unique_ptr<VT, Deleter<VT> > U;
156 static_assert(std::is_nothrow_move_constructible<U>::value, "");
157 }
158 {
159 typedef std::unique_ptr<VT, NCDeleter<VT> &> U;
160 static_assert(std::is_nothrow_move_constructible<U>::value, "");
161 }
162 {
163 typedef std::unique_ptr<VT, const NCConstDeleter<VT> &> U;
164 static_assert(std::is_nothrow_move_constructible<U>::value, "");
165 }
166 #endif
167 }
168
test()169 TEST_CONSTEXPR_CXX23 bool test() {
170 {
171 test_basic</*IsArray*/ false>();
172 test_sfinae<int>();
173 test_noexcept<int>();
174 }
175 {
176 test_basic</*IsArray*/ true>();
177 test_sfinae<int[]>();
178 test_noexcept<int[]>();
179 }
180
181 return true;
182 }
183
184 template <bool IsArray>
test_sink3()185 void test_sink3() {
186 typedef typename std::conditional<!IsArray, A, A[]>::type VT;
187 sink3<VT>(source3<VT>());
188 assert(A::count == 0);
189 }
190
main(int,char **)191 int main(int, char**) {
192 test_sink3</*IsArray*/ false>();
193 test_sink3</*IsArray*/ true>();
194 test();
195 #if TEST_STD_VER >= 23
196 static_assert(test());
197 #endif
198
199 return 0;
200 }
201