[RISCV] Fix mgather -> riscv.masked.strided.load combine not extending indices (...
[llvm-project.git] / libcxx / test / std / concepts / concepts.lang / concept.swappable / swappable_with.compile.pass.cpp
blob3d128eb8a9defbcb49257dbd3944d57486d9cfc2
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 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: c++03, c++11, c++14, c++17
11 // template<class T, class U>
12 // concept swappable_with = // see below
14 #include <concepts>
16 #include <array>
17 #include <cassert>
18 #include <deque>
19 #include <forward_list>
20 #include <list>
21 #include <map>
22 #include <memory>
23 #include <optional>
24 #include <set>
25 #include <unordered_map>
26 #include <unordered_set>
27 #include <vector>
29 #include "type_classification/moveconstructible.h"
30 #include "type_classification/swappable.h"
32 template <class T, class U>
33 constexpr bool check_swappable_with_impl() {
34 static_assert(std::swappable_with<T, U> == std::swappable_with<U, T>);
35 return std::swappable_with<T, U>;
38 template <class T, class U>
39 constexpr bool check_swappable_with() {
40 static_assert(!check_swappable_with_impl<T, U>());
41 static_assert(!check_swappable_with_impl<T, U const>());
42 static_assert(!check_swappable_with_impl<T const, U>());
43 static_assert(!check_swappable_with_impl<T const, U const>());
45 static_assert(!check_swappable_with_impl<T, U&>());
46 static_assert(!check_swappable_with_impl<T, U const&>());
47 static_assert(!check_swappable_with_impl<T, U volatile&>());
48 static_assert(!check_swappable_with_impl<T, U const volatile&>());
49 static_assert(!check_swappable_with_impl<T const, U&>());
50 static_assert(!check_swappable_with_impl<T const, U const&>());
51 static_assert(!check_swappable_with_impl<T const, U volatile&>());
52 static_assert(!check_swappable_with_impl<T const, U const volatile&>());
54 static_assert(!check_swappable_with_impl<T&, U>());
55 static_assert(!check_swappable_with_impl<T&, U const>());
56 static_assert(!check_swappable_with_impl<T const&, U>());
57 static_assert(!check_swappable_with_impl<T const&, U const>());
58 static_assert(!check_swappable_with_impl<T volatile&, U>());
59 static_assert(!check_swappable_with_impl<T volatile&, U const>());
60 static_assert(!check_swappable_with_impl<T const volatile&, U>());
61 static_assert(!check_swappable_with_impl<T const volatile&, U const>());
63 static_assert(!check_swappable_with_impl<T&, U const&>());
64 static_assert(!check_swappable_with_impl<T&, U volatile&>());
65 static_assert(!check_swappable_with_impl<T&, U const volatile&>());
66 static_assert(!check_swappable_with_impl<T const&, U&>());
67 static_assert(!check_swappable_with_impl<T const&, U const&>());
68 static_assert(!check_swappable_with_impl<T const&, U volatile&>());
69 static_assert(!check_swappable_with_impl<T const&, U const volatile&>());
70 static_assert(!check_swappable_with_impl<T volatile&, U&>());
71 static_assert(!check_swappable_with_impl<T volatile&, U const&>());
72 static_assert(!check_swappable_with_impl<T volatile&, U const volatile&>());
73 static_assert(!check_swappable_with_impl<T const volatile&, U&>());
74 static_assert(!check_swappable_with_impl<T const volatile&, U const&>());
75 static_assert(!check_swappable_with_impl<T const volatile&, U volatile&>());
76 static_assert(
77 !check_swappable_with_impl<T const volatile&, U const volatile&>());
79 static_assert(!check_swappable_with_impl<T, U&&>());
80 static_assert(!check_swappable_with_impl<T, U const&&>());
81 static_assert(!check_swappable_with_impl<T, U volatile&&>());
82 static_assert(!check_swappable_with_impl<T, U const volatile&&>());
83 static_assert(!check_swappable_with_impl<T const, U&&>());
84 static_assert(!check_swappable_with_impl<T const, U const&&>());
85 static_assert(!check_swappable_with_impl<T const, U volatile&&>());
86 static_assert(!check_swappable_with_impl<T const, U const volatile&&>());
88 static_assert(!check_swappable_with_impl<T&&, U>());
89 static_assert(!check_swappable_with_impl<T&&, U const>());
90 static_assert(!check_swappable_with_impl<T const&&, U>());
91 static_assert(!check_swappable_with_impl<T const&&, U const>());
92 static_assert(!check_swappable_with_impl<T volatile&&, U>());
93 static_assert(!check_swappable_with_impl<T volatile&&, U const>());
94 static_assert(!check_swappable_with_impl<T const volatile&&, U>());
95 static_assert(!check_swappable_with_impl<T const volatile&&, U const>());
97 static_assert(!check_swappable_with_impl<T&, U&&>());
98 static_assert(!check_swappable_with_impl<T&, U const&&>());
99 static_assert(!check_swappable_with_impl<T&, U volatile&&>());
100 static_assert(!check_swappable_with_impl<T&, U const volatile&&>());
101 static_assert(!check_swappable_with_impl<T const&, U&&>());
102 static_assert(!check_swappable_with_impl<T const&, U const&&>());
103 static_assert(!check_swappable_with_impl<T const&, U volatile&&>());
104 static_assert(!check_swappable_with_impl<T const&, U const volatile&&>());
105 static_assert(!check_swappable_with_impl<T volatile&, U&&>());
106 static_assert(!check_swappable_with_impl<T volatile&, U const&&>());
107 static_assert(!check_swappable_with_impl<T volatile&, U volatile&&>());
108 static_assert(!check_swappable_with_impl<T volatile&, U const volatile&&>());
109 static_assert(!check_swappable_with_impl<T const volatile&, U&&>());
110 static_assert(!check_swappable_with_impl<T const volatile&, U const&&>());
111 static_assert(!check_swappable_with_impl<T const volatile&, U volatile&&>());
112 static_assert(
113 !check_swappable_with_impl<T const volatile&, U const volatile&&>());
115 static_assert(!check_swappable_with_impl<T&&, U&>());
116 static_assert(!check_swappable_with_impl<T&&, U const&>());
117 static_assert(!check_swappable_with_impl<T&&, U volatile&>());
118 static_assert(!check_swappable_with_impl<T&&, U const volatile&>());
119 static_assert(!check_swappable_with_impl<T const&&, U&>());
120 static_assert(!check_swappable_with_impl<T const&&, U const&>());
121 static_assert(!check_swappable_with_impl<T const&&, U volatile&>());
122 static_assert(!check_swappable_with_impl<T const&&, U const volatile&>());
123 static_assert(!check_swappable_with_impl<T volatile&&, U&>());
124 static_assert(!check_swappable_with_impl<T volatile&&, U const&>());
125 static_assert(!check_swappable_with_impl<T volatile&&, U volatile&>());
126 static_assert(!check_swappable_with_impl<T volatile&&, U const volatile&>());
127 static_assert(!check_swappable_with_impl<T const volatile&&, U&>());
128 static_assert(!check_swappable_with_impl<T const volatile&&, U const&>());
129 static_assert(!check_swappable_with_impl<T const volatile&&, U volatile&>());
130 static_assert(
131 !check_swappable_with_impl<T const volatile&&, U const volatile&>());
133 static_assert(!check_swappable_with_impl<T&&, U&&>());
134 static_assert(!check_swappable_with_impl<T&&, U const&&>());
135 static_assert(!check_swappable_with_impl<T&&, U volatile&&>());
136 static_assert(!check_swappable_with_impl<T&&, U const volatile&&>());
137 static_assert(!check_swappable_with_impl<T const&&, U&&>());
138 static_assert(!check_swappable_with_impl<T const&&, U const&&>());
139 static_assert(!check_swappable_with_impl<T const&&, U volatile&&>());
140 static_assert(!check_swappable_with_impl<T const&&, U const volatile&&>());
141 static_assert(!check_swappable_with_impl<T volatile&&, U&&>());
142 static_assert(!check_swappable_with_impl<T volatile&&, U const&&>());
143 static_assert(!check_swappable_with_impl<T volatile&&, U volatile&&>());
144 static_assert(!check_swappable_with_impl<T volatile&&, U const volatile&&>());
145 static_assert(!check_swappable_with_impl<T const volatile&&, U&&>());
146 static_assert(!check_swappable_with_impl<T const volatile&&, U const&&>());
147 static_assert(!check_swappable_with_impl<T const volatile&&, U volatile&&>());
148 static_assert(
149 !check_swappable_with_impl<T const volatile&&, U const volatile&&>());
150 return check_swappable_with_impl<T&, U&>();
153 template <class T, class U>
154 constexpr bool check_swappable_with_including_lvalue_ref_to_volatile() {
155 constexpr auto result = check_swappable_with<T, U>();
156 static_assert(check_swappable_with_impl<T volatile&, U volatile&>() ==
157 result);
158 return result;
161 namespace fundamental {
162 static_assert(
163 check_swappable_with_including_lvalue_ref_to_volatile<int, int>());
164 static_assert(
165 check_swappable_with_including_lvalue_ref_to_volatile<double, double>());
166 static_assert(
167 !check_swappable_with_including_lvalue_ref_to_volatile<int, double>());
169 static_assert(
170 check_swappable_with_including_lvalue_ref_to_volatile<int*, int*>());
171 static_assert(
172 !check_swappable_with_including_lvalue_ref_to_volatile<int, int*>());
173 static_assert(check_swappable_with_including_lvalue_ref_to_volatile<
174 int (*)(), int (*)()>());
175 static_assert(
176 !check_swappable_with_including_lvalue_ref_to_volatile<int, int (*)()>());
178 struct S {};
179 static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<int, S>());
180 static_assert(check_swappable_with_including_lvalue_ref_to_volatile<
181 int S::*, int S::*>());
182 static_assert(
183 !check_swappable_with_including_lvalue_ref_to_volatile<int, int S::*>());
184 static_assert(check_swappable_with_including_lvalue_ref_to_volatile<
185 int (S::*)(), int (S::*)()>());
186 static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<
187 int, int (S::*)()>());
188 static_assert(check_swappable_with_including_lvalue_ref_to_volatile<
189 int (S::*)() noexcept, int (S::*)() noexcept>());
190 static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<
191 int (S::*)() noexcept, int (S::*)()>());
192 static_assert(check_swappable_with_including_lvalue_ref_to_volatile<
193 int (S::*)() const, int (S::*)() const>());
194 static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<
195 int (S::*)() const, int (S::*)()>());
196 static_assert(check_swappable_with_including_lvalue_ref_to_volatile<
197 int (S::*)() const noexcept, int (S::*)() const noexcept>());
198 static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<
199 int (S::*)() const, int (S::*)() const noexcept>());
200 static_assert(check_swappable_with_including_lvalue_ref_to_volatile<
201 int (S::*)() volatile, int (S::*)() volatile>());
202 static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<
203 int (S::*)() volatile, int (S::*)()>());
204 static_assert(check_swappable_with_including_lvalue_ref_to_volatile<
205 int (S::*)() const volatile, int (S::*)() const volatile>());
206 static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<
207 int (S::*)() const volatile, int (S::*)()>());
209 static_assert(
210 check_swappable_with_including_lvalue_ref_to_volatile<int[5], int[5]>());
211 static_assert(
212 !check_swappable_with_including_lvalue_ref_to_volatile<int[5], int[6]>());
213 static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<
214 int[5], double[5]>());
215 static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<
216 int[5], double[6]>());
217 static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<int[5][6],
218 int[5]>());
219 static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<int[5][6],
220 int[6]>());
221 static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<
222 int[5][6], double[5]>());
223 static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<
224 int[5][6], double[6]>());
225 static_assert(check_swappable_with_including_lvalue_ref_to_volatile<
226 int[5][6], int[5][6]>());
227 static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<
228 int[5][6], int[5][4]>());
229 static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<
230 int[5][6], int[6][5]>());
231 static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<
232 int[5][6], double[5][6]>());
233 static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<
234 int[5][6], double[6][5]>());
236 // always false
237 static_assert(!check_swappable_with_impl<void, void>());
238 static_assert(!check_swappable_with_impl<int, void>());
239 static_assert(!check_swappable_with_impl<int&, void>());
240 static_assert(!check_swappable_with_impl<void, int>());
241 static_assert(!check_swappable_with_impl<void, int&>());
242 static_assert(!check_swappable_with_impl<int, int()>());
243 static_assert(!check_swappable_with_impl<int, int (&)()>());
244 } // namespace fundamental
246 namespace adl {
247 static_assert(
248 check_swappable_with<lvalue_adl_swappable, lvalue_adl_swappable>());
249 static_assert(check_swappable_with<lvalue_rvalue_adl_swappable,
250 lvalue_rvalue_adl_swappable>());
251 static_assert(check_swappable_with<rvalue_lvalue_adl_swappable,
252 rvalue_lvalue_adl_swappable>());
253 static_assert(
254 check_swappable_with_impl<rvalue_adl_swappable, rvalue_adl_swappable>());
255 static_assert(!check_swappable_with_impl<lvalue_rvalue_adl_swappable&,
256 lvalue_rvalue_adl_swappable&&>());
258 struct s1 {};
259 struct no_common_reference_with_s1 {
260 friend void swap(s1&, no_common_reference_with_s1&);
261 friend void swap(no_common_reference_with_s1&, s1&);
263 static_assert(!check_swappable_with<s1, no_common_reference_with_s1>());
265 struct one_way_swappable_with_s1 {
266 friend void swap(s1&, one_way_swappable_with_s1&);
267 operator s1();
269 static_assert(std::common_reference_with<one_way_swappable_with_s1, s1>);
270 static_assert(!check_swappable_with<one_way_swappable_with_s1, s1>());
272 struct one_way_swappable_with_s1_other_way {
273 friend void swap(one_way_swappable_with_s1_other_way&, s1&);
274 operator s1();
276 static_assert(
277 std::common_reference_with<one_way_swappable_with_s1_other_way, s1>);
278 static_assert(!check_swappable_with<one_way_swappable_with_s1_other_way, s1>());
280 struct can_swap_with_s1_but_not_swappable {
281 can_swap_with_s1_but_not_swappable(can_swap_with_s1_but_not_swappable&&) =
282 delete;
283 friend void swap(s1&, can_swap_with_s1_but_not_swappable&);
284 friend void swap(can_swap_with_s1_but_not_swappable&, s1&);
286 operator s1() const;
288 static_assert(
289 std::common_reference_with<can_swap_with_s1_but_not_swappable, s1>);
290 static_assert(!std::swappable<can_swap_with_s1_but_not_swappable>);
291 static_assert(
292 !check_swappable_with<can_swap_with_s1_but_not_swappable&, s1&>());
294 struct swappable_with_s1 {
295 friend void swap(s1&, swappable_with_s1&);
296 friend void swap(swappable_with_s1&, s1&);
297 operator s1() const;
299 static_assert(check_swappable_with<swappable_with_s1, s1>());
301 struct swappable_with_const_s1_but_not_swappable {
302 swappable_with_const_s1_but_not_swappable(
303 swappable_with_const_s1_but_not_swappable const&);
304 swappable_with_const_s1_but_not_swappable(
305 swappable_with_const_s1_but_not_swappable const&&);
306 swappable_with_const_s1_but_not_swappable&
307 operator=(swappable_with_const_s1_but_not_swappable const&);
308 swappable_with_const_s1_but_not_swappable&
309 operator=(swappable_with_const_s1_but_not_swappable const&&);
311 friend void swap(s1 const&, swappable_with_const_s1_but_not_swappable const&);
312 friend void swap(swappable_with_const_s1_but_not_swappable const&, s1 const&);
314 operator s1 const &() const;
316 static_assert(
317 !std::swappable<swappable_with_const_s1_but_not_swappable const&>);
318 static_assert(!std::swappable_with<
319 swappable_with_const_s1_but_not_swappable const&, s1 const&>);
321 struct swappable_with_volatile_s1_but_not_swappable {
322 swappable_with_volatile_s1_but_not_swappable(
323 swappable_with_volatile_s1_but_not_swappable volatile&);
324 swappable_with_volatile_s1_but_not_swappable(
325 swappable_with_volatile_s1_but_not_swappable volatile&&);
326 swappable_with_volatile_s1_but_not_swappable&
327 operator=(swappable_with_volatile_s1_but_not_swappable volatile&);
328 swappable_with_volatile_s1_but_not_swappable&
329 operator=(swappable_with_volatile_s1_but_not_swappable volatile&&);
331 friend void swap(s1 volatile&,
332 swappable_with_volatile_s1_but_not_swappable volatile&);
333 friend void swap(swappable_with_volatile_s1_but_not_swappable volatile&,
334 s1 volatile&);
336 operator s1 volatile &() volatile;
338 static_assert(
339 !std::swappable<swappable_with_volatile_s1_but_not_swappable volatile&>);
340 static_assert(
341 !std::swappable_with<swappable_with_volatile_s1_but_not_swappable volatile&,
342 s1 volatile&>);
344 struct swappable_with_cv_s1_but_not_swappable {
345 swappable_with_cv_s1_but_not_swappable(
346 swappable_with_cv_s1_but_not_swappable const volatile&);
347 swappable_with_cv_s1_but_not_swappable(
348 swappable_with_cv_s1_but_not_swappable const volatile&&);
349 swappable_with_cv_s1_but_not_swappable&
350 operator=(swappable_with_cv_s1_but_not_swappable const volatile&);
351 swappable_with_cv_s1_but_not_swappable&
352 operator=(swappable_with_cv_s1_but_not_swappable const volatile&&);
354 friend void swap(s1 const volatile&,
355 swappable_with_cv_s1_but_not_swappable const volatile&);
356 friend void swap(swappable_with_cv_s1_but_not_swappable const volatile&,
357 s1 const volatile&);
359 operator s1 const volatile &() const volatile;
361 static_assert(
362 !std::swappable<swappable_with_cv_s1_but_not_swappable const volatile&>);
363 static_assert(
364 !std::swappable_with<swappable_with_cv_s1_but_not_swappable const volatile&,
365 s1 const volatile&>);
367 struct s2 {
368 friend void swap(s2 const&, s2 const&);
369 friend void swap(s2 volatile&, s2 volatile&);
370 friend void swap(s2 const volatile&, s2 const volatile&);
373 struct swappable_with_const_s2 {
374 swappable_with_const_s2(swappable_with_const_s2 const&);
375 swappable_with_const_s2(swappable_with_const_s2 const&&);
376 swappable_with_const_s2& operator=(swappable_with_const_s2 const&);
377 swappable_with_const_s2& operator=(swappable_with_const_s2 const&&);
379 friend void swap(swappable_with_const_s2 const&,
380 swappable_with_const_s2 const&);
381 friend void swap(s2 const&, swappable_with_const_s2 const&);
382 friend void swap(swappable_with_const_s2 const&, s2 const&);
384 operator s2 const &() const;
386 static_assert(std::swappable_with<swappable_with_const_s2 const&, s2 const&>);
388 struct swappable_with_volatile_s2 {
389 swappable_with_volatile_s2(swappable_with_volatile_s2 volatile&);
390 swappable_with_volatile_s2(swappable_with_volatile_s2 volatile&&);
391 swappable_with_volatile_s2& operator=(swappable_with_volatile_s2 volatile&);
392 swappable_with_volatile_s2& operator=(swappable_with_volatile_s2 volatile&&);
394 friend void swap(swappable_with_volatile_s2 volatile&,
395 swappable_with_volatile_s2 volatile&);
396 friend void swap(s2 volatile&, swappable_with_volatile_s2 volatile&);
397 friend void swap(swappable_with_volatile_s2 volatile&, s2 volatile&);
399 operator s2 volatile &() volatile;
401 static_assert(
402 std::swappable_with<swappable_with_volatile_s2 volatile&, s2 volatile&>);
404 struct swappable_with_cv_s2 {
405 swappable_with_cv_s2(swappable_with_cv_s2 const volatile&);
406 swappable_with_cv_s2(swappable_with_cv_s2 const volatile&&);
407 swappable_with_cv_s2& operator=(swappable_with_cv_s2 const volatile&);
408 swappable_with_cv_s2& operator=(swappable_with_cv_s2 const volatile&&);
410 friend void swap(swappable_with_cv_s2 const volatile&,
411 swappable_with_cv_s2 const volatile&);
412 friend void swap(s2 const volatile&, swappable_with_cv_s2 const volatile&);
413 friend void swap(swappable_with_cv_s2 const volatile&, s2 const volatile&);
415 operator s2 const volatile &() const volatile;
417 static_assert(std::swappable_with<swappable_with_cv_s2 const volatile&,
418 s2 const volatile&>);
420 struct swappable_with_rvalue_ref_to_s1_but_not_swappable {
421 friend void swap(swappable_with_rvalue_ref_to_s1_but_not_swappable&&,
422 swappable_with_rvalue_ref_to_s1_but_not_swappable&&);
423 friend void swap(s1&&, swappable_with_rvalue_ref_to_s1_but_not_swappable&&);
424 friend void swap(swappable_with_rvalue_ref_to_s1_but_not_swappable&&, s1&&);
426 operator s1() const;
428 static_assert(
429 !std::swappable<swappable_with_rvalue_ref_to_s1_but_not_swappable const&&>);
430 static_assert(
431 !std::swappable_with<
432 swappable_with_rvalue_ref_to_s1_but_not_swappable const&&, s1 const&&>);
434 struct swappable_with_rvalue_ref_to_const_s1_but_not_swappable {
435 friend void
436 swap(s1 const&&,
437 swappable_with_rvalue_ref_to_const_s1_but_not_swappable const&&);
438 friend void
439 swap(swappable_with_rvalue_ref_to_const_s1_but_not_swappable const&&,
440 s1 const&&);
442 operator s1 const() const;
444 static_assert(!std::swappable<
445 swappable_with_rvalue_ref_to_const_s1_but_not_swappable const&&>);
446 static_assert(!std::swappable_with<
447 swappable_with_rvalue_ref_to_const_s1_but_not_swappable const&&,
448 s1 const&&>);
450 struct swappable_with_rvalue_ref_to_volatile_s1_but_not_swappable {
451 swappable_with_rvalue_ref_to_volatile_s1_but_not_swappable(
452 swappable_with_rvalue_ref_to_volatile_s1_but_not_swappable volatile&);
453 swappable_with_rvalue_ref_to_volatile_s1_but_not_swappable(
454 swappable_with_rvalue_ref_to_volatile_s1_but_not_swappable volatile&&);
455 swappable_with_rvalue_ref_to_volatile_s1_but_not_swappable& operator=(
456 swappable_with_rvalue_ref_to_volatile_s1_but_not_swappable volatile&);
457 swappable_with_rvalue_ref_to_volatile_s1_but_not_swappable& operator=(
458 swappable_with_rvalue_ref_to_volatile_s1_but_not_swappable volatile&&);
460 friend void
461 swap(s1 volatile&&,
462 swappable_with_rvalue_ref_to_volatile_s1_but_not_swappable volatile&&);
463 friend void
464 swap(swappable_with_rvalue_ref_to_volatile_s1_but_not_swappable volatile&&,
465 s1 volatile&&);
467 operator s1 volatile &&() volatile&&;
469 static_assert(
470 !std::swappable<
471 swappable_with_rvalue_ref_to_volatile_s1_but_not_swappable volatile&&>);
472 static_assert(
473 !std::swappable_with<
474 swappable_with_rvalue_ref_to_volatile_s1_but_not_swappable volatile&&,
475 s1 volatile&&>);
477 struct swappable_with_rvalue_ref_to_cv_s1_but_not_swappable {
478 swappable_with_rvalue_ref_to_cv_s1_but_not_swappable(
479 swappable_with_rvalue_ref_to_cv_s1_but_not_swappable const volatile&);
480 swappable_with_rvalue_ref_to_cv_s1_but_not_swappable(
481 swappable_with_rvalue_ref_to_cv_s1_but_not_swappable const volatile&&);
482 swappable_with_rvalue_ref_to_cv_s1_but_not_swappable& operator=(
483 swappable_with_rvalue_ref_to_cv_s1_but_not_swappable const volatile&);
484 swappable_with_rvalue_ref_to_cv_s1_but_not_swappable& operator=(
485 swappable_with_rvalue_ref_to_cv_s1_but_not_swappable const volatile&&);
487 friend void
488 swap(s1 const volatile&&,
489 swappable_with_rvalue_ref_to_cv_s1_but_not_swappable const volatile&&);
490 friend void
491 swap(swappable_with_rvalue_ref_to_cv_s1_but_not_swappable const volatile&&,
492 s1 const volatile&&);
494 operator s1 const volatile &&() const volatile&&;
496 static_assert(
497 !std::swappable<
498 swappable_with_rvalue_ref_to_cv_s1_but_not_swappable const volatile&&>);
499 static_assert(
500 !std::swappable_with<
501 swappable_with_rvalue_ref_to_cv_s1_but_not_swappable const volatile&&,
502 s1 const volatile&&>);
504 struct s3 {
505 friend void swap(s3&&, s3&&);
506 friend void swap(s3 const&&, s3 const&&);
507 friend void swap(s3 volatile&&, s3 volatile&&);
508 friend void swap(s3 const volatile&&, s3 const volatile&&);
511 struct swappable_with_rvalue_ref_to_s3 {
512 friend void swap(swappable_with_rvalue_ref_to_s3&&,
513 swappable_with_rvalue_ref_to_s3&&);
514 friend void swap(s3&&, swappable_with_rvalue_ref_to_s3&&);
515 friend void swap(swappable_with_rvalue_ref_to_s3&&, s3&&);
517 operator s3() const;
519 static_assert(std::swappable_with<swappable_with_rvalue_ref_to_s3&&, s3&&>);
521 struct swappable_with_rvalue_ref_to_const_s3 {
522 swappable_with_rvalue_ref_to_const_s3(
523 swappable_with_rvalue_ref_to_const_s3 const&);
524 swappable_with_rvalue_ref_to_const_s3(
525 swappable_with_rvalue_ref_to_const_s3 const&&);
526 swappable_with_rvalue_ref_to_const_s3&
527 operator=(swappable_with_rvalue_ref_to_const_s3 const&);
528 swappable_with_rvalue_ref_to_const_s3&
529 operator=(swappable_with_rvalue_ref_to_const_s3 const&&);
531 friend void swap(swappable_with_rvalue_ref_to_const_s3 const&&,
532 swappable_with_rvalue_ref_to_const_s3 const&&);
533 friend void swap(s3 const&&, swappable_with_rvalue_ref_to_const_s3 const&&);
534 friend void swap(swappable_with_rvalue_ref_to_const_s3 const&&, s3 const&&);
536 operator s3() const;
538 static_assert(std::swappable_with<swappable_with_rvalue_ref_to_const_s3 const&&,
539 s3 const&&>);
541 struct swappable_with_rvalue_ref_to_volatile_s3 {
542 swappable_with_rvalue_ref_to_volatile_s3(
543 swappable_with_rvalue_ref_to_volatile_s3 volatile&);
544 swappable_with_rvalue_ref_to_volatile_s3(
545 swappable_with_rvalue_ref_to_volatile_s3 volatile&&);
546 swappable_with_rvalue_ref_to_volatile_s3&
547 operator=(swappable_with_rvalue_ref_to_volatile_s3 volatile&);
548 swappable_with_rvalue_ref_to_volatile_s3&
549 operator=(swappable_with_rvalue_ref_to_volatile_s3 volatile&&);
551 friend void swap(swappable_with_rvalue_ref_to_volatile_s3 volatile&&,
552 swappable_with_rvalue_ref_to_volatile_s3 volatile&&);
553 friend void swap(s3 volatile&&,
554 swappable_with_rvalue_ref_to_volatile_s3 volatile&&);
555 friend void swap(swappable_with_rvalue_ref_to_volatile_s3 volatile&&,
556 s3 volatile&&);
558 operator s3 volatile &&() volatile;
560 static_assert(
561 std::swappable_with<swappable_with_rvalue_ref_to_volatile_s3 volatile&&,
562 s3 volatile&&>);
564 struct swappable_with_rvalue_ref_to_cv_s3 {
565 swappable_with_rvalue_ref_to_cv_s3(
566 swappable_with_rvalue_ref_to_cv_s3 const volatile&);
567 swappable_with_rvalue_ref_to_cv_s3(
568 swappable_with_rvalue_ref_to_cv_s3 const volatile&&);
569 swappable_with_rvalue_ref_to_cv_s3&
570 operator=(swappable_with_rvalue_ref_to_cv_s3 const volatile&);
571 swappable_with_rvalue_ref_to_cv_s3&
572 operator=(swappable_with_rvalue_ref_to_cv_s3 const volatile&&);
574 friend void swap(swappable_with_rvalue_ref_to_cv_s3 const volatile&&,
575 swappable_with_rvalue_ref_to_cv_s3 const volatile&&);
576 friend void swap(s3 const volatile&&,
577 swappable_with_rvalue_ref_to_cv_s3 const volatile&&);
578 friend void swap(swappable_with_rvalue_ref_to_cv_s3 const volatile&&,
579 s3 const volatile&&);
581 operator s3 const volatile &&() const volatile;
583 static_assert(
584 std::swappable_with<swappable_with_rvalue_ref_to_cv_s3 const volatile&&,
585 s3 const volatile&&>);
587 namespace union_swap {
588 union adl_swappable {
589 int x;
590 double y;
592 operator int() const;
595 void swap(adl_swappable&, adl_swappable&) noexcept;
596 void swap(adl_swappable&&, adl_swappable&&) noexcept;
597 void swap(adl_swappable&, int&) noexcept;
598 void swap(int&, adl_swappable&) noexcept;
599 } // namespace union_swap
600 static_assert(
601 std::swappable_with<union_swap::adl_swappable, union_swap::adl_swappable>);
602 static_assert(std::swappable_with<union_swap::adl_swappable&,
603 union_swap::adl_swappable&>);
604 static_assert(std::swappable_with<union_swap::adl_swappable&&,
605 union_swap::adl_swappable&&>);
606 static_assert(std::swappable_with<union_swap::adl_swappable&, int&>);
607 } // namespace adl
609 namespace standard_types {
610 static_assert(
611 check_swappable_with<std::array<int, 10>, std::array<int, 10> >());
612 static_assert(
613 !check_swappable_with<std::array<int, 10>, std::array<double, 10> >());
614 static_assert(check_swappable_with<std::deque<int>, std::deque<int> >());
615 static_assert(!check_swappable_with<std::deque<int>, std::vector<int> >());
616 static_assert(
617 check_swappable_with<std::forward_list<int>, std::forward_list<int> >());
618 static_assert(
619 !check_swappable_with<std::forward_list<int>, std::vector<int> >());
620 static_assert(check_swappable_with<std::list<int>, std::list<int> >());
621 static_assert(!check_swappable_with<std::list<int>, std::vector<int> >());
623 static_assert(
624 check_swappable_with<std::map<int, void*>, std::map<int, void*> >());
625 static_assert(!check_swappable_with<std::map<int, void*>, std::vector<int> >());
626 static_assert(check_swappable_with<std::optional<std::vector<int> >,
627 std::optional<std::vector<int> > >());
628 static_assert(!check_swappable_with<std::optional<std::vector<int> >,
629 std::vector<int> >());
630 static_assert(check_swappable_with<std::vector<int>, std::vector<int> >());
631 static_assert(!check_swappable_with<std::vector<int>, int>());
632 } // namespace standard_types
634 namespace types_with_purpose {
635 static_assert(!check_swappable_with<DeletedMoveCtor, DeletedMoveCtor>());
636 static_assert(!check_swappable_with<ImplicitlyDeletedMoveCtor,
637 ImplicitlyDeletedMoveCtor>());
638 static_assert(!check_swappable_with<DeletedMoveAssign, DeletedMoveAssign>());
639 static_assert(!check_swappable_with<ImplicitlyDeletedMoveAssign,
640 ImplicitlyDeletedMoveAssign>());
641 static_assert(!check_swappable_with<NonMovable, NonMovable>());
642 static_assert(
643 !check_swappable_with<DerivedFromNonMovable, DerivedFromNonMovable>());
644 static_assert(!check_swappable_with<HasANonMovable, HasANonMovable>());
645 } // namespace types_with_purpose
647 namespace LWG3175 {
648 // Example taken directly from [concept.swappable]
649 template <class T, std::swappable_with<T> U>
650 constexpr void value_swap(T&& t, U&& u) {
651 std::ranges::swap(std::forward<T>(t), std::forward<U>(u));
654 template <std::swappable T>
655 constexpr void lv_swap(T& t1, T& t2) {
656 std::ranges::swap(t1, t2);
659 namespace N {
660 struct A {
661 int m;
663 struct Proxy {
664 A* a;
665 constexpr Proxy(A& a_) : a{&a_} {}
666 friend constexpr void swap(Proxy x, Proxy y) {
667 std::ranges::swap(*x.a, *y.a);
670 constexpr Proxy proxy(A& a) { return Proxy{a}; }
671 } // namespace N
673 constexpr bool CheckRegression() {
674 int i = 1, j = 2;
675 lv_swap(i, j);
676 assert(i == 2 && j == 1);
678 N::A a1 = {5}, a2 = {-5};
679 value_swap(a1, proxy(a2));
680 assert(a1.m == -5 && a2.m == 5);
681 return true;
684 static_assert(CheckRegression());
685 } // namespace LWG3175