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 assignement post-conditions are tested.
12 // ADDITIONAL_COMPILE_FLAGS: -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 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 assert(A::count == (expect_alive * 2));
44 s2 = std::move(s1);
45 assert(A::count == expect_alive);
46 assert(s2.get() == p);
47 assert(s1.get() == 0);
48 }
49 assert(A::count == 0);
50 {
51 std::unique_ptr<VT, Deleter<VT> > s1(newValue<VT>(expect_alive),
52 Deleter<VT>(5));
53 A* p = s1.get();
54 std::unique_ptr<VT, Deleter<VT> > s2(newValue<VT>(expect_alive));
55 assert(A::count == (expect_alive * 2));
56 s2 = std::move(s1);
57 assert(s2.get() == p);
58 assert(s1.get() == 0);
59 assert(A::count == expect_alive);
60 assert(s2.get_deleter().state() == 5);
61 assert(s1.get_deleter().state() == 0);
62 }
63 assert(A::count == 0);
64 {
65 CDeleter<VT> d1(5);
66 std::unique_ptr<VT, CDeleter<VT>&> s1(newValue<VT>(expect_alive), d1);
67 A* p = s1.get();
68 CDeleter<VT> d2(6);
69 std::unique_ptr<VT, CDeleter<VT>&> s2(newValue<VT>(expect_alive), d2);
70 s2 = std::move(s1);
71 assert(s2.get() == p);
72 assert(s1.get() == 0);
73 assert(A::count == expect_alive);
74 assert(d1.state() == 5);
75 assert(d2.state() == 5);
76 }
77 assert(A::count == 0);
78 {
79 std::unique_ptr<VT> s(newValue<VT>(expect_alive));
80 A* p = s.get();
81 s = std::move(s);
82 assert(A::count == expect_alive);
83 assert(s.get() == p);
84 }
85 assert(A::count == 0);
86 }
87
88 template <bool IsArray>
test_sfinae()89 void test_sfinae() {
90 typedef typename std::conditional<IsArray, int[], int>::type VT;
91 {
92 typedef std::unique_ptr<VT> U;
93 static_assert(!std::is_assignable<U, U&>::value, "");
94 static_assert(!std::is_assignable<U, const U&>::value, "");
95 static_assert(!std::is_assignable<U, const U&&>::value, "");
96 static_assert(std::is_nothrow_assignable<U, U&&>::value, "");
97 }
98 {
99 typedef std::unique_ptr<VT, GenericDeleter> U;
100 static_assert(!std::is_assignable<U, U&>::value, "");
101 static_assert(!std::is_assignable<U, const U&>::value, "");
102 static_assert(!std::is_assignable<U, const U&&>::value, "");
103 static_assert(std::is_nothrow_assignable<U, U&&>::value, "");
104 }
105 {
106 typedef std::unique_ptr<VT, NCDeleter<VT>&> U;
107 static_assert(!std::is_assignable<U, U&>::value, "");
108 static_assert(!std::is_assignable<U, const U&>::value, "");
109 static_assert(!std::is_assignable<U, const U&&>::value, "");
110 static_assert(std::is_nothrow_assignable<U, U&&>::value, "");
111 }
112 {
113 typedef std::unique_ptr<VT, const NCDeleter<VT>&> U;
114 static_assert(!std::is_assignable<U, U&>::value, "");
115 static_assert(!std::is_assignable<U, const U&>::value, "");
116 static_assert(!std::is_assignable<U, const U&&>::value, "");
117 static_assert(std::is_nothrow_assignable<U, U&&>::value, "");
118 }
119 }
120
121
main(int,char **)122 int main(int, char**) {
123 {
124 test_basic</*IsArray*/ false>();
125 test_sfinae<false>();
126 }
127 {
128 test_basic</*IsArray*/ true>();
129 test_sfinae<true>();
130 }
131
132 return 0;
133 }
134