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 //===----------------------------------------------------------------------===//
11 // template <class T1, class T2>
12 // void swap(const pair<T1, T2>& x, const pair<T1, T2>& y) const noexcept(noexcept(x.swap(y)));;
14 // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
17 #include <type_traits>
20 #include "test_macros.h"
23 // For the second overload, is_swappable_v<const T1> is true and is_swappable_v<const T2> is true.
24 struct NonConstSwappable
{
25 friend constexpr void swap(NonConstSwappable
&, NonConstSwappable
&);
28 struct ConstSwappable
{
30 friend constexpr void swap(const ConstSwappable
& lhs
, const ConstSwappable
& rhs
) { std::swap(lhs
.i
, rhs
.i
); }
33 static_assert(std::is_swappable_v
<const std::pair
<ConstSwappable
, ConstSwappable
>>);
34 static_assert(!std::is_swappable_v
<const std::pair
<NonConstSwappable
, ConstSwappable
>>);
35 static_assert(!std::is_swappable_v
<const std::pair
<ConstSwappable
, NonConstSwappable
>>);
36 static_assert(!std::is_swappable_v
<const std::pair
<NonConstSwappable
, NonConstSwappable
>>);
38 // noexcept(noexcept(x.swap(y)));
40 concept NonMemberSwapNoexcept
=
41 requires(T t1
, T t2
) {
42 { swap(t1
, t2
) } noexcept
;
45 template <bool canThrow
>
46 struct SwapMayThrow
{};
48 template <bool canThrow
>
49 void swap(const SwapMayThrow
<canThrow
>&, const SwapMayThrow
<canThrow
>&) noexcept(!canThrow
);
51 static_assert(NonMemberSwapNoexcept
<const std::pair
<SwapMayThrow
<false>, SwapMayThrow
<false>>>);
52 static_assert(!NonMemberSwapNoexcept
<const std::pair
<SwapMayThrow
<true>, SwapMayThrow
<false>>>);
53 static_assert(!NonMemberSwapNoexcept
<const std::pair
<SwapMayThrow
<false>, SwapMayThrow
<true>>>);
54 static_assert(!NonMemberSwapNoexcept
<const std::pair
<SwapMayThrow
<true>, SwapMayThrow
<true>>>);
56 constexpr bool test() {
57 // user defined const swap
59 using P
= std::pair
<const ConstSwappable
, const ConstSwappable
>;
60 const P
p1(ConstSwappable
{0}, ConstSwappable
{1});
61 const P
p2(ConstSwappable
{2}, ConstSwappable
{3});
64 assert(p1
.first
.i
== 2);
65 assert(p1
.second
.i
== 3);
66 assert(p2
.first
.i
== 0);
67 assert(p2
.second
.i
== 1);
72 int i1
= 0, i2
= 1, i3
= 2, i4
= 3;
73 const std::pair
<int&, int&> p1
{i1
, i2
};
74 const std::pair
<int&, int&> p2
{i3
, i4
};
77 assert(p1
.first
== 2);
78 assert(p1
.second
== 3);
79 assert(p2
.first
== 0);
80 assert(p2
.second
== 1);
85 int main(int, char**) {
88 // gcc cannot have mutable member in constant expression
89 #if !defined(TEST_COMPILER_GCC)
90 static_assert(test());