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 // UNSUPPORTED: c++03, c++11, c++14, c++17 10 // UNSUPPORTED: libcpp-no-concepts 11 12 // template<class T, class U> 13 // concept swappable_with = // see below 14 15 #include <concepts> 16 17 #include <array> 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> 28 29 #include "type_classification/moveconstructible.h" 30 #include "type_classification/swappable.h" 31 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>; 36 } 37 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>()); 44 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&>()); 53 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>()); 62 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&>()); 78 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&&>()); 87 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>()); 96 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&&>()); 114 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&>()); 132 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&>(); 151 } 152 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; 159 } 160 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>()); 168 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 (*)()>()); 177 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::*)()>()); 208 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]>()); 235 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 245 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&&>()); 257 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&); 262 }; 263 static_assert(!check_swappable_with<s1, no_common_reference_with_s1>()); 264 265 struct one_way_swappable_with_s1 { 266 friend void swap(s1&, one_way_swappable_with_s1&); 267 operator s1(); 268 }; 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>()); 271 272 struct one_way_swappable_with_s1_other_way { 273 friend void swap(one_way_swappable_with_s1_other_way&, s1&); 274 operator s1(); 275 }; 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>()); 279 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&); 285 286 operator s1() const; 287 }; 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&>()); 293 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; 298 }; 299 static_assert(check_swappable_with<swappable_with_s1, s1>()); 300 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&&); 310 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&); 313 314 operator s1 const &() const; 315 }; 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&>); 320 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&&); 330 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&); 335 336 operator s1 volatile &() volatile; 337 }; 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&>); 343 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&&); 353 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&); 358 359 operator s1 const volatile &() const volatile; 360 }; 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&>); 366 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&); 371 }; 372 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&&); 378 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&); 383 384 operator s2 const &() const; 385 }; 386 static_assert(std::swappable_with<swappable_with_const_s2 const&, s2 const&>); 387 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&&); 393 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&); 398 399 operator s2 volatile &() volatile; 400 }; 401 static_assert( 402 std::swappable_with<swappable_with_volatile_s2 volatile&, s2 volatile&>); 403 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&&); 409 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&); 414 415 operator s2 const volatile &() const volatile; 416 }; 417 static_assert(std::swappable_with<swappable_with_cv_s2 const volatile&, 418 s2 const volatile&>); 419 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&&); 425 426 operator s1() const; 427 }; 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&&>); 433 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&&); 441 442 operator s1 const() const; 443 }; 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&&>); 449 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&&); 459 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&&); 466 467 operator s1 volatile &&() volatile&&; 468 }; 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&&>); 476 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&&); 486 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&&); 493 494 operator s1 const volatile &&() const volatile&&; 495 }; 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&&>); 503 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&&); 509 }; 510 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&&); 516 517 operator s3() const; 518 }; 519 static_assert(std::swappable_with<swappable_with_rvalue_ref_to_s3&&, s3&&>); 520 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&&); 530 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&&); 535 536 operator s3() const; 537 }; 538 static_assert(std::swappable_with<swappable_with_rvalue_ref_to_const_s3 const&&, 539 s3 const&&>); 540 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&&); 550 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&&); 557 558 operator s3 volatile &() volatile; 559 }; 560 static_assert( 561 std::swappable_with<swappable_with_rvalue_ref_to_volatile_s3 volatile&&, 562 s3 volatile&&>); 563 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&&); 573 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&&); 580 581 operator s3 const volatile &() const volatile; 582 }; 583 static_assert( 584 std::swappable_with<swappable_with_rvalue_ref_to_cv_s3 const volatile&&, 585 s3 const volatile&&>); 586 587 namespace union_swap { 588 union adl_swappable { 589 int x; 590 double y; 591 592 operator int() const; 593 }; 594 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 608 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> >()); 622 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 633 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 646 647 int main(int, char**) { return 0; } 648