blob: 46e526dcd0c8241a0a49d57ed1bc913af8690062 [file] [log] [blame]
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: libcpp-no-concepts
// template<class T, class U>
// concept swappable_with = // see below
#include <concepts>
#include <array>
#include <deque>
#include <forward_list>
#include <list>
#include <map>
#include <memory>
#include <optional>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include "type_classification/moveconstructible.h"
#include "type_classification/swappable.h"
template <class T, class U>
constexpr bool check_swappable_with_impl() {
static_assert(std::swappable_with<T, U> == std::swappable_with<U, T>);
return std::swappable_with<T, U>;
}
template <class T, class U>
constexpr bool check_swappable_with() {
static_assert(!check_swappable_with_impl<T, U>());
static_assert(!check_swappable_with_impl<T, U const>());
static_assert(!check_swappable_with_impl<T const, U>());
static_assert(!check_swappable_with_impl<T const, U const>());
static_assert(!check_swappable_with_impl<T, U&>());
static_assert(!check_swappable_with_impl<T, U const&>());
static_assert(!check_swappable_with_impl<T, U volatile&>());
static_assert(!check_swappable_with_impl<T, U const volatile&>());
static_assert(!check_swappable_with_impl<T const, U&>());
static_assert(!check_swappable_with_impl<T const, U const&>());
static_assert(!check_swappable_with_impl<T const, U volatile&>());
static_assert(!check_swappable_with_impl<T const, U const volatile&>());
static_assert(!check_swappable_with_impl<T&, U>());
static_assert(!check_swappable_with_impl<T&, U const>());
static_assert(!check_swappable_with_impl<T const&, U>());
static_assert(!check_swappable_with_impl<T const&, U const>());
static_assert(!check_swappable_with_impl<T volatile&, U>());
static_assert(!check_swappable_with_impl<T volatile&, U const>());
static_assert(!check_swappable_with_impl<T const volatile&, U>());
static_assert(!check_swappable_with_impl<T const volatile&, U const>());
static_assert(!check_swappable_with_impl<T&, U const&>());
static_assert(!check_swappable_with_impl<T&, U volatile&>());
static_assert(!check_swappable_with_impl<T&, U const volatile&>());
static_assert(!check_swappable_with_impl<T const&, U&>());
static_assert(!check_swappable_with_impl<T const&, U const&>());
static_assert(!check_swappable_with_impl<T const&, U volatile&>());
static_assert(!check_swappable_with_impl<T const&, U const volatile&>());
static_assert(!check_swappable_with_impl<T volatile&, U&>());
static_assert(!check_swappable_with_impl<T volatile&, U const&>());
static_assert(!check_swappable_with_impl<T volatile&, U const volatile&>());
static_assert(!check_swappable_with_impl<T const volatile&, U&>());
static_assert(!check_swappable_with_impl<T const volatile&, U const&>());
static_assert(!check_swappable_with_impl<T const volatile&, U volatile&>());
static_assert(
!check_swappable_with_impl<T const volatile&, U const volatile&>());
static_assert(!check_swappable_with_impl<T, U&&>());
static_assert(!check_swappable_with_impl<T, U const&&>());
static_assert(!check_swappable_with_impl<T, U volatile&&>());
static_assert(!check_swappable_with_impl<T, U const volatile&&>());
static_assert(!check_swappable_with_impl<T const, U&&>());
static_assert(!check_swappable_with_impl<T const, U const&&>());
static_assert(!check_swappable_with_impl<T const, U volatile&&>());
static_assert(!check_swappable_with_impl<T const, U const volatile&&>());
static_assert(!check_swappable_with_impl<T&&, U>());
static_assert(!check_swappable_with_impl<T&&, U const>());
static_assert(!check_swappable_with_impl<T const&&, U>());
static_assert(!check_swappable_with_impl<T const&&, U const>());
static_assert(!check_swappable_with_impl<T volatile&&, U>());
static_assert(!check_swappable_with_impl<T volatile&&, U const>());
static_assert(!check_swappable_with_impl<T const volatile&&, U>());
static_assert(!check_swappable_with_impl<T const volatile&&, U const>());
static_assert(!check_swappable_with_impl<T&, U&&>());
static_assert(!check_swappable_with_impl<T&, U const&&>());
static_assert(!check_swappable_with_impl<T&, U volatile&&>());
static_assert(!check_swappable_with_impl<T&, U const volatile&&>());
static_assert(!check_swappable_with_impl<T const&, U&&>());
static_assert(!check_swappable_with_impl<T const&, U const&&>());
static_assert(!check_swappable_with_impl<T const&, U volatile&&>());
static_assert(!check_swappable_with_impl<T const&, U const volatile&&>());
static_assert(!check_swappable_with_impl<T volatile&, U&&>());
static_assert(!check_swappable_with_impl<T volatile&, U const&&>());
static_assert(!check_swappable_with_impl<T volatile&, U volatile&&>());
static_assert(!check_swappable_with_impl<T volatile&, U const volatile&&>());
static_assert(!check_swappable_with_impl<T const volatile&, U&&>());
static_assert(!check_swappable_with_impl<T const volatile&, U const&&>());
static_assert(!check_swappable_with_impl<T const volatile&, U volatile&&>());
static_assert(
!check_swappable_with_impl<T const volatile&, U const volatile&&>());
static_assert(!check_swappable_with_impl<T&&, U&>());
static_assert(!check_swappable_with_impl<T&&, U const&>());
static_assert(!check_swappable_with_impl<T&&, U volatile&>());
static_assert(!check_swappable_with_impl<T&&, U const volatile&>());
static_assert(!check_swappable_with_impl<T const&&, U&>());
static_assert(!check_swappable_with_impl<T const&&, U const&>());
static_assert(!check_swappable_with_impl<T const&&, U volatile&>());
static_assert(!check_swappable_with_impl<T const&&, U const volatile&>());
static_assert(!check_swappable_with_impl<T volatile&&, U&>());
static_assert(!check_swappable_with_impl<T volatile&&, U const&>());
static_assert(!check_swappable_with_impl<T volatile&&, U volatile&>());
static_assert(!check_swappable_with_impl<T volatile&&, U const volatile&>());
static_assert(!check_swappable_with_impl<T const volatile&&, U&>());
static_assert(!check_swappable_with_impl<T const volatile&&, U const&>());
static_assert(!check_swappable_with_impl<T const volatile&&, U volatile&>());
static_assert(
!check_swappable_with_impl<T const volatile&&, U const volatile&>());
static_assert(!check_swappable_with_impl<T&&, U&&>());
static_assert(!check_swappable_with_impl<T&&, U const&&>());
static_assert(!check_swappable_with_impl<T&&, U volatile&&>());
static_assert(!check_swappable_with_impl<T&&, U const volatile&&>());
static_assert(!check_swappable_with_impl<T const&&, U&&>());
static_assert(!check_swappable_with_impl<T const&&, U const&&>());
static_assert(!check_swappable_with_impl<T const&&, U volatile&&>());
static_assert(!check_swappable_with_impl<T const&&, U const volatile&&>());
static_assert(!check_swappable_with_impl<T volatile&&, U&&>());
static_assert(!check_swappable_with_impl<T volatile&&, U const&&>());
static_assert(!check_swappable_with_impl<T volatile&&, U volatile&&>());
static_assert(!check_swappable_with_impl<T volatile&&, U const volatile&&>());
static_assert(!check_swappable_with_impl<T const volatile&&, U&&>());
static_assert(!check_swappable_with_impl<T const volatile&&, U const&&>());
static_assert(!check_swappable_with_impl<T const volatile&&, U volatile&&>());
static_assert(
!check_swappable_with_impl<T const volatile&&, U const volatile&&>());
return check_swappable_with_impl<T&, U&>();
}
template <class T, class U>
constexpr bool check_swappable_with_including_lvalue_ref_to_volatile() {
constexpr auto result = check_swappable_with<T, U>();
static_assert(check_swappable_with_impl<T volatile&, U volatile&>() ==
result);
return result;
}
namespace fundamental {
static_assert(
check_swappable_with_including_lvalue_ref_to_volatile<int, int>());
static_assert(
check_swappable_with_including_lvalue_ref_to_volatile<double, double>());
static_assert(
!check_swappable_with_including_lvalue_ref_to_volatile<int, double>());
static_assert(
check_swappable_with_including_lvalue_ref_to_volatile<int*, int*>());
static_assert(
!check_swappable_with_including_lvalue_ref_to_volatile<int, int*>());
static_assert(check_swappable_with_including_lvalue_ref_to_volatile<
int (*)(), int (*)()>());
static_assert(
!check_swappable_with_including_lvalue_ref_to_volatile<int, int (*)()>());
struct S {};
static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<int, S>());
static_assert(check_swappable_with_including_lvalue_ref_to_volatile<
int S::*, int S::*>());
static_assert(
!check_swappable_with_including_lvalue_ref_to_volatile<int, int S::*>());
static_assert(check_swappable_with_including_lvalue_ref_to_volatile<
int (S::*)(), int (S::*)()>());
static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<
int, int (S::*)()>());
static_assert(check_swappable_with_including_lvalue_ref_to_volatile<
int (S::*)() noexcept, int (S::*)() noexcept>());
static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<
int (S::*)() noexcept, int (S::*)()>());
static_assert(check_swappable_with_including_lvalue_ref_to_volatile<
int (S::*)() const, int (S::*)() const>());
static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<
int (S::*)() const, int (S::*)()>());
static_assert(check_swappable_with_including_lvalue_ref_to_volatile<
int (S::*)() const noexcept, int (S::*)() const noexcept>());
static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<
int (S::*)() const, int (S::*)() const noexcept>());
static_assert(check_swappable_with_including_lvalue_ref_to_volatile<
int (S::*)() volatile, int (S::*)() volatile>());
static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<
int (S::*)() volatile, int (S::*)()>());
static_assert(check_swappable_with_including_lvalue_ref_to_volatile<
int (S::*)() const volatile, int (S::*)() const volatile>());
static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<
int (S::*)() const volatile, int (S::*)()>());
static_assert(
check_swappable_with_including_lvalue_ref_to_volatile<int[5], int[5]>());
static_assert(
!check_swappable_with_including_lvalue_ref_to_volatile<int[5], int[6]>());
static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<
int[5], double[5]>());
static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<
int[5], double[6]>());
static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<int[5][6],
int[5]>());
static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<int[5][6],
int[6]>());
static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<
int[5][6], double[5]>());
static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<
int[5][6], double[6]>());
static_assert(check_swappable_with_including_lvalue_ref_to_volatile<
int[5][6], int[5][6]>());
static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<
int[5][6], int[5][4]>());
static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<
int[5][6], int[6][5]>());
static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<
int[5][6], double[5][6]>());
static_assert(!check_swappable_with_including_lvalue_ref_to_volatile<
int[5][6], double[6][5]>());
// always false
static_assert(!check_swappable_with_impl<void, void>());
static_assert(!check_swappable_with_impl<int, void>());
static_assert(!check_swappable_with_impl<int&, void>());
static_assert(!check_swappable_with_impl<void, int>());
static_assert(!check_swappable_with_impl<void, int&>());
static_assert(!check_swappable_with_impl<int, int()>());
static_assert(!check_swappable_with_impl<int, int (&)()>());
} // namespace fundamental
namespace adl {
static_assert(
check_swappable_with<lvalue_adl_swappable, lvalue_adl_swappable>());
static_assert(check_swappable_with<lvalue_rvalue_adl_swappable,
lvalue_rvalue_adl_swappable>());
static_assert(check_swappable_with<rvalue_lvalue_adl_swappable,
rvalue_lvalue_adl_swappable>());
static_assert(
check_swappable_with_impl<rvalue_adl_swappable, rvalue_adl_swappable>());
static_assert(!check_swappable_with_impl<lvalue_rvalue_adl_swappable&,
lvalue_rvalue_adl_swappable&&>());
struct s1 {};
struct no_common_reference_with_s1 {
friend void swap(s1&, no_common_reference_with_s1&);
friend void swap(no_common_reference_with_s1&, s1&);
};
static_assert(!check_swappable_with<s1, no_common_reference_with_s1>());
struct one_way_swappable_with_s1 {
friend void swap(s1&, one_way_swappable_with_s1&);
operator s1();
};
static_assert(std::common_reference_with<one_way_swappable_with_s1, s1>);
static_assert(!check_swappable_with<one_way_swappable_with_s1, s1>());
struct one_way_swappable_with_s1_other_way {
friend void swap(one_way_swappable_with_s1_other_way&, s1&);
operator s1();
};
static_assert(
std::common_reference_with<one_way_swappable_with_s1_other_way, s1>);
static_assert(!check_swappable_with<one_way_swappable_with_s1_other_way, s1>());
struct can_swap_with_s1_but_not_swappable {
can_swap_with_s1_but_not_swappable(can_swap_with_s1_but_not_swappable&&) =
delete;
friend void swap(s1&, can_swap_with_s1_but_not_swappable&);
friend void swap(can_swap_with_s1_but_not_swappable&, s1&);
operator s1() const;
};
static_assert(
std::common_reference_with<can_swap_with_s1_but_not_swappable, s1>);
static_assert(!std::swappable<can_swap_with_s1_but_not_swappable>);
static_assert(
!check_swappable_with<can_swap_with_s1_but_not_swappable&, s1&>());
struct swappable_with_s1 {
friend void swap(s1&, swappable_with_s1&);
friend void swap(swappable_with_s1&, s1&);
operator s1() const;
};
static_assert(check_swappable_with<swappable_with_s1, s1>());
struct swappable_with_const_s1_but_not_swappable {
swappable_with_const_s1_but_not_swappable(
swappable_with_const_s1_but_not_swappable const&);
swappable_with_const_s1_but_not_swappable(
swappable_with_const_s1_but_not_swappable const&&);
swappable_with_const_s1_but_not_swappable&
operator=(swappable_with_const_s1_but_not_swappable const&);
swappable_with_const_s1_but_not_swappable&
operator=(swappable_with_const_s1_but_not_swappable const&&);
friend void swap(s1 const&, swappable_with_const_s1_but_not_swappable const&);
friend void swap(swappable_with_const_s1_but_not_swappable const&, s1 const&);
operator s1 const &() const;
};
static_assert(
!std::swappable<swappable_with_const_s1_but_not_swappable const&>);
static_assert(!std::swappable_with<
swappable_with_const_s1_but_not_swappable const&, s1 const&>);
struct swappable_with_volatile_s1_but_not_swappable {
swappable_with_volatile_s1_but_not_swappable(
swappable_with_volatile_s1_but_not_swappable volatile&);
swappable_with_volatile_s1_but_not_swappable(
swappable_with_volatile_s1_but_not_swappable volatile&&);
swappable_with_volatile_s1_but_not_swappable&
operator=(swappable_with_volatile_s1_but_not_swappable volatile&);
swappable_with_volatile_s1_but_not_swappable&
operator=(swappable_with_volatile_s1_but_not_swappable volatile&&);
friend void swap(s1 volatile&,
swappable_with_volatile_s1_but_not_swappable volatile&);
friend void swap(swappable_with_volatile_s1_but_not_swappable volatile&,
s1 volatile&);
operator s1 volatile &() volatile;
};
static_assert(
!std::swappable<swappable_with_volatile_s1_but_not_swappable volatile&>);
static_assert(
!std::swappable_with<swappable_with_volatile_s1_but_not_swappable volatile&,
s1 volatile&>);
struct swappable_with_cv_s1_but_not_swappable {
swappable_with_cv_s1_but_not_swappable(
swappable_with_cv_s1_but_not_swappable const volatile&);
swappable_with_cv_s1_but_not_swappable(
swappable_with_cv_s1_but_not_swappable const volatile&&);
swappable_with_cv_s1_but_not_swappable&
operator=(swappable_with_cv_s1_but_not_swappable const volatile&);
swappable_with_cv_s1_but_not_swappable&
operator=(swappable_with_cv_s1_but_not_swappable const volatile&&);
friend void swap(s1 const volatile&,
swappable_with_cv_s1_but_not_swappable const volatile&);
friend void swap(swappable_with_cv_s1_but_not_swappable const volatile&,
s1 const volatile&);
operator s1 const volatile &() const volatile;
};
static_assert(
!std::swappable<swappable_with_cv_s1_but_not_swappable const volatile&>);
static_assert(
!std::swappable_with<swappable_with_cv_s1_but_not_swappable const volatile&,
s1 const volatile&>);
struct s2 {
friend void swap(s2 const&, s2 const&);
friend void swap(s2 volatile&, s2 volatile&);
friend void swap(s2 const volatile&, s2 const volatile&);
};
struct swappable_with_const_s2 {
swappable_with_const_s2(swappable_with_const_s2 const&);
swappable_with_const_s2(swappable_with_const_s2 const&&);
swappable_with_const_s2& operator=(swappable_with_const_s2 const&);
swappable_with_const_s2& operator=(swappable_with_const_s2 const&&);
friend void swap(swappable_with_const_s2 const&,
swappable_with_const_s2 const&);
friend void swap(s2 const&, swappable_with_const_s2 const&);
friend void swap(swappable_with_const_s2 const&, s2 const&);
operator s2 const &() const;
};
static_assert(std::swappable_with<swappable_with_const_s2 const&, s2 const&>);
struct swappable_with_volatile_s2 {
swappable_with_volatile_s2(swappable_with_volatile_s2 volatile&);
swappable_with_volatile_s2(swappable_with_volatile_s2 volatile&&);
swappable_with_volatile_s2& operator=(swappable_with_volatile_s2 volatile&);
swappable_with_volatile_s2& operator=(swappable_with_volatile_s2 volatile&&);
friend void swap(swappable_with_volatile_s2 volatile&,
swappable_with_volatile_s2 volatile&);
friend void swap(s2 volatile&, swappable_with_volatile_s2 volatile&);
friend void swap(swappable_with_volatile_s2 volatile&, s2 volatile&);
operator s2 volatile &() volatile;
};
static_assert(
std::swappable_with<swappable_with_volatile_s2 volatile&, s2 volatile&>);
struct swappable_with_cv_s2 {
swappable_with_cv_s2(swappable_with_cv_s2 const volatile&);
swappable_with_cv_s2(swappable_with_cv_s2 const volatile&&);
swappable_with_cv_s2& operator=(swappable_with_cv_s2 const volatile&);
swappable_with_cv_s2& operator=(swappable_with_cv_s2 const volatile&&);
friend void swap(swappable_with_cv_s2 const volatile&,
swappable_with_cv_s2 const volatile&);
friend void swap(s2 const volatile&, swappable_with_cv_s2 const volatile&);
friend void swap(swappable_with_cv_s2 const volatile&, s2 const volatile&);
operator s2 const volatile &() const volatile;
};
static_assert(std::swappable_with<swappable_with_cv_s2 const volatile&,
s2 const volatile&>);
struct swappable_with_rvalue_ref_to_s1_but_not_swappable {
friend void swap(swappable_with_rvalue_ref_to_s1_but_not_swappable&&,
swappable_with_rvalue_ref_to_s1_but_not_swappable&&);
friend void swap(s1&&, swappable_with_rvalue_ref_to_s1_but_not_swappable&&);
friend void swap(swappable_with_rvalue_ref_to_s1_but_not_swappable&&, s1&&);
operator s1() const;
};
static_assert(
!std::swappable<swappable_with_rvalue_ref_to_s1_but_not_swappable const&&>);
static_assert(
!std::swappable_with<
swappable_with_rvalue_ref_to_s1_but_not_swappable const&&, s1 const&&>);
struct swappable_with_rvalue_ref_to_const_s1_but_not_swappable {
friend void
swap(s1 const&&,
swappable_with_rvalue_ref_to_const_s1_but_not_swappable const&&);
friend void
swap(swappable_with_rvalue_ref_to_const_s1_but_not_swappable const&&,
s1 const&&);
operator s1 const() const;
};
static_assert(!std::swappable<
swappable_with_rvalue_ref_to_const_s1_but_not_swappable const&&>);
static_assert(!std::swappable_with<
swappable_with_rvalue_ref_to_const_s1_but_not_swappable const&&,
s1 const&&>);
struct swappable_with_rvalue_ref_to_volatile_s1_but_not_swappable {
swappable_with_rvalue_ref_to_volatile_s1_but_not_swappable(
swappable_with_rvalue_ref_to_volatile_s1_but_not_swappable volatile&);
swappable_with_rvalue_ref_to_volatile_s1_but_not_swappable(
swappable_with_rvalue_ref_to_volatile_s1_but_not_swappable volatile&&);
swappable_with_rvalue_ref_to_volatile_s1_but_not_swappable& operator=(
swappable_with_rvalue_ref_to_volatile_s1_but_not_swappable volatile&);
swappable_with_rvalue_ref_to_volatile_s1_but_not_swappable& operator=(
swappable_with_rvalue_ref_to_volatile_s1_but_not_swappable volatile&&);
friend void
swap(s1 volatile&&,
swappable_with_rvalue_ref_to_volatile_s1_but_not_swappable volatile&&);
friend void
swap(swappable_with_rvalue_ref_to_volatile_s1_but_not_swappable volatile&&,
s1 volatile&&);
operator s1 volatile &&() volatile&&;
};
static_assert(
!std::swappable<
swappable_with_rvalue_ref_to_volatile_s1_but_not_swappable volatile&&>);
static_assert(
!std::swappable_with<
swappable_with_rvalue_ref_to_volatile_s1_but_not_swappable volatile&&,
s1 volatile&&>);
struct swappable_with_rvalue_ref_to_cv_s1_but_not_swappable {
swappable_with_rvalue_ref_to_cv_s1_but_not_swappable(
swappable_with_rvalue_ref_to_cv_s1_but_not_swappable const volatile&);
swappable_with_rvalue_ref_to_cv_s1_but_not_swappable(
swappable_with_rvalue_ref_to_cv_s1_but_not_swappable const volatile&&);
swappable_with_rvalue_ref_to_cv_s1_but_not_swappable& operator=(
swappable_with_rvalue_ref_to_cv_s1_but_not_swappable const volatile&);
swappable_with_rvalue_ref_to_cv_s1_but_not_swappable& operator=(
swappable_with_rvalue_ref_to_cv_s1_but_not_swappable const volatile&&);
friend void
swap(s1 const volatile&&,
swappable_with_rvalue_ref_to_cv_s1_but_not_swappable const volatile&&);
friend void
swap(swappable_with_rvalue_ref_to_cv_s1_but_not_swappable const volatile&&,
s1 const volatile&&);
operator s1 const volatile &&() const volatile&&;
};
static_assert(
!std::swappable<
swappable_with_rvalue_ref_to_cv_s1_but_not_swappable const volatile&&>);
static_assert(
!std::swappable_with<
swappable_with_rvalue_ref_to_cv_s1_but_not_swappable const volatile&&,
s1 const volatile&&>);
struct s3 {
friend void swap(s3&&, s3&&);
friend void swap(s3 const&&, s3 const&&);
friend void swap(s3 volatile&&, s3 volatile&&);
friend void swap(s3 const volatile&&, s3 const volatile&&);
};
struct swappable_with_rvalue_ref_to_s3 {
friend void swap(swappable_with_rvalue_ref_to_s3&&,
swappable_with_rvalue_ref_to_s3&&);
friend void swap(s3&&, swappable_with_rvalue_ref_to_s3&&);
friend void swap(swappable_with_rvalue_ref_to_s3&&, s3&&);
operator s3() const;
};
static_assert(std::swappable_with<swappable_with_rvalue_ref_to_s3&&, s3&&>);
struct swappable_with_rvalue_ref_to_const_s3 {
swappable_with_rvalue_ref_to_const_s3(
swappable_with_rvalue_ref_to_const_s3 const&);
swappable_with_rvalue_ref_to_const_s3(
swappable_with_rvalue_ref_to_const_s3 const&&);
swappable_with_rvalue_ref_to_const_s3&
operator=(swappable_with_rvalue_ref_to_const_s3 const&);
swappable_with_rvalue_ref_to_const_s3&
operator=(swappable_with_rvalue_ref_to_const_s3 const&&);
friend void swap(swappable_with_rvalue_ref_to_const_s3 const&&,
swappable_with_rvalue_ref_to_const_s3 const&&);
friend void swap(s3 const&&, swappable_with_rvalue_ref_to_const_s3 const&&);
friend void swap(swappable_with_rvalue_ref_to_const_s3 const&&, s3 const&&);
operator s3() const;
};
static_assert(std::swappable_with<swappable_with_rvalue_ref_to_const_s3 const&&,
s3 const&&>);
struct swappable_with_rvalue_ref_to_volatile_s3 {
swappable_with_rvalue_ref_to_volatile_s3(
swappable_with_rvalue_ref_to_volatile_s3 volatile&);
swappable_with_rvalue_ref_to_volatile_s3(
swappable_with_rvalue_ref_to_volatile_s3 volatile&&);
swappable_with_rvalue_ref_to_volatile_s3&
operator=(swappable_with_rvalue_ref_to_volatile_s3 volatile&);
swappable_with_rvalue_ref_to_volatile_s3&
operator=(swappable_with_rvalue_ref_to_volatile_s3 volatile&&);
friend void swap(swappable_with_rvalue_ref_to_volatile_s3 volatile&&,
swappable_with_rvalue_ref_to_volatile_s3 volatile&&);
friend void swap(s3 volatile&&,
swappable_with_rvalue_ref_to_volatile_s3 volatile&&);
friend void swap(swappable_with_rvalue_ref_to_volatile_s3 volatile&&,
s3 volatile&&);
operator s3 volatile &() volatile;
};
static_assert(
std::swappable_with<swappable_with_rvalue_ref_to_volatile_s3 volatile&&,
s3 volatile&&>);
struct swappable_with_rvalue_ref_to_cv_s3 {
swappable_with_rvalue_ref_to_cv_s3(
swappable_with_rvalue_ref_to_cv_s3 const volatile&);
swappable_with_rvalue_ref_to_cv_s3(
swappable_with_rvalue_ref_to_cv_s3 const volatile&&);
swappable_with_rvalue_ref_to_cv_s3&
operator=(swappable_with_rvalue_ref_to_cv_s3 const volatile&);
swappable_with_rvalue_ref_to_cv_s3&
operator=(swappable_with_rvalue_ref_to_cv_s3 const volatile&&);
friend void swap(swappable_with_rvalue_ref_to_cv_s3 const volatile&&,
swappable_with_rvalue_ref_to_cv_s3 const volatile&&);
friend void swap(s3 const volatile&&,
swappable_with_rvalue_ref_to_cv_s3 const volatile&&);
friend void swap(swappable_with_rvalue_ref_to_cv_s3 const volatile&&,
s3 const volatile&&);
operator s3 const volatile &() const volatile;
};
static_assert(
std::swappable_with<swappable_with_rvalue_ref_to_cv_s3 const volatile&&,
s3 const volatile&&>);
namespace union_swap {
union adl_swappable {
int x;
double y;
operator int() const;
};
void swap(adl_swappable&, adl_swappable&) noexcept;
void swap(adl_swappable&&, adl_swappable&&) noexcept;
void swap(adl_swappable&, int&) noexcept;
void swap(int&, adl_swappable&) noexcept;
} // namespace union_swap
static_assert(
std::swappable_with<union_swap::adl_swappable, union_swap::adl_swappable>);
static_assert(std::swappable_with<union_swap::adl_swappable&,
union_swap::adl_swappable&>);
static_assert(std::swappable_with<union_swap::adl_swappable&&,
union_swap::adl_swappable&&>);
static_assert(std::swappable_with<union_swap::adl_swappable&, int&>);
} // namespace adl
namespace standard_types {
static_assert(
check_swappable_with<std::array<int, 10>, std::array<int, 10> >());
static_assert(
!check_swappable_with<std::array<int, 10>, std::array<double, 10> >());
static_assert(check_swappable_with<std::deque<int>, std::deque<int> >());
static_assert(!check_swappable_with<std::deque<int>, std::vector<int> >());
static_assert(
check_swappable_with<std::forward_list<int>, std::forward_list<int> >());
static_assert(
!check_swappable_with<std::forward_list<int>, std::vector<int> >());
static_assert(check_swappable_with<std::list<int>, std::list<int> >());
static_assert(!check_swappable_with<std::list<int>, std::vector<int> >());
static_assert(
check_swappable_with<std::map<int, void*>, std::map<int, void*> >());
static_assert(!check_swappable_with<std::map<int, void*>, std::vector<int> >());
static_assert(check_swappable_with<std::optional<std::vector<int> >,
std::optional<std::vector<int> > >());
static_assert(!check_swappable_with<std::optional<std::vector<int> >,
std::vector<int> >());
static_assert(check_swappable_with<std::vector<int>, std::vector<int> >());
static_assert(!check_swappable_with<std::vector<int>, int>());
} // namespace standard_types
namespace types_with_purpose {
static_assert(!check_swappable_with<DeletedMoveCtor, DeletedMoveCtor>());
static_assert(!check_swappable_with<ImplicitlyDeletedMoveCtor,
ImplicitlyDeletedMoveCtor>());
static_assert(!check_swappable_with<DeletedMoveAssign, DeletedMoveAssign>());
static_assert(!check_swappable_with<ImplicitlyDeletedMoveAssign,
ImplicitlyDeletedMoveAssign>());
static_assert(!check_swappable_with<NonMovable, NonMovable>());
static_assert(
!check_swappable_with<DerivedFromNonMovable, DerivedFromNonMovable>());
static_assert(!check_swappable_with<HasANonMovable, HasANonMovable>());
} // namespace types_with_purpose
int main(int, char**) { return 0; }