]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/93562.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / 20_util / unique_ptr / modifiers / 93562.cc
1 // Copyright (C) 2020-2023 Free Software Foundation, Inc.
2 //
3 // This file is part of the GNU ISO C++ Library. This library is free
4 // software; you can redistribute it and/or modify it under the
5 // terms of the GNU General Public License as published by the
6 // Free Software Foundation; either version 3, or (at your option)
7 // any later version.
8
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13
14 // You should have received a copy of the GNU General Public License along
15 // with this library; see the file COPYING3. If not see
16 // <http://www.gnu.org/licenses/>.
17
18 // { dg-do run { target c++11 } }
19
20 #include <memory>
21 #include <testsuite_hooks.h>
22
23 struct incomplete;
24
25 // This function isn't called, we just need to check it compiles.
26 void
27 test01(std::unique_ptr<incomplete>& p1, std::unique_ptr<incomplete>& p2)
28 {
29 // PR libstdc++/93562
30 p1.swap(p2);
31 swap(p1, p2);
32 }
33
34 // This function isn't called, we just need to check it compiles.
35 void
36 test02(std::unique_ptr<incomplete[]>& p1, std::unique_ptr<incomplete[]>& p2)
37 {
38 // PR libstdc++/93562
39 p1.swap(p2);
40 swap(p1, p2);
41 }
42
43 namespace A
44 {
45 struct Deleter
46 {
47 Deleter& operator=(const Deleter&) = delete;
48
49 void operator()(int* p) const noexcept { delete p; }
50
51 // found by ADL
52 friend void swap(Deleter& lhs, Deleter& rhs) noexcept
53 { std::swap(lhs.id, rhs.id); }
54
55 int id;
56 };
57
58 static_assert(!std::is_move_assignable<Deleter>::value, "not assignable");
59 #if __cplusplus >= 201703L
60 static_assert(std::is_swappable_v<Deleter>, "but swappable");
61 #endif
62 } // namespace A
63
64 void
65 test03()
66 {
67 std::unique_ptr<int, A::Deleter> p1(new int(1), { -1 });
68 std::unique_ptr<int, A::Deleter> p2(new int(2), { -2 });
69 int* const pi1 = p1.get();
70 int* const pi2 = p2.get();
71 // This type must swappable even though the deleter is not move-assignable:
72 swap(p1, p2);
73 VERIFY(p1.get() == pi2);
74 VERIFY(p1.get_deleter().id == -2);
75 VERIFY(p2.get() == pi1);
76 VERIFY(p2.get_deleter().id == -1);
77 }
78
79 void
80 test04()
81 {
82 std::unique_ptr<int[], A::Deleter> p1(new int[1]{1}, { -1 });
83 std::unique_ptr<int[], A::Deleter> p2(new int[2]{2, 2}, { -2 });
84 int* const pi1 = p1.get();
85 int* const pi2 = p2.get();
86 // This type must swappable even though the deleter is not move-assignable:
87 swap(p1, p2);
88 VERIFY(p1.get() == pi2);
89 VERIFY(p1.get_deleter().id == -2);
90 VERIFY(p2.get() == pi1);
91 VERIFY(p2.get_deleter().id == -1);
92 }
93
94 int main()
95 {
96 test03();
97 test04();
98 }