brintos

brintos / llvm-project-archived public Read only

0
0
Text · 29.9 KiB · 3d128eb Raw
686 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++14, c++1710 11// template<class T, class U>12// concept swappable_with = // see below13 14#include <concepts>15 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>28 29#include "type_classification/moveconstructible.h"30#include "type_classification/swappable.h"31 32template <class T, class U>33constexpr 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 38template <class T, class U>39constexpr 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 153template <class T, class U>154constexpr 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 161namespace fundamental {162static_assert(163    check_swappable_with_including_lvalue_ref_to_volatile<int, int>());164static_assert(165    check_swappable_with_including_lvalue_ref_to_volatile<double, double>());166static_assert(167    !check_swappable_with_including_lvalue_ref_to_volatile<int, double>());168 169static_assert(170    check_swappable_with_including_lvalue_ref_to_volatile<int*, int*>());171static_assert(172    !check_swappable_with_including_lvalue_ref_to_volatile<int, int*>());173static_assert(check_swappable_with_including_lvalue_ref_to_volatile<174              int (*)(), int (*)()>());175static_assert(176    !check_swappable_with_including_lvalue_ref_to_volatile<int, int (*)()>());177 178struct S {};179static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<int, S>());180static_assert(check_swappable_with_including_lvalue_ref_to_volatile<181              int S::*, int S::*>());182static_assert(183    !check_swappable_with_including_lvalue_ref_to_volatile<int, int S::*>());184static_assert(check_swappable_with_including_lvalue_ref_to_volatile<185              int (S::*)(), int (S::*)()>());186static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<187              int, int (S::*)()>());188static_assert(check_swappable_with_including_lvalue_ref_to_volatile<189              int (S::*)() noexcept, int (S::*)() noexcept>());190static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<191              int (S::*)() noexcept, int (S::*)()>());192static_assert(check_swappable_with_including_lvalue_ref_to_volatile<193              int (S::*)() const, int (S::*)() const>());194static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<195              int (S::*)() const, int (S::*)()>());196static_assert(check_swappable_with_including_lvalue_ref_to_volatile<197              int (S::*)() const noexcept, int (S::*)() const noexcept>());198static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<199              int (S::*)() const, int (S::*)() const noexcept>());200static_assert(check_swappable_with_including_lvalue_ref_to_volatile<201              int (S::*)() volatile, int (S::*)() volatile>());202static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<203              int (S::*)() volatile, int (S::*)()>());204static_assert(check_swappable_with_including_lvalue_ref_to_volatile<205              int (S::*)() const volatile, int (S::*)() const volatile>());206static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<207              int (S::*)() const volatile, int (S::*)()>());208 209static_assert(210    check_swappable_with_including_lvalue_ref_to_volatile<int[5], int[5]>());211static_assert(212    !check_swappable_with_including_lvalue_ref_to_volatile<int[5], int[6]>());213static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<214              int[5], double[5]>());215static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<216              int[5], double[6]>());217static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<int[5][6],218                                                                     int[5]>());219static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<int[5][6],220                                                                     int[6]>());221static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<222              int[5][6], double[5]>());223static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<224              int[5][6], double[6]>());225static_assert(check_swappable_with_including_lvalue_ref_to_volatile<226              int[5][6], int[5][6]>());227static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<228              int[5][6], int[5][4]>());229static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<230              int[5][6], int[6][5]>());231static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<232              int[5][6], double[5][6]>());233static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<234              int[5][6], double[6][5]>());235 236// always false237static_assert(!check_swappable_with_impl<void, void>());238static_assert(!check_swappable_with_impl<int, void>());239static_assert(!check_swappable_with_impl<int&, void>());240static_assert(!check_swappable_with_impl<void, int>());241static_assert(!check_swappable_with_impl<void, int&>());242static_assert(!check_swappable_with_impl<int, int()>());243static_assert(!check_swappable_with_impl<int, int (&)()>());244} // namespace fundamental245 246namespace adl {247static_assert(248    check_swappable_with<lvalue_adl_swappable, lvalue_adl_swappable>());249static_assert(check_swappable_with<lvalue_rvalue_adl_swappable,250                                   lvalue_rvalue_adl_swappable>());251static_assert(check_swappable_with<rvalue_lvalue_adl_swappable,252                                   rvalue_lvalue_adl_swappable>());253static_assert(254    check_swappable_with_impl<rvalue_adl_swappable, rvalue_adl_swappable>());255static_assert(!check_swappable_with_impl<lvalue_rvalue_adl_swappable&,256                                         lvalue_rvalue_adl_swappable&&>());257 258struct s1 {};259struct 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};263static_assert(!check_swappable_with<s1, no_common_reference_with_s1>());264 265struct one_way_swappable_with_s1 {266  friend void swap(s1&, one_way_swappable_with_s1&);267  operator s1();268};269static_assert(std::common_reference_with<one_way_swappable_with_s1, s1>);270static_assert(!check_swappable_with<one_way_swappable_with_s1, s1>());271 272struct one_way_swappable_with_s1_other_way {273  friend void swap(one_way_swappable_with_s1_other_way&, s1&);274  operator s1();275};276static_assert(277    std::common_reference_with<one_way_swappable_with_s1_other_way, s1>);278static_assert(!check_swappable_with<one_way_swappable_with_s1_other_way, s1>());279 280struct 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};288static_assert(289    std::common_reference_with<can_swap_with_s1_but_not_swappable, s1>);290static_assert(!std::swappable<can_swap_with_s1_but_not_swappable>);291static_assert(292    !check_swappable_with<can_swap_with_s1_but_not_swappable&, s1&>());293 294struct swappable_with_s1 {295  friend void swap(s1&, swappable_with_s1&);296  friend void swap(swappable_with_s1&, s1&);297  operator s1() const;298};299static_assert(check_swappable_with<swappable_with_s1, s1>());300 301struct 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};316static_assert(317    !std::swappable<swappable_with_const_s1_but_not_swappable const&>);318static_assert(!std::swappable_with<319              swappable_with_const_s1_but_not_swappable const&, s1 const&>);320 321struct 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};338static_assert(339    !std::swappable<swappable_with_volatile_s1_but_not_swappable volatile&>);340static_assert(341    !std::swappable_with<swappable_with_volatile_s1_but_not_swappable volatile&,342                         s1 volatile&>);343 344struct 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};361static_assert(362    !std::swappable<swappable_with_cv_s1_but_not_swappable const volatile&>);363static_assert(364    !std::swappable_with<swappable_with_cv_s1_but_not_swappable const volatile&,365                         s1 const volatile&>);366 367struct 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 373struct 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};386static_assert(std::swappable_with<swappable_with_const_s2 const&, s2 const&>);387 388struct 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};401static_assert(402    std::swappable_with<swappable_with_volatile_s2 volatile&, s2 volatile&>);403 404struct 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};417static_assert(std::swappable_with<swappable_with_cv_s2 const volatile&,418                                  s2 const volatile&>);419 420struct 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};428static_assert(429    !std::swappable<swappable_with_rvalue_ref_to_s1_but_not_swappable const&&>);430static_assert(431    !std::swappable_with<432        swappable_with_rvalue_ref_to_s1_but_not_swappable const&&, s1 const&&>);433 434struct swappable_with_rvalue_ref_to_const_s1_but_not_swappable {435  friend void436  swap(s1 const&&,437       swappable_with_rvalue_ref_to_const_s1_but_not_swappable const&&);438  friend void439  swap(swappable_with_rvalue_ref_to_const_s1_but_not_swappable const&&,440       s1 const&&);441 442  operator s1 const() const;443};444static_assert(!std::swappable<445              swappable_with_rvalue_ref_to_const_s1_but_not_swappable const&&>);446static_assert(!std::swappable_with<447              swappable_with_rvalue_ref_to_const_s1_but_not_swappable const&&,448              s1 const&&>);449 450struct 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 void461  swap(s1 volatile&&,462       swappable_with_rvalue_ref_to_volatile_s1_but_not_swappable volatile&&);463  friend void464  swap(swappable_with_rvalue_ref_to_volatile_s1_but_not_swappable volatile&&,465       s1 volatile&&);466 467  operator s1 volatile &&() volatile&&;468};469static_assert(470    !std::swappable<471        swappable_with_rvalue_ref_to_volatile_s1_but_not_swappable volatile&&>);472static_assert(473    !std::swappable_with<474        swappable_with_rvalue_ref_to_volatile_s1_but_not_swappable volatile&&,475        s1 volatile&&>);476 477struct 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 void488  swap(s1 const volatile&&,489       swappable_with_rvalue_ref_to_cv_s1_but_not_swappable const volatile&&);490  friend void491  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};496static_assert(497    !std::swappable<498        swappable_with_rvalue_ref_to_cv_s1_but_not_swappable const volatile&&>);499static_assert(500    !std::swappable_with<501        swappable_with_rvalue_ref_to_cv_s1_but_not_swappable const volatile&&,502        s1 const volatile&&>);503 504struct 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 511struct 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};519static_assert(std::swappable_with<swappable_with_rvalue_ref_to_s3&&, s3&&>);520 521struct 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};538static_assert(std::swappable_with<swappable_with_rvalue_ref_to_const_s3 const&&,539                                  s3 const&&>);540 541struct 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};560static_assert(561    std::swappable_with<swappable_with_rvalue_ref_to_volatile_s3 volatile&&,562                        s3 volatile&&>);563 564struct 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};583static_assert(584    std::swappable_with<swappable_with_rvalue_ref_to_cv_s3 const volatile&&,585                        s3 const volatile&&>);586 587namespace union_swap {588union adl_swappable {589  int x;590  double y;591 592  operator int() const;593};594 595void swap(adl_swappable&, adl_swappable&) noexcept;596void swap(adl_swappable&&, adl_swappable&&) noexcept;597void swap(adl_swappable&, int&) noexcept;598void swap(int&, adl_swappable&) noexcept;599} // namespace union_swap600static_assert(601    std::swappable_with<union_swap::adl_swappable, union_swap::adl_swappable>);602static_assert(std::swappable_with<union_swap::adl_swappable&,603                                  union_swap::adl_swappable&>);604static_assert(std::swappable_with<union_swap::adl_swappable&&,605                                  union_swap::adl_swappable&&>);606static_assert(std::swappable_with<union_swap::adl_swappable&, int&>);607} // namespace adl608 609namespace standard_types {610static_assert(611    check_swappable_with<std::array<int, 10>, std::array<int, 10> >());612static_assert(613    !check_swappable_with<std::array<int, 10>, std::array<double, 10> >());614static_assert(check_swappable_with<std::deque<int>, std::deque<int> >());615static_assert(!check_swappable_with<std::deque<int>, std::vector<int> >());616static_assert(617    check_swappable_with<std::forward_list<int>, std::forward_list<int> >());618static_assert(619    !check_swappable_with<std::forward_list<int>, std::vector<int> >());620static_assert(check_swappable_with<std::list<int>, std::list<int> >());621static_assert(!check_swappable_with<std::list<int>, std::vector<int> >());622 623static_assert(624    check_swappable_with<std::map<int, void*>, std::map<int, void*> >());625static_assert(!check_swappable_with<std::map<int, void*>, std::vector<int> >());626static_assert(check_swappable_with<std::optional<std::vector<int> >,627                                   std::optional<std::vector<int> > >());628static_assert(!check_swappable_with<std::optional<std::vector<int> >,629                                    std::vector<int> >());630static_assert(check_swappable_with<std::vector<int>, std::vector<int> >());631static_assert(!check_swappable_with<std::vector<int>, int>());632} // namespace standard_types633 634namespace types_with_purpose {635static_assert(!check_swappable_with<DeletedMoveCtor, DeletedMoveCtor>());636static_assert(!check_swappable_with<ImplicitlyDeletedMoveCtor,637                                    ImplicitlyDeletedMoveCtor>());638static_assert(!check_swappable_with<DeletedMoveAssign, DeletedMoveAssign>());639static_assert(!check_swappable_with<ImplicitlyDeletedMoveAssign,640                                    ImplicitlyDeletedMoveAssign>());641static_assert(!check_swappable_with<NonMovable, NonMovable>());642static_assert(643    !check_swappable_with<DerivedFromNonMovable, DerivedFromNonMovable>());644static_assert(!check_swappable_with<HasANonMovable, HasANonMovable>());645} // namespace types_with_purpose646 647namespace LWG3175 {648// Example taken directly from [concept.swappable]649template <class T, std::swappable_with<T> U>650constexpr void value_swap(T&& t, U&& u) {651  std::ranges::swap(std::forward<T>(t), std::forward<U>(u));652}653 654template <std::swappable T>655constexpr void lv_swap(T& t1, T& t2) {656  std::ranges::swap(t1, t2);657}658 659namespace N {660struct A {661  int m;662};663struct 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);668  }669};670constexpr Proxy proxy(A& a) { return Proxy{a}; }671} // namespace N672 673constexpr bool CheckRegression() {674  int i = 1, j = 2;675  lv_swap(i, j);676  assert(i == 2 && j == 1);677 678  N::A a1 = {5}, a2 = {-5};679  value_swap(a1, proxy(a2));680  assert(a1.m == -5 && a2.m == 5);681  return true;682}683 684static_assert(CheckRegression());685} // namespace LWG3175686