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