xref: /llvm-project/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.swap/member_swap_const.pass.cpp (revision 16719cd011a4d1a856ddc24dd80703172bfcfffe)
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