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