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