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// UNSUPPORTED: c++03
10
11// <utility>
12
13// template <class T1, class T2> struct pair
14
15// template <class U, class V>
16// constexpr explicit(see below) pair(pair<U, V>&& p);
17
18#include <utility>
19#include <memory>
20#include <cassert>
21
22#include "archetypes.h"
23#include "test_convertible.h"
24
25#include "test_macros.h"
26using namespace ImplicitTypes; // Get implicitly archetypes
27
28template <class T1, class U1,
29 bool CanCopy = true, bool CanConvert = CanCopy>
30void test_pair_rv()
31{
32 using P1 = std::pair<T1, int>;
33 using P2 = std::pair<int, T1>;
34 using UP1 = std::pair<U1, int>&&;
35 using UP2 = std::pair<int, U1>&&;
36 static_assert(std::is_constructible<P1, UP1>::value == CanCopy, "");
37 static_assert(test_convertible<P1, UP1>() == CanConvert, "");
38 static_assert(std::is_constructible<P2, UP2>::value == CanCopy, "");
39 static_assert(test_convertible<P2, UP2>() == CanConvert, "");
40}
41
42struct Base
43{
44 virtual ~Base() {}
45};
46
47struct Derived
48 : public Base
49{
50};
51
52
53template <class T, class U>
54struct DPair : public std::pair<T, U> {
55 using Base = std::pair<T, U>;
56 using Base::Base;
57};
58
59struct ExplicitT {
60 constexpr explicit ExplicitT(int x) : value(x) {}
61 int value;
62};
63
64struct ImplicitT {
65 constexpr ImplicitT(int x) : value(x) {}
66 int value;
67};
68
69struct NotCopyOrMoveConstructible {
70 NotCopyOrMoveConstructible() = default;
71 NotCopyOrMoveConstructible(NotCopyOrMoveConstructible const&) = delete;
72 NotCopyOrMoveConstructible(NotCopyOrMoveConstructible&&) = delete;
73};
74
75struct NonCopyConstructible {
76 NonCopyConstructible(NonCopyConstructible const&) = delete;
77 NonCopyConstructible(NonCopyConstructible&&) = default;
78};
79
80int main(int, char**)
81{
82 {
83 typedef std::pair<std::unique_ptr<Derived>, int> P1;
84 typedef std::pair<std::unique_ptr<Base>, long> P2;
85 P1 p1(std::unique_ptr<Derived>(), 4);
86 P2 p2 = std::move(p1);
87 assert(p2.first == nullptr);
88 assert(p2.second == 4);
89 }
90 {
91 // We allow derived types to use this constructor
92 using P1 = DPair<long, long>;
93 using P2 = std::pair<int, int>;
94 P1 p1(42, 101);
95 P2 p2(std::move(p1));
96 assert(p2.first == 42);
97 assert(p2.second == 101);
98 }
99 {
100 test_pair_rv<AllCtors, AllCtors>();
101 test_pair_rv<AllCtors, AllCtors&>();
102 test_pair_rv<AllCtors, AllCtors&&>();
103 test_pair_rv<AllCtors, const AllCtors&>();
104 test_pair_rv<AllCtors, const AllCtors&&>();
105
106 test_pair_rv<ExplicitTypes::AllCtors, ExplicitTypes::AllCtors>();
107 test_pair_rv<ExplicitTypes::AllCtors, ExplicitTypes::AllCtors&, true, false>();
108 test_pair_rv<ExplicitTypes::AllCtors, ExplicitTypes::AllCtors&&, true, false>();
109 test_pair_rv<ExplicitTypes::AllCtors, const ExplicitTypes::AllCtors&, true, false>();
110 test_pair_rv<ExplicitTypes::AllCtors, const ExplicitTypes::AllCtors&&, true, false>();
111
112 test_pair_rv<MoveOnly, MoveOnly>();
113 test_pair_rv<MoveOnly, MoveOnly&, false>();
114 test_pair_rv<MoveOnly, MoveOnly&&>();
115
116 test_pair_rv<ExplicitTypes::MoveOnly, ExplicitTypes::MoveOnly>(); // copy construction
117 test_pair_rv<ExplicitTypes::MoveOnly, ExplicitTypes::MoveOnly&, false>();
118 test_pair_rv<ExplicitTypes::MoveOnly, ExplicitTypes::MoveOnly&&, true, false>();
119
120 test_pair_rv<CopyOnly, CopyOnly>();
121 test_pair_rv<CopyOnly, CopyOnly&>();
122 test_pair_rv<CopyOnly, CopyOnly&&>();
123
124 test_pair_rv<ExplicitTypes::CopyOnly, ExplicitTypes::CopyOnly>();
125 test_pair_rv<ExplicitTypes::CopyOnly, ExplicitTypes::CopyOnly&, true, false>();
126 test_pair_rv<ExplicitTypes::CopyOnly, ExplicitTypes::CopyOnly&&, true, false>();
127
128 test_pair_rv<NonCopyable, NonCopyable, false>();
129 test_pair_rv<NonCopyable, NonCopyable&, false>();
130 test_pair_rv<NonCopyable, NonCopyable&&, false>();
131 test_pair_rv<NonCopyable, const NonCopyable&, false>();
132 test_pair_rv<NonCopyable, const NonCopyable&&, false>();
133 }
134 { // Test construction of references
135 test_pair_rv<NonCopyable&, NonCopyable&>();
136 test_pair_rv<NonCopyable&, NonCopyable&&>();
137 test_pair_rv<NonCopyable&, NonCopyable const&, false>();
138 test_pair_rv<NonCopyable const&, NonCopyable&&>();
139 test_pair_rv<NonCopyable&&, NonCopyable&&>();
140
141 test_pair_rv<ConvertingType&, int, false>();
142 test_pair_rv<ExplicitTypes::ConvertingType&, int, false>();
143 // Unfortunately the below conversions are allowed and create dangling
144 // references.
145 //test_pair_rv<ConvertingType&&, int>();
146 //test_pair_rv<ConvertingType const&, int>();
147 //test_pair_rv<ConvertingType const&&, int>();
148 // But these are not because the converting constructor is explicit.
149 test_pair_rv<ExplicitTypes::ConvertingType&&, int, false>();
150 test_pair_rv<ExplicitTypes::ConvertingType const&, int, false>();
151 test_pair_rv<ExplicitTypes::ConvertingType const&&, int, false>();
152 }
153 {
154 test_pair_rv<AllCtors, int, false>();
155 test_pair_rv<ExplicitTypes::AllCtors, int, false>();
156 test_pair_rv<ConvertingType, int>();
157 test_pair_rv<ExplicitTypes::ConvertingType, int, true, false>();
158
159 test_pair_rv<ConvertingType, int>();
160 test_pair_rv<ConvertingType, ConvertingType>();
161 test_pair_rv<ConvertingType, ConvertingType const&>();
162 test_pair_rv<ConvertingType, ConvertingType&>();
163 test_pair_rv<ConvertingType, ConvertingType&&>();
164
165 test_pair_rv<ExplicitTypes::ConvertingType, int, true, false>();
166 test_pair_rv<ExplicitTypes::ConvertingType, int&, true, false>();
167 test_pair_rv<ExplicitTypes::ConvertingType, const int&, true, false>();
168 test_pair_rv<ExplicitTypes::ConvertingType, int&&, true, false>();
169 test_pair_rv<ExplicitTypes::ConvertingType, const int&&, true, false>();
170
171 test_pair_rv<ExplicitTypes::ConvertingType, ExplicitTypes::ConvertingType>();
172 test_pair_rv<ExplicitTypes::ConvertingType, ExplicitTypes::ConvertingType const&, true, false>();
173 test_pair_rv<ExplicitTypes::ConvertingType, ExplicitTypes::ConvertingType&, true, false>();
174 test_pair_rv<ExplicitTypes::ConvertingType, ExplicitTypes::ConvertingType&&, true, false>();
175 }
176 {
177 // When constructing a pair containing a reference, we only bind the
178 // reference, so it doesn't matter whether the type is or isn't
179 // copy/move constructible.
180 {
181 using P1 = std::pair<NotCopyOrMoveConstructible&, long>;
182 using P2 = std::pair<NotCopyOrMoveConstructible&, int>;
183 static_assert(std::is_constructible<P1, P2&&>::value, "");
184
185 NotCopyOrMoveConstructible obj;
186 P2 p2{obj, 3};
187 P1 p1(std::move(p2));
188 assert(&p1.first == &obj);
189 assert(&p2.first == &obj);
190 }
191 {
192 using P1 = std::pair<NotCopyOrMoveConstructible&&, long>;
193 using P2 = std::pair<NotCopyOrMoveConstructible&&, int>;
194 static_assert(std::is_constructible<P1, P2&&>::value, "");
195
196 NotCopyOrMoveConstructible obj;
197 P2 p2{std::move(obj), 3};
198 P1 p1(std::move(p2));
199 assert(&p1.first == &obj);
200 assert(&p2.first == &obj);
201 }
202 }
203 {
204 // Make sure we can't move-construct from a pair containing a reference
205 // if that type isn't copy-constructible (since otherwise we'd be stealing
206 // the object through the reference).
207 using P1 = std::pair<NonCopyConstructible, long>;
208 using P2 = std::pair<NonCopyConstructible&, int>;
209 static_assert(!std::is_constructible<P1, P2&&>::value, "");
210 }
211#if TEST_STD_VER > 11
212 { // explicit constexpr test
213 constexpr std::pair<int, int> p1(42, 43);
214 constexpr std::pair<ExplicitT, ExplicitT> p2(std::move(p1));
215 static_assert(p2.first.value == 42, "");
216 static_assert(p2.second.value == 43, "");
217 }
218 { // implicit constexpr test
219 constexpr std::pair<int, int> p1(42, 43);
220 constexpr std::pair<ImplicitT, ImplicitT> p2 = std::move(p1);
221 static_assert(p2.first.value == 42, "");
222 static_assert(p2.second.value == 43, "");
223 }
224#endif
225
226 return 0;
227}
228

source code of libcxx/test/std/utilities/utility/pairs/pairs.pair/ctor.pair_U_V_move.pass.cpp