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