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 // The test fails due to the missing is_trivially_constructible intrinsic. 11 // XFAIL: gcc-4.9 12 13 // <utility> 14 15 // template <class T1, class T2> struct pair 16 17 // Test that we properly provide the trivial copy operations by default. 18 19 // FreeBSD provides the old ABI. This test checks the new ABI so we need 20 // to manually turn it on. 21 #if defined(__FreeBSD__) 22 #define _LIBCPP_ABI_UNSTABLE 23 #endif 24 25 #include <utility> 26 #include <type_traits> 27 #include <cstdlib> 28 #include <cassert> 29 30 #include "test_macros.h" 31 32 #if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR) 33 #error Non-trivial ctor ABI macro defined 34 #endif 35 36 template <class T> 37 struct HasTrivialABI : std::integral_constant<bool, 38 std::is_trivially_destructible<T>::value 39 && (!std::is_copy_constructible<T>::value || std::is_trivially_copy_constructible<T>::value) 40 #if TEST_STD_VER >= 11 41 && (!std::is_move_constructible<T>::value || std::is_trivially_move_constructible<T>::value) 42 #endif 43 > {}; 44 45 #if TEST_STD_VER >= 11 46 struct NonTrivialDtor { 47 NonTrivialDtor(NonTrivialDtor const&) = default; 48 ~NonTrivialDtor(); 49 }; 50 NonTrivialDtor::~NonTrivialDtor() {} 51 static_assert(!HasTrivialABI<NonTrivialDtor>::value, ""); 52 53 struct NonTrivialCopy { 54 NonTrivialCopy(NonTrivialCopy const&); 55 }; 56 NonTrivialCopy::NonTrivialCopy(NonTrivialCopy const&) {} 57 static_assert(!HasTrivialABI<NonTrivialCopy>::value, ""); 58 59 struct NonTrivialMove { 60 NonTrivialMove(NonTrivialMove const&) = default; 61 NonTrivialMove(NonTrivialMove&&); 62 }; 63 NonTrivialMove::NonTrivialMove(NonTrivialMove&&) {} 64 static_assert(!HasTrivialABI<NonTrivialMove>::value, ""); 65 66 struct DeletedCopy { 67 DeletedCopy(DeletedCopy const&) = delete; 68 DeletedCopy(DeletedCopy&&) = default; 69 }; 70 static_assert(HasTrivialABI<DeletedCopy>::value, ""); 71 72 struct TrivialMove { 73 TrivialMove(TrivialMove &&) = default; 74 }; 75 static_assert(HasTrivialABI<TrivialMove>::value, ""); 76 77 struct Trivial { 78 Trivial(Trivial const&) = default; 79 }; 80 static_assert(HasTrivialABI<Trivial>::value, ""); 81 #endif 82 83 84 int main() 85 { 86 { 87 typedef std::pair<int, short> P; 88 static_assert(std::is_copy_constructible<P>::value, ""); 89 static_assert(HasTrivialABI<P>::value, ""); 90 } 91 #if TEST_STD_VER >= 11 92 { 93 typedef std::pair<int, short> P; 94 static_assert(std::is_move_constructible<P>::value, ""); 95 static_assert(HasTrivialABI<P>::value, ""); 96 } 97 { 98 using P = std::pair<NonTrivialDtor, int>; 99 static_assert(!std::is_trivially_destructible<P>::value, ""); 100 static_assert(std::is_copy_constructible<P>::value, ""); 101 static_assert(!std::is_trivially_copy_constructible<P>::value, ""); 102 static_assert(std::is_move_constructible<P>::value, ""); 103 static_assert(!std::is_trivially_move_constructible<P>::value, ""); 104 static_assert(!HasTrivialABI<P>::value, ""); 105 } 106 { 107 using P = std::pair<NonTrivialCopy, int>; 108 static_assert(std::is_copy_constructible<P>::value, ""); 109 static_assert(!std::is_trivially_copy_constructible<P>::value, ""); 110 static_assert(std::is_move_constructible<P>::value, ""); 111 static_assert(!std::is_trivially_move_constructible<P>::value, ""); 112 static_assert(!HasTrivialABI<P>::value, ""); 113 } 114 { 115 using P = std::pair<NonTrivialMove, int>; 116 static_assert(std::is_copy_constructible<P>::value, ""); 117 static_assert(std::is_trivially_copy_constructible<P>::value, ""); 118 static_assert(std::is_move_constructible<P>::value, ""); 119 static_assert(!std::is_trivially_move_constructible<P>::value, ""); 120 static_assert(!HasTrivialABI<P>::value, ""); 121 } 122 { 123 using P = std::pair<DeletedCopy, int>; 124 static_assert(!std::is_copy_constructible<P>::value, ""); 125 static_assert(!std::is_trivially_copy_constructible<P>::value, ""); 126 static_assert(std::is_move_constructible<P>::value, ""); 127 static_assert(std::is_trivially_move_constructible<P>::value, ""); 128 static_assert(HasTrivialABI<P>::value, ""); 129 } 130 { 131 using P = std::pair<Trivial, int>; 132 static_assert(std::is_copy_constructible<P>::value, ""); 133 static_assert(std::is_trivially_copy_constructible<P>::value, ""); 134 static_assert(std::is_move_constructible<P>::value, ""); 135 static_assert(std::is_trivially_move_constructible<P>::value, ""); 136 static_assert(HasTrivialABI<P>::value, ""); 137 } 138 { 139 using P = std::pair<TrivialMove, int>; 140 static_assert(!std::is_copy_constructible<P>::value, ""); 141 static_assert(!std::is_trivially_copy_constructible<P>::value, ""); 142 static_assert(std::is_move_constructible<P>::value, ""); 143 static_assert(std::is_trivially_move_constructible<P>::value, ""); 144 static_assert(HasTrivialABI<P>::value, ""); 145 } 146 #endif 147 } 148