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 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 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 55 constexpr void swap(const ConstSwappable& lhs, const ConstSwappable& rhs) { std::swap(lhs.i, rhs.i); } 56 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 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