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 // UNSUPPORTED: c++98, c++03 11 12 // <utility> 13 14 // template <class T, class U> struct pair; 15 16 // pair(pair const&) = default; 17 // pair(pair &&) = default; 18 // pair& operator=(pair const&); 19 // pair& operator=(pair&&); 20 21 // Test that the copy/move constructors and assignment operators are 22 // correctly defined or deleted based on the properties of `T` and `U`. 23 24 #include <cassert> 25 #include <string> 26 #include <tuple> 27 28 #include "archetypes.hpp" 29 using namespace ImplicitTypes; // Get implicitly archetypes 30 31 namespace ConstructorTest { 32 33 template <class T1, bool CanCopy = true, bool CanMove = CanCopy> void test() { 34 using P1 = std::pair<T1, int>; 35 using P2 = std::pair<int, T1>; 36 static_assert(std::is_copy_constructible<P1>::value == CanCopy, ""); 37 static_assert(std::is_move_constructible<P1>::value == CanMove, ""); 38 static_assert(std::is_copy_constructible<P2>::value == CanCopy, ""); 39 static_assert(std::is_move_constructible<P2>::value == CanMove, ""); 40 }; 41 42 } // namespace ConstructorTest 43 44 void test_constructors_exist() { 45 using namespace ConstructorTest; 46 { 47 test<int>(); 48 test<int &>(); 49 test<int &&, false, true>(); 50 test<const int>(); 51 test<const int &>(); 52 test<const int &&, false, true>(); 53 } 54 { 55 test<Copyable>(); 56 test<Copyable &>(); 57 test<Copyable &&, false, true>(); 58 } 59 { 60 test<NonCopyable, false>(); 61 test<NonCopyable &, true>(); 62 test<NonCopyable &&, false, true>(); 63 } 64 { 65 // Even though CopyOnly has an explicitly deleted move constructor 66 // pair's move constructor is only implicitly deleted and therefore 67 // it doesn't participate in overload resolution. 68 test<CopyOnly, true, true>(); 69 test<CopyOnly &, true>(); 70 test<CopyOnly &&, false, true>(); 71 } 72 { 73 test<MoveOnly, false, true>(); 74 test<MoveOnly &, true>(); 75 test<MoveOnly &&, false, true>(); 76 } 77 } 78 79 namespace AssignmentOperatorTest { 80 81 template <class T1, bool CanCopy = true, bool CanMove = CanCopy> void test() { 82 using P1 = std::pair<T1, int>; 83 using P2 = std::pair<int, T1>; 84 static_assert(std::is_copy_assignable<P1>::value == CanCopy, ""); 85 static_assert(std::is_move_assignable<P1>::value == CanMove, ""); 86 static_assert(std::is_copy_assignable<P2>::value == CanCopy, ""); 87 static_assert(std::is_move_assignable<P2>::value == CanMove, ""); 88 }; 89 90 } // namespace AssignmentOperatorTest 91 92 void test_assignment_operator_exists() { 93 using namespace AssignmentOperatorTest; 94 { 95 test<int>(); 96 test<int &>(); 97 test<int &&>(); 98 test<const int, false>(); 99 test<const int &, false>(); 100 test<const int &&, false>(); 101 } 102 { 103 test<Copyable>(); 104 test<Copyable &>(); 105 test<Copyable &&>(); 106 } 107 { 108 test<NonCopyable, false>(); 109 test<NonCopyable &, false>(); 110 test<NonCopyable &&, false>(); 111 } 112 { 113 test<CopyOnly, true>(); 114 test<CopyOnly &, true>(); 115 test<CopyOnly &&, true>(); 116 } 117 { 118 test<MoveOnly, false, true>(); 119 test<MoveOnly &, false, false>(); 120 test<MoveOnly &&, false, true>(); 121 } 122 } 123 124 int main() { 125 test_constructors_exist(); 126 test_assignment_operator_exists(); 127 } 128