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 // tuple& operator=(const tuple& u); 14 15 // UNSUPPORTED: c++03 16 17 #include <tuple> 18 #include <memory> 19 #include <string> 20 #include <cassert> 21 22 #include "test_macros.h" 23 24 struct NonAssignable { 25 NonAssignable& operator=(NonAssignable const&) = delete; 26 NonAssignable& operator=(NonAssignable&&) = delete; 27 }; 28 struct CopyAssignable { 29 CopyAssignable& operator=(CopyAssignable const&) = default; 30 CopyAssignable& operator=(CopyAssignable &&) = delete; 31 }; 32 static_assert(std::is_copy_assignable<CopyAssignable>::value, ""); 33 struct MoveAssignable { 34 MoveAssignable& operator=(MoveAssignable const&) = delete; 35 MoveAssignable& operator=(MoveAssignable&&) = default; 36 }; 37 struct NothrowCopyAssignable { 38 NothrowCopyAssignable& operator=(NothrowCopyAssignable const&) noexcept { return *this; } 39 }; 40 struct PotentiallyThrowingCopyAssignable { 41 PotentiallyThrowingCopyAssignable& operator=(PotentiallyThrowingCopyAssignable const&) { return *this; } 42 }; 43 44 struct CopyAssignableInt { 45 CopyAssignableInt& operator=(int&) { return *this; } 46 }; 47 48 int main(int, char**) 49 { 50 { 51 typedef std::tuple<> T; 52 T t0; 53 T t; 54 t = t0; 55 } 56 { 57 typedef std::tuple<int> T; 58 T t0(2); 59 T t; 60 t = t0; 61 assert(std::get<0>(t) == 2); 62 } 63 { 64 typedef std::tuple<int, char> T; 65 T t0(2, 'a'); 66 T t; 67 t = t0; 68 assert(std::get<0>(t) == 2); 69 assert(std::get<1>(t) == 'a'); 70 } 71 { 72 typedef std::tuple<int, char, std::string> T; 73 const T t0(2, 'a', "some text"); 74 T t; 75 t = t0; 76 assert(std::get<0>(t) == 2); 77 assert(std::get<1>(t) == 'a'); 78 assert(std::get<2>(t) == "some text"); 79 } 80 { 81 // test reference assignment. 82 using T = std::tuple<int&, int&&>; 83 int x = 42; 84 int y = 100; 85 int x2 = -1; 86 int y2 = 500; 87 T t(x, std::move(y)); 88 T t2(x2, std::move(y2)); 89 t = t2; 90 assert(std::get<0>(t) == x2); 91 assert(&std::get<0>(t) == &x); 92 assert(std::get<1>(t) == y2); 93 assert(&std::get<1>(t) == &y); 94 } 95 { 96 // test that the implicitly generated copy assignment operator 97 // is properly deleted 98 using T = std::tuple<std::unique_ptr<int>>; 99 static_assert(!std::is_copy_assignable<T>::value, ""); 100 } 101 { 102 using T = std::tuple<int, NonAssignable>; 103 static_assert(!std::is_copy_assignable<T>::value, ""); 104 } 105 { 106 using T = std::tuple<int, CopyAssignable>; 107 static_assert(std::is_copy_assignable<T>::value, ""); 108 } 109 { 110 using T = std::tuple<int, MoveAssignable>; 111 static_assert(!std::is_copy_assignable<T>::value, ""); 112 } 113 { 114 using T = std::tuple<int, int, int>; 115 using P = std::pair<int, int>; 116 static_assert(!std::is_assignable<T&, P>::value, ""); 117 } 118 { 119 // test const requirement 120 using T = std::tuple<CopyAssignableInt, CopyAssignableInt>; 121 using P = std::pair<int, int>; 122 static_assert(!std::is_assignable<T&, P const>::value, ""); 123 } 124 { 125 using T = std::tuple<int, MoveAssignable>; 126 using P = std::pair<int, MoveAssignable>; 127 static_assert(!std::is_assignable<T&, P&>::value, ""); 128 } 129 { 130 using T = std::tuple<NothrowCopyAssignable, int>; 131 static_assert(std::is_nothrow_copy_assignable<T>::value, ""); 132 } 133 { 134 using T = std::tuple<PotentiallyThrowingCopyAssignable, int>; 135 static_assert(!std::is_nothrow_copy_assignable<T>::value, ""); 136 } 137 138 return 0; 139 } 140