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 // <utility>
10
11 // template<ValueType T, size_t N>
12 // requires Swappable<T>
13 // void
14 // swap(T (&a)[N], T (&b)[N]);
15
16 #include <utility>
17 #include <cassert>
18 #include <memory>
19
20 #include "test_macros.h"
21
22
23 #if TEST_STD_VER >= 11
24 struct CopyOnly {
CopyOnlyCopyOnly25 CopyOnly() {}
CopyOnlyCopyOnly26 CopyOnly(CopyOnly const&) noexcept {}
operator =CopyOnly27 CopyOnly& operator=(CopyOnly const&) { return *this; }
28 };
29
30
31 struct NoexceptMoveOnly {
NoexceptMoveOnlyNoexceptMoveOnly32 NoexceptMoveOnly() {}
NoexceptMoveOnlyNoexceptMoveOnly33 NoexceptMoveOnly(NoexceptMoveOnly&&) noexcept {}
operator =NoexceptMoveOnly34 NoexceptMoveOnly& operator=(NoexceptMoveOnly&&) noexcept { return *this; }
35 };
36
37 struct NotMoveConstructible {
NotMoveConstructibleNotMoveConstructible38 NotMoveConstructible() {}
operator =NotMoveConstructible39 NotMoveConstructible& operator=(NotMoveConstructible&&) { return *this; }
40 private:
41 NotMoveConstructible(NotMoveConstructible&&);
42 };
43
44 template <class Tp>
45 auto can_swap_test(int) -> decltype(std::swap(std::declval<Tp>(), std::declval<Tp>()));
46
47 template <class Tp>
48 auto can_swap_test(...) -> std::false_type;
49
50 template <class Tp>
can_swap()51 constexpr bool can_swap() {
52 return std::is_same<decltype(can_swap_test<Tp>(0)), void>::value;
53 }
54 #endif
55
56 #if TEST_STD_VER > 17
test_swap_constexpr()57 constexpr bool test_swap_constexpr()
58 {
59 int i[3] = {1, 2, 3};
60 int j[3] = {4, 5, 6};
61 std::swap(i, j);
62 return i[0] == 4 &&
63 i[1] == 5 &&
64 i[2] == 6 &&
65 j[0] == 1 &&
66 j[1] == 2 &&
67 j[2] == 3;
68 }
69 #endif // TEST_STD_VER > 17
70
main(int,char **)71 int main(int, char**)
72 {
73 {
74 int i[3] = {1, 2, 3};
75 int j[3] = {4, 5, 6};
76 std::swap(i, j);
77 assert(i[0] == 4);
78 assert(i[1] == 5);
79 assert(i[2] == 6);
80 assert(j[0] == 1);
81 assert(j[1] == 2);
82 assert(j[2] == 3);
83 }
84 #if TEST_STD_VER >= 11
85 {
86 std::unique_ptr<int> i[3];
87 for (int k = 0; k < 3; ++k)
88 i[k].reset(new int(k+1));
89 std::unique_ptr<int> j[3];
90 for (int k = 0; k < 3; ++k)
91 j[k].reset(new int(k+4));
92 std::swap(i, j);
93 assert(*i[0] == 4);
94 assert(*i[1] == 5);
95 assert(*i[2] == 6);
96 assert(*j[0] == 1);
97 assert(*j[1] == 2);
98 assert(*j[2] == 3);
99 }
100 {
101 using CA = CopyOnly[42];
102 using MA = NoexceptMoveOnly[42];
103 using NA = NotMoveConstructible[42];
104 static_assert(can_swap<CA&>(), "");
105 static_assert(can_swap<MA&>(), "");
106 static_assert(!can_swap<NA&>(), "");
107
108 CA ca;
109 MA ma;
110 static_assert(!noexcept(std::swap(ca, ca)), "");
111 static_assert(noexcept(std::swap(ma, ma)), "");
112 }
113 #endif
114
115 #if TEST_STD_VER > 17
116 static_assert(test_swap_constexpr());
117 #endif // TEST_STD_VER > 17
118
119 return 0;
120 }
121