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