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 swap(T (&a)[N], T (&b)[N]); // constexpr since C++20
14
15#include <algorithm>
16#include <cassert>
17#include <memory>
18#include <type_traits>
19#include <utility>
20
21#include "test_macros.h"
22
23#if TEST_STD_VER >= 11
24struct CopyOnly {
25 TEST_CONSTEXPR_CXX20 CopyOnly() {}
26 TEST_CONSTEXPR_CXX20 CopyOnly(CopyOnly const&) noexcept {}
27 TEST_CONSTEXPR_CXX20 CopyOnly& operator=(CopyOnly const&) { return *this; }
28};
29
30struct NoexceptMoveOnly {
31 TEST_CONSTEXPR_CXX20 NoexceptMoveOnly() {}
32 TEST_CONSTEXPR_CXX20 NoexceptMoveOnly(NoexceptMoveOnly&&) noexcept {}
33 TEST_CONSTEXPR_CXX20 NoexceptMoveOnly& operator=(NoexceptMoveOnly&&) noexcept { return *this; }
34};
35
36struct NotMoveConstructible {
37 TEST_CONSTEXPR_CXX20 NotMoveConstructible() {}
38 TEST_CONSTEXPR_CXX20 NotMoveConstructible& operator=(NotMoveConstructible&&) { return *this; }
39 NotMoveConstructible(NotMoveConstructible&&) = delete;
40};
41
42template <class Tp>
43auto can_swap_test(int) -> decltype(std::swap(std::declval<Tp>(), std::declval<Tp>()));
44
45template <class Tp>
46auto can_swap_test(...) -> std::false_type;
47
48template <class Tp>
49constexpr bool can_swap() {
50 return std::is_same<decltype(can_swap_test<Tp>(0)), void>::value;
51}
52
53TEST_CONSTEXPR_CXX23 void test_unique_ptr() {
54 std::unique_ptr<int> i[3];
55 for (int k = 0; k < 3; ++k)
56 i[k].reset(new int(k + 1));
57 std::unique_ptr<int> j[3];
58 for (int k = 0; k < 3; ++k)
59 j[k].reset(new int(k + 4));
60 std::swap(i, j);
61 assert(*i[0] == 4);
62 assert(*i[1] == 5);
63 assert(*i[2] == 6);
64 assert(*j[0] == 1);
65 assert(*j[1] == 2);
66 assert(*j[2] == 3);
67}
68#endif
69
70TEST_CONSTEXPR_CXX20 bool test() {
71 {
72 int i[3] = {1, 2, 3};
73 int j[3] = {4, 5, 6};
74 std::swap(a&: i, b&: j);
75 assert(i[0] == 4);
76 assert(i[1] == 5);
77 assert(i[2] == 6);
78 assert(j[0] == 1);
79 assert(j[1] == 2);
80 assert(j[2] == 3);
81 }
82 {
83 int a[2][2] = {{0, 1}, {2, 3}};
84 decltype(a) b = {{9, 8}, {7, 6}};
85
86 std::swap(a&: a, b&: b);
87
88 assert(a[0][0] == 9);
89 assert(a[0][1] == 8);
90 assert(a[1][0] == 7);
91 assert(a[1][1] == 6);
92
93 assert(b[0][0] == 0);
94 assert(b[0][1] == 1);
95 assert(b[1][0] == 2);
96 assert(b[1][1] == 3);
97 }
98
99 {
100 int a[3][3] = {{0, 1, 2}, {3, 4, 5}, {6, 7, 8}};
101 decltype(a) b = {{9, 8, 7}, {6, 5, 4}, {3, 2, 1}};
102
103 std::swap(a&: a, b&: b);
104
105 assert(a[0][0] == 9);
106 assert(a[0][1] == 8);
107 assert(a[0][2] == 7);
108 assert(a[1][0] == 6);
109 assert(a[1][1] == 5);
110 assert(a[1][2] == 4);
111 assert(a[2][0] == 3);
112 assert(a[2][1] == 2);
113 assert(a[2][2] == 1);
114
115 assert(b[0][0] == 0);
116 assert(b[0][1] == 1);
117 assert(b[0][2] == 2);
118 assert(b[1][0] == 3);
119 assert(b[1][1] == 4);
120 assert(b[1][2] == 5);
121 assert(b[2][0] == 6);
122 assert(b[2][1] == 7);
123 assert(b[2][2] == 8);
124 }
125#if TEST_STD_VER >= 11
126 {
127 using CA = CopyOnly[42];
128 using MA = NoexceptMoveOnly[42];
129 using NA = NotMoveConstructible[42];
130 static_assert(can_swap<CA&>(), "");
131 static_assert(can_swap<MA&>(), "");
132 static_assert(!can_swap<NA&>(), "");
133
134 CA ca;
135 MA ma;
136 static_assert(!noexcept(std::swap(ca, ca)), "");
137 static_assert(noexcept(std::swap(ma, ma)), "");
138 }
139
140 if (TEST_STD_AT_LEAST_23_OR_RUNTIME_EVALUATED)
141 test_unique_ptr();
142#endif
143
144 return true;
145}
146
147int main(int, char**) {
148 test();
149#if TEST_STD_VER >= 20
150 static_assert(test());
151#endif
152
153 return 0;
154}
155

source code of libcxx/test/std/utilities/utility/utility.swap/swap_array.pass.cpp