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

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