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 // template <class... Types> class tuple; 12 13 // template <class... UTypes> 14 // tuple& operator=(const tuple<UTypes...>& u); 15 16 // UNSUPPORTED: c++03 17 18 #include <tuple> 19 #include <string> 20 #include <cassert> 21 22 #include "test_macros.h" 23 24 struct B 25 { 26 int id_; 27 28 explicit B(int i = 0) : id_(i) {} 29 }; 30 31 struct D 32 : B 33 { 34 explicit D(int i = 0) : B(i) {} 35 }; 36 37 struct NonAssignable { 38 NonAssignable& operator=(NonAssignable const&) = delete; 39 NonAssignable& operator=(NonAssignable&&) = delete; 40 }; 41 42 struct NothrowCopyAssignable 43 { 44 NothrowCopyAssignable& operator=(NothrowCopyAssignable const&) noexcept { return *this; } 45 }; 46 47 struct PotentiallyThrowingCopyAssignable 48 { 49 PotentiallyThrowingCopyAssignable& operator=(PotentiallyThrowingCopyAssignable const&) { return *this; } 50 }; 51 52 int main(int, char**) 53 { 54 { 55 typedef std::tuple<long> T0; 56 typedef std::tuple<long long> T1; 57 T0 t0(2); 58 T1 t1; 59 t1 = t0; 60 assert(std::get<0>(t1) == 2); 61 } 62 { 63 typedef std::tuple<long, char> T0; 64 typedef std::tuple<long long, int> T1; 65 T0 t0(2, 'a'); 66 T1 t1; 67 t1 = t0; 68 assert(std::get<0>(t1) == 2); 69 assert(std::get<1>(t1) == int('a')); 70 } 71 { 72 typedef std::tuple<long, char, D> T0; 73 typedef std::tuple<long long, int, B> T1; 74 T0 t0(2, 'a', D(3)); 75 T1 t1; 76 t1 = t0; 77 assert(std::get<0>(t1) == 2); 78 assert(std::get<1>(t1) == int('a')); 79 assert(std::get<2>(t1).id_ == 3); 80 } 81 { 82 D d(3); 83 D d2(2); 84 typedef std::tuple<long, char, D&> T0; 85 typedef std::tuple<long long, int, B&> T1; 86 T0 t0(2, 'a', d2); 87 T1 t1(1, 'b', d); 88 t1 = t0; 89 assert(std::get<0>(t1) == 2); 90 assert(std::get<1>(t1) == int('a')); 91 assert(std::get<2>(t1).id_ == 2); 92 } 93 { 94 // Test that tuple evaluates correctly applies an lvalue reference 95 // before evaluating is_assignable (i.e. 'is_assignable<int&, int&>') 96 // instead of evaluating 'is_assignable<int&&, int&>' which is false. 97 int x = 42; 98 int y = 43; 99 std::tuple<int&&> t(std::move(x)); 100 std::tuple<int&> t2(y); 101 t = t2; 102 assert(std::get<0>(t) == 43); 103 assert(&std::get<0>(t) == &x); 104 } 105 { 106 using T = std::tuple<int, NonAssignable>; 107 using U = std::tuple<NonAssignable, int>; 108 static_assert(!std::is_assignable<T, U const&>::value, ""); 109 static_assert(!std::is_assignable<U, T const&>::value, ""); 110 } 111 { 112 typedef std::tuple<NothrowCopyAssignable, long> T0; 113 typedef std::tuple<NothrowCopyAssignable, int> T1; 114 static_assert(std::is_nothrow_assignable<T0&, T1 const&>::value, ""); 115 } 116 { 117 typedef std::tuple<PotentiallyThrowingCopyAssignable, long> T0; 118 typedef std::tuple<PotentiallyThrowingCopyAssignable, int> T1; 119 static_assert(!std::is_nothrow_assignable<T0&, T1 const&>::value, ""); 120 } 121 122 return 0; 123 } 124