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 T1, class T2> struct pair 15 16 // template <class U, class V> pair(pair<U, V>&& p); 17 18 #include <utility> 19 #include <memory> 20 #include <cassert> 21 22 #include "archetypes.hpp" 23 #include "test_convertible.hpp" 24 using namespace ImplicitTypes; // Get implicitly archetypes 25 26 template <class T1, class U1, 27 bool CanCopy = true, bool CanConvert = CanCopy> 28 void test_pair_rv() 29 { 30 using P1 = std::pair<T1, int>; 31 using P2 = std::pair<int, T1>; 32 using UP1 = std::pair<U1, int>&&; 33 using UP2 = std::pair<int, U1>&&; 34 static_assert(std::is_constructible<P1, UP1>::value == CanCopy, ""); 35 static_assert(test_convertible<P1, UP1>() == CanConvert, ""); 36 static_assert(std::is_constructible<P2, UP2>::value == CanCopy, ""); 37 static_assert(test_convertible<P2, UP2>() == CanConvert, ""); 38 } 39 40 struct Base 41 { 42 virtual ~Base() {} 43 }; 44 45 struct Derived 46 : public Base 47 { 48 }; 49 50 51 template <class T, class U> 52 struct DPair : public std::pair<T, U> { 53 using Base = std::pair<T, U>; 54 using Base::Base; 55 }; 56 57 struct ExplicitT { 58 constexpr explicit ExplicitT(int x) : value(x) {} 59 int value; 60 }; 61 62 struct ImplicitT { 63 constexpr ImplicitT(int x) : value(x) {} 64 int value; 65 }; 66 67 int main() 68 { 69 { 70 typedef std::pair<std::unique_ptr<Derived>, short> P1; 71 typedef std::pair<std::unique_ptr<Base>, long> P2; 72 P1 p1(std::unique_ptr<Derived>(), 4); 73 P2 p2 = std::move(p1); 74 assert(p2.first == nullptr); 75 assert(p2.second == 4); 76 } 77 { 78 // We allow derived types to use this constructor 79 using P1 = DPair<long, long>; 80 using P2 = std::pair<int, int>; 81 P1 p1(42, 101); 82 P2 p2(std::move(p1)); 83 assert(p2.first == 42); 84 assert(p2.second = 101); 85 } 86 { 87 test_pair_rv<AllCtors, AllCtors>(); 88 test_pair_rv<AllCtors, AllCtors&>(); 89 test_pair_rv<AllCtors, AllCtors&&>(); 90 test_pair_rv<AllCtors, const AllCtors&>(); 91 test_pair_rv<AllCtors, const AllCtors&&>(); 92 93 test_pair_rv<ExplicitTypes::AllCtors, ExplicitTypes::AllCtors>(); 94 test_pair_rv<ExplicitTypes::AllCtors, ExplicitTypes::AllCtors&, true, false>(); 95 test_pair_rv<ExplicitTypes::AllCtors, ExplicitTypes::AllCtors&&, true, false>(); 96 test_pair_rv<ExplicitTypes::AllCtors, const ExplicitTypes::AllCtors&, true, false>(); 97 test_pair_rv<ExplicitTypes::AllCtors, const ExplicitTypes::AllCtors&&, true, false>(); 98 99 test_pair_rv<MoveOnly, MoveOnly>(); 100 test_pair_rv<MoveOnly, MoveOnly&, false>(); 101 test_pair_rv<MoveOnly, MoveOnly&&>(); 102 103 test_pair_rv<ExplicitTypes::MoveOnly, ExplicitTypes::MoveOnly>(); // copy construction 104 test_pair_rv<ExplicitTypes::MoveOnly, ExplicitTypes::MoveOnly&, false>(); 105 test_pair_rv<ExplicitTypes::MoveOnly, ExplicitTypes::MoveOnly&&, true, false>(); 106 107 test_pair_rv<CopyOnly, CopyOnly>(); 108 test_pair_rv<CopyOnly, CopyOnly&>(); 109 test_pair_rv<CopyOnly, CopyOnly&&>(); 110 111 test_pair_rv<ExplicitTypes::CopyOnly, ExplicitTypes::CopyOnly>(); 112 test_pair_rv<ExplicitTypes::CopyOnly, ExplicitTypes::CopyOnly&, true, false>(); 113 test_pair_rv<ExplicitTypes::CopyOnly, ExplicitTypes::CopyOnly&&, true, false>(); 114 115 test_pair_rv<NonCopyable, NonCopyable, false>(); 116 test_pair_rv<NonCopyable, NonCopyable&, false>(); 117 test_pair_rv<NonCopyable, NonCopyable&&, false>(); 118 test_pair_rv<NonCopyable, const NonCopyable&, false>(); 119 test_pair_rv<NonCopyable, const NonCopyable&&, false>(); 120 } 121 { // Test construction of references 122 test_pair_rv<NonCopyable&, NonCopyable&>(); 123 test_pair_rv<NonCopyable&, NonCopyable&&>(); 124 test_pair_rv<NonCopyable&, NonCopyable const&, false>(); 125 test_pair_rv<NonCopyable const&, NonCopyable&&>(); 126 test_pair_rv<NonCopyable&&, NonCopyable&&>(); 127 128 test_pair_rv<ConvertingType&, int, false>(); 129 test_pair_rv<ExplicitTypes::ConvertingType&, int, false>(); 130 // Unfortunately the below conversions are allowed and create dangling 131 // references. 132 //test_pair_rv<ConvertingType&&, int>(); 133 //test_pair_rv<ConvertingType const&, int>(); 134 //test_pair_rv<ConvertingType const&&, int>(); 135 // But these are not because the converting constructor is explicit. 136 test_pair_rv<ExplicitTypes::ConvertingType&&, int, false>(); 137 test_pair_rv<ExplicitTypes::ConvertingType const&, int, false>(); 138 test_pair_rv<ExplicitTypes::ConvertingType const&&, int, false>(); 139 } 140 { 141 test_pair_rv<AllCtors, int, false>(); 142 test_pair_rv<ExplicitTypes::AllCtors, int, false>(); 143 test_pair_rv<ConvertingType, int>(); 144 test_pair_rv<ExplicitTypes::ConvertingType, int, true, false>(); 145 146 test_pair_rv<ConvertingType, int>(); 147 test_pair_rv<ConvertingType, ConvertingType>(); 148 test_pair_rv<ConvertingType, ConvertingType const&>(); 149 test_pair_rv<ConvertingType, ConvertingType&>(); 150 test_pair_rv<ConvertingType, ConvertingType&&>(); 151 152 test_pair_rv<ExplicitTypes::ConvertingType, int, true, false>(); 153 test_pair_rv<ExplicitTypes::ConvertingType, int&, true, false>(); 154 test_pair_rv<ExplicitTypes::ConvertingType, const int&, true, false>(); 155 test_pair_rv<ExplicitTypes::ConvertingType, int&&, true, false>(); 156 test_pair_rv<ExplicitTypes::ConvertingType, const int&&, true, false>(); 157 158 test_pair_rv<ExplicitTypes::ConvertingType, ExplicitTypes::ConvertingType>(); 159 test_pair_rv<ExplicitTypes::ConvertingType, ExplicitTypes::ConvertingType const&, true, false>(); 160 test_pair_rv<ExplicitTypes::ConvertingType, ExplicitTypes::ConvertingType&, true, false>(); 161 test_pair_rv<ExplicitTypes::ConvertingType, ExplicitTypes::ConvertingType&&, true, false>(); 162 } 163 #if TEST_STD_VER > 11 164 { // explicit constexpr test 165 constexpr std::pair<int, int> p1(42, 43); 166 constexpr std::pair<ExplicitT, ExplicitT> p2(std::move(p1)); 167 static_assert(p2.first.value == 42, ""); 168 static_assert(p2.second.value == 43, ""); 169 } 170 { // implicit constexpr test 171 constexpr std::pair<int, int> p1(42, 43); 172 constexpr std::pair<ImplicitT, ImplicitT> p2 = std::move(p1); 173 static_assert(p2.first.value == 42, ""); 174 static_assert(p2.second.value == 43, ""); 175 } 176 #endif 177 } 178