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... UTypes> 12 // constexpr const tuple& operator=(const tuple<UTypes...>& u) const; 13 // 14 // Constraints: 15 // - sizeof...(Types) equals sizeof...(UTypes) and 16 // - (is_assignable_v<const Types&, const UTypes&> && ...) is true. 17 18 // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 19 20 #include <cassert> 21 #include <tuple> 22 #include <type_traits> 23 24 #include "test_macros.h" 25 #include "types.h" 26 27 // test constraints 28 29 // sizeof...(Types) equals sizeof...(UTypes) 30 static_assert(std::is_assignable_v<const std::tuple<int&>&, const std::tuple<long&>&>); 31 static_assert(!std::is_assignable_v<const std::tuple<int&, int&>&, const std::tuple<long&>&>); 32 static_assert(!std::is_assignable_v<const std::tuple<int&>&, const std::tuple<long&, long&>&>); 33 34 // (is_assignable_v<const Types&, const UTypes&> && ...) is true 35 static_assert(std::is_assignable_v<const std::tuple<AssignableFrom<ConstCopyAssign>>&, 36 const std::tuple<ConstCopyAssign>&>); 37 38 static_assert(std::is_assignable_v<const std::tuple<AssignableFrom<ConstCopyAssign>, ConstCopyAssign>&, 39 const std::tuple<ConstCopyAssign, ConstCopyAssign>&>); 40 41 static_assert(!std::is_assignable_v<const std::tuple<AssignableFrom<ConstCopyAssign>, CopyAssign>&, 42 const std::tuple<ConstCopyAssign, CopyAssign>&>); 43 44 constexpr bool test() { 45 // reference types 46 { 47 int i1 = 1; 48 int i2 = 2; 49 long j1 = 3; 50 long j2 = 4; 51 const std::tuple<int&, int&> t1{i1, i2}; 52 const std::tuple<long&, long&> t2{j1, j2}; 53 t2 = t1; 54 assert(std::get<0>(t2) == 1); 55 assert(std::get<1>(t2) == 2); 56 } 57 58 // user defined const copy assignment 59 { 60 const std::tuple<ConstCopyAssign> t1{1}; 61 const std::tuple<AssignableFrom<ConstCopyAssign>> t2{2}; 62 t2 = t1; 63 assert(std::get<0>(t2).v.val == 1); 64 } 65 66 // make sure the right assignment operator of the type in the tuple is used 67 { 68 std::tuple<TracedAssignment> t1{}; 69 const std::tuple<AssignableFrom<TracedAssignment>> t2{}; 70 t2 = t1; 71 assert(std::get<0>(t2).v.constCopyAssign == 1); 72 } 73 74 return true; 75 } 76 77 int main() { 78 test(); 79 80 // gcc cannot have mutable member in constant expression 81 #if !defined(TEST_COMPILER_GCC) 82 static_assert(test()); 83 #endif 84 return 0; 85 } 86