1 //===----------------------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: c++03, c++11, c++14, c++17
11 // template<class T, class U>
12 // concept swappable_with = // see below
19 #include <forward_list>
25 #include <unordered_map>
26 #include <unordered_set>
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&>());
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&&>());
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&>());
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&&>());
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&>() ==
161 namespace fundamental
{
163 check_swappable_with_including_lvalue_ref_to_volatile
<int, int>());
165 check_swappable_with_including_lvalue_ref_to_volatile
<double, double>());
167 !check_swappable_with_including_lvalue_ref_to_volatile
<int, double>());
170 check_swappable_with_including_lvalue_ref_to_volatile
<int*, int*>());
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 (*)()>());
176 !check_swappable_with_including_lvalue_ref_to_volatile
<int, int (*)()>());
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::*>());
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::*)()>());
210 check_swappable_with_including_lvalue_ref_to_volatile
<int[5], int[5]>());
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],
219 static_assert(!check_swappable_with_including_lvalue_ref_to_volatile
<int[5][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]>());
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
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
>());
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
&&>());
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
&);
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
&);
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
&&) =
283 friend void swap(s1
&, can_swap_with_s1_but_not_swappable
&);
284 friend void swap(can_swap_with_s1_but_not_swappable
&, s1
&);
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
>);
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
&);
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;
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&,
336 operator s1
volatile &() volatile;
339 !std::swappable
<swappable_with_volatile_s1_but_not_swappable
volatile&>);
341 !std::swappable_with
<swappable_with_volatile_s1_but_not_swappable
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&,
359 operator s1
const volatile &() const volatile;
362 !std::swappable
<swappable_with_cv_s1_but_not_swappable
const volatile&>);
364 !std::swappable_with
<swappable_with_cv_s1_but_not_swappable
const volatile&,
365 s1
const volatile&>);
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;
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
&&);
429 !std::swappable
<swappable_with_rvalue_ref_to_s1_but_not_swappable
const&&>);
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
{
437 swappable_with_rvalue_ref_to_const_s1_but_not_swappable
const&&);
439 swap(swappable_with_rvalue_ref_to_const_s1_but_not_swappable
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&&,
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&&);
462 swappable_with_rvalue_ref_to_volatile_s1_but_not_swappable
volatile&&);
464 swap(swappable_with_rvalue_ref_to_volatile_s1_but_not_swappable
volatile&&,
467 operator s1
volatile &&() volatile&&;
471 swappable_with_rvalue_ref_to_volatile_s1_but_not_swappable
volatile&&>);
473 !std::swappable_with
<
474 swappable_with_rvalue_ref_to_volatile_s1_but_not_swappable
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&&);
488 swap(s1
const volatile&&,
489 swappable_with_rvalue_ref_to_cv_s1_but_not_swappable
const volatile&&);
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&&;
498 swappable_with_rvalue_ref_to_cv_s1_but_not_swappable
const volatile&&>);
500 !std::swappable_with
<
501 swappable_with_rvalue_ref_to_cv_s1_but_not_swappable
const volatile&&,
502 s1
const volatile&&>);
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
&&);
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&&);
538 static_assert(std::swappable_with
<swappable_with_rvalue_ref_to_const_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&&,
558 operator s3
volatile &&() volatile;
561 std::swappable_with
<swappable_with_rvalue_ref_to_volatile_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;
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
{
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
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&>);
609 namespace standard_types
{
611 check_swappable_with
<std::array
<int, 10>, std::array
<int, 10> >());
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> >());
617 check_swappable_with
<std::forward_list
<int>, std::forward_list
<int> >());
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> >());
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
>());
643 !check_swappable_with
<DerivedFromNonMovable
, DerivedFromNonMovable
>());
644 static_assert(!check_swappable_with
<HasANonMovable
, HasANonMovable
>());
645 } // namespace types_with_purpose
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
);
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
}; }
673 constexpr bool CheckRegression() {
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);
684 static_assert(CheckRegression());
685 } // namespace LWG3175