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 // <tuple>
10
11 // void swap(const tuple& rhs);
12
13 // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
14
15 #include <cassert>
16 #include <tuple>
17 #include <utility>
18
19 #include "test_macros.h"
20
21 #ifndef TEST_HAS_NO_EXCEPTIONS
22 class SwapThrower {
23 void swap(SwapThrower&) = delete;
24 void swap(const SwapThrower&) const = delete;
25 };
26
swap(const SwapThrower &,const SwapThrower &)27 void swap(const SwapThrower&, const SwapThrower&) { throw 0.f; }
28
29 static_assert(std::is_swappable_v<const SwapThrower>);
30 static_assert(std::is_swappable_with_v<const SwapThrower&, const SwapThrower&>);
31
test_noexcept()32 void test_noexcept() {
33 const std::tuple<SwapThrower> t1;
34 const std::tuple<SwapThrower> t2;
35
36 try {
37 t1.swap(t2);
38 std::swap(t1, t2);
39 assert(false);
40 } catch (float) {
41 }
42
43 try {
44 std::swap(std::as_const(t1), std::as_const(t2));
45 assert(false);
46 } catch (float) {
47 }
48 }
49 #endif // TEST_HAS_NO_EXCEPTIONS
50
51 struct ConstSwappable {
52 mutable int i;
53 };
54
swap(const ConstSwappable & lhs,const ConstSwappable & rhs)55 constexpr void swap(const ConstSwappable& lhs, const ConstSwappable& rhs) { std::swap(lhs.i, rhs.i); }
56
test()57 constexpr bool test() {
58 {
59 typedef std::tuple<const ConstSwappable> T;
60 const T t0(ConstSwappable{0});
61 T t1(ConstSwappable{1});
62 t0.swap(t1);
63 assert(std::get<0>(t0).i == 1);
64 assert(std::get<0>(t1).i == 0);
65 }
66 {
67 typedef std::tuple<ConstSwappable, ConstSwappable> T;
68 const T t0({0}, {1});
69 const T t1({2}, {3});
70 t0.swap(t1);
71 assert(std::get<0>(t0).i == 2);
72 assert(std::get<1>(t0).i == 3);
73 assert(std::get<0>(t1).i == 0);
74 assert(std::get<1>(t1).i == 1);
75 }
76 {
77 typedef std::tuple<ConstSwappable, const ConstSwappable, const ConstSwappable> T;
78 const T t0({0}, {1}, {2});
79 const T t1({3}, {4}, {5});
80 t0.swap(t1);
81 assert(std::get<0>(t0).i == 3);
82 assert(std::get<1>(t0).i == 4);
83 assert(std::get<2>(t0).i == 5);
84 assert(std::get<0>(t1).i == 0);
85 assert(std::get<1>(t1).i == 1);
86 assert(std::get<2>(t1).i == 2);
87 }
88 return true;
89 }
90
main(int,char **)91 int main(int, char**) {
92 #ifndef TEST_HAS_NO_EXCEPTIONS
93 test_noexcept();
94 #endif
95 test();
96
97 // gcc cannot have mutable member in constant expression
98 #if !defined(TEST_COMPILER_GCC)
99 static_assert(test());
100 #endif
101
102 return 0;
103 }
104