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 // UNSUPPORTED: c++03
10
11 // Self assignment post-conditions are tested.
12 // ADDITIONAL_COMPILE_FLAGS(gcc-style-warnings): -Wno-self-move
13
14 // <memory>
15
16 // unique_ptr
17
18 // Test unique_ptr move assignment
19
20 // test move assignment. Should only require a MoveConstructible deleter, or if
21 // deleter is a reference, not even that.
22
23 #include <memory>
24 #include <utility>
25 #include <cassert>
26
27 #include "test_macros.h"
28 #include "deleter_types.h"
29 #include "unique_ptr_test_helper.h"
30
31 struct GenericDeleter {
32 void operator()(void*) const;
33 };
34
35 template <bool IsArray>
test_basic()36 TEST_CONSTEXPR_CXX23 void test_basic() {
37 typedef typename std::conditional<IsArray, A[], A>::type VT;
38 const int expect_alive = IsArray ? 5 : 1;
39 {
40 std::unique_ptr<VT> s1(newValue<VT>(expect_alive));
41 A* p = s1.get();
42 std::unique_ptr<VT> s2(newValue<VT>(expect_alive));
43 if (!TEST_IS_CONSTANT_EVALUATED)
44 assert(A::count == (expect_alive * 2));
45 s2 = std::move(s1);
46 if (!TEST_IS_CONSTANT_EVALUATED)
47 assert(A::count == expect_alive);
48 assert(s2.get() == p);
49 assert(s1.get() == 0);
50 }
51 if (!TEST_IS_CONSTANT_EVALUATED)
52 assert(A::count == 0);
53 {
54 std::unique_ptr<VT, Deleter<VT> > s1(newValue<VT>(expect_alive),
55 Deleter<VT>(5));
56 A* p = s1.get();
57 std::unique_ptr<VT, Deleter<VT> > s2(newValue<VT>(expect_alive));
58 if (!TEST_IS_CONSTANT_EVALUATED)
59 assert(A::count == (expect_alive * 2));
60 s2 = std::move(s1);
61 assert(s2.get() == p);
62 assert(s1.get() == 0);
63 if (!TEST_IS_CONSTANT_EVALUATED)
64 assert(A::count == expect_alive);
65 assert(s2.get_deleter().state() == 5);
66 assert(s1.get_deleter().state() == 0);
67 }
68 if (!TEST_IS_CONSTANT_EVALUATED)
69 assert(A::count == 0);
70 {
71 CDeleter<VT> d1(5);
72 std::unique_ptr<VT, CDeleter<VT>&> s1(newValue<VT>(expect_alive), d1);
73 A* p = s1.get();
74 CDeleter<VT> d2(6);
75 std::unique_ptr<VT, CDeleter<VT>&> s2(newValue<VT>(expect_alive), d2);
76 s2 = std::move(s1);
77 assert(s2.get() == p);
78 assert(s1.get() == 0);
79 if (!TEST_IS_CONSTANT_EVALUATED)
80 assert(A::count == expect_alive);
81 assert(d1.state() == 5);
82 assert(d2.state() == 5);
83 }
84 if (!TEST_IS_CONSTANT_EVALUATED)
85 assert(A::count == 0);
86 {
87 std::unique_ptr<VT> s(newValue<VT>(expect_alive));
88 A* p = s.get();
89 s = std::move(s);
90 if (!TEST_IS_CONSTANT_EVALUATED)
91 assert(A::count == expect_alive);
92 assert(s.get() == p);
93 }
94 if (!TEST_IS_CONSTANT_EVALUATED)
95 assert(A::count == 0);
96 }
97
98 template <bool IsArray>
test_sfinae()99 TEST_CONSTEXPR_CXX23 void test_sfinae() {
100 typedef typename std::conditional<IsArray, int[], int>::type VT;
101 {
102 typedef std::unique_ptr<VT> U;
103 static_assert(!std::is_assignable<U, U&>::value, "");
104 static_assert(!std::is_assignable<U, const U&>::value, "");
105 static_assert(!std::is_assignable<U, const U&&>::value, "");
106 static_assert(std::is_nothrow_assignable<U, U&&>::value, "");
107 }
108 {
109 typedef std::unique_ptr<VT, GenericDeleter> U;
110 static_assert(!std::is_assignable<U, U&>::value, "");
111 static_assert(!std::is_assignable<U, const U&>::value, "");
112 static_assert(!std::is_assignable<U, const U&&>::value, "");
113 static_assert(std::is_nothrow_assignable<U, U&&>::value, "");
114 }
115 {
116 typedef std::unique_ptr<VT, NCDeleter<VT>&> U;
117 static_assert(!std::is_assignable<U, U&>::value, "");
118 static_assert(!std::is_assignable<U, const U&>::value, "");
119 static_assert(!std::is_assignable<U, const U&&>::value, "");
120 static_assert(std::is_nothrow_assignable<U, U&&>::value, "");
121 }
122 {
123 typedef std::unique_ptr<VT, const NCDeleter<VT>&> U;
124 static_assert(!std::is_assignable<U, U&>::value, "");
125 static_assert(!std::is_assignable<U, const U&>::value, "");
126 static_assert(!std::is_assignable<U, const U&&>::value, "");
127 static_assert(std::is_nothrow_assignable<U, U&&>::value, "");
128 }
129 }
130
test()131 TEST_CONSTEXPR_CXX23 bool test() {
132 {
133 test_basic</*IsArray*/ false>();
134 test_sfinae<false>();
135 }
136 {
137 test_basic</*IsArray*/ true>();
138 test_sfinae<true>();
139 }
140
141 return true;
142 }
143
main(int,char **)144 int main(int, char**) {
145 test();
146 #if TEST_STD_VER >= 23
147 static_assert(test());
148 #endif
149
150 return 0;
151 }
152