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