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