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
31struct GenericDeleter {
32 void operator()(void*) const;
33};
34
35template <bool IsArray>
36TEST_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
98template <bool IsArray>
99TEST_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
131TEST_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
144int main(int, char**) {
145 test();
146#if TEST_STD_VER >= 23
147 static_assert(test());
148#endif
149
150 return 0;
151}
152

source code of libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move.pass.cpp