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// <memory>
12
13// unique_ptr
14
15// Test unique_ptr converting move assignment
16
17#include <memory>
18#include <utility>
19#include <cassert>
20
21#include "test_macros.h"
22#include "unique_ptr_test_helper.h"
23
24template <class APtr, class BPtr>
25void testAssign(APtr& aptr, BPtr& bptr) {
26 A* p = bptr.get();
27 assert(A::count == 2);
28 aptr = std::move(bptr);
29 assert(aptr.get() == p);
30 assert(bptr.get() == 0);
31 assert(A::count == 1);
32 assert(B::count == 1);
33}
34
35template <class LHS, class RHS>
36void checkDeleter(LHS& lhs, RHS& rhs, int LHSState, int RHSState) {
37 assert(lhs.get_deleter().state() == LHSState);
38 assert(rhs.get_deleter().state() == RHSState);
39}
40
41template <class T>
42struct NCConvertingDeleter {
43 NCConvertingDeleter() = default;
44 NCConvertingDeleter(NCConvertingDeleter const&) = delete;
45 NCConvertingDeleter(NCConvertingDeleter&&) = default;
46
47 template <class U>
48 NCConvertingDeleter(NCConvertingDeleter<U>&&) {}
49
50 void operator()(T*) const {}
51};
52
53template <class T>
54struct NCConvertingDeleter<T[]> {
55 NCConvertingDeleter() = default;
56 NCConvertingDeleter(NCConvertingDeleter const&) = delete;
57 NCConvertingDeleter(NCConvertingDeleter&&) = default;
58
59 template <class U>
60 NCConvertingDeleter(NCConvertingDeleter<U>&&) {}
61
62 void operator()(T*) const {}
63};
64
65struct GenericDeleter {
66 void operator()(void*) const;
67};
68
69struct NCGenericDeleter {
70 NCGenericDeleter() = default;
71 NCGenericDeleter(NCGenericDeleter const&) = delete;
72 NCGenericDeleter(NCGenericDeleter&&) = default;
73
74 void operator()(void*) const {}
75};
76
77void test_sfinae() {
78 using DA = NCConvertingDeleter<A[]>; // non-copyable deleters
79 using DAC = NCConvertingDeleter<const A[]>; // non-copyable deleters
80
81 using UA = std::unique_ptr<A[]>;
82 using UAC = std::unique_ptr<const A[]>;
83 using UAD = std::unique_ptr<A[], DA>;
84 using UACD = std::unique_ptr<const A[], DAC>;
85
86 { // cannot move from an lvalue
87 static_assert(std::is_assignable<UAC, UA&&>::value, "");
88 static_assert(!std::is_assignable<UAC, UA&>::value, "");
89 static_assert(!std::is_assignable<UAC, const UA&>::value, "");
90 }
91 { // cannot move if the deleter-types cannot convert
92 static_assert(std::is_assignable<UACD, UAD&&>::value, "");
93 static_assert(!std::is_assignable<UACD, UAC&&>::value, "");
94 static_assert(!std::is_assignable<UAC, UACD&&>::value, "");
95 }
96 { // cannot move-convert with reference deleters of different types
97 using UA1 = std::unique_ptr<A[], DA&>;
98 using UA2 = std::unique_ptr<A[], DAC&>;
99 static_assert(!std::is_assignable<UA1, UA2&&>::value, "");
100 }
101 { // cannot move-convert with reference deleters of different types
102 using UA1 = std::unique_ptr<A[], const DA&>;
103 using UA2 = std::unique_ptr<A[], const DAC&>;
104 static_assert(!std::is_assignable<UA1, UA2&&>::value, "");
105 }
106 { // cannot move-convert with reference deleters with different qualifiers
107 using UA1 = std::unique_ptr<A[], DA&>;
108 using UA2 = std::unique_ptr<A[], const DA&>;
109 static_assert(!std::is_assignable<UA1, UA2&&>::value, "");
110 static_assert(!std::is_assignable<UA2, UA1&&>::value, "");
111 }
112 { // cannot move-convert from unique_ptr<Single>
113 using UA1 = std::unique_ptr<A[]>;
114 using UA2 = std::unique_ptr<A>;
115 static_assert(!std::is_assignable<UA1, UA2&&>::value, "");
116 }
117 { // cannot move-convert from unique_ptr<Array[]>
118 using UA1 = std::unique_ptr<A[], NCGenericDeleter>;
119 using UA2 = std::unique_ptr<A, NCGenericDeleter>;
120 static_assert(!std::is_assignable<UA1, UA2&&>::value, "");
121 }
122}
123
124int main(int, char**) {
125 test_sfinae();
126 // FIXME: add tests
127
128 return 0;
129}
130

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