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