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 // pair(const T1& x, const T2& y);
16 
17 #include <utility>
18 #include <cassert>
19 
20 #include "archetypes.h"
21 #include "test_convertible.h"
22 
23 #include "test_macros.h"
24 using namespace ImplicitTypes; // Get implicitly archetypes
25 
26 struct ExplicitT {
ExplicitTExplicitT27   constexpr explicit ExplicitT(int x) : value(x) {}
ExplicitTExplicitT28   constexpr explicit ExplicitT(ExplicitT const& o) : value(o.value) {}
29   int value;
30 };
31 
32 struct ImplicitT {
ImplicitTImplicitT33   constexpr ImplicitT(int x) : value(x) {}
ImplicitTImplicitT34   constexpr ImplicitT(ImplicitT const& o) : value(o.value) {}
35   int value;
36 };
37 
38 template <class T1,
39           bool CanCopy = true, bool CanConvert = CanCopy>
test_sfinae()40 void test_sfinae() {
41     using P1 = std::pair<T1, int>;
42     using P2 = std::pair<int, T1>;
43     using T1Arg = T1 const&;
44     using T2 = int const&;
45     static_assert(std::is_constructible<P1, T1Arg, T2>::value == CanCopy, "");
46     static_assert(test_convertible<P1,   T1Arg, T2>() == CanConvert, "");
47     static_assert(std::is_constructible<P2, T2,   T1Arg>::value == CanCopy, "");
48     static_assert(test_convertible<P2,   T2,   T1Arg>() == CanConvert, "");
49 }
50 
main(int,char **)51 int main(int, char**)
52 {
53     {
54         typedef std::pair<float, short*> P;
55         P p(3.5f, 0);
56         assert(p.first == 3.5f);
57         assert(p.second == nullptr);
58     }
59     {
60         typedef std::pair<ImplicitT, int> P;
61         P p(1, 2);
62         assert(p.first.value == 1);
63         assert(p.second == 2);
64     }
65     {
66         test_sfinae<AllCtors>();
67         test_sfinae<ExplicitTypes::AllCtors, true, false>();
68         test_sfinae<CopyOnly>();
69         test_sfinae<ExplicitTypes::CopyOnly, true, false>();
70         test_sfinae<MoveOnly, false>();
71         test_sfinae<ExplicitTypes::MoveOnly, false>();
72         test_sfinae<NonCopyable, false>();
73         test_sfinae<ExplicitTypes::NonCopyable, false>();
74     }
75 #if TEST_STD_VER > 11
76     {
77         typedef std::pair<float, short*> P;
78         constexpr P p(3.5f, 0);
79         static_assert(p.first == 3.5f, "");
80         static_assert(p.second == nullptr, "");
81     }
82     {
83         using P = std::pair<ExplicitT, int>;
84         constexpr ExplicitT e(42);
85         constexpr int x = 10;
86         constexpr P p(e, x);
87         static_assert(p.first.value == 42, "");
88         static_assert(p.second == 10, "");
89     }
90     {
91         using P = std::pair<ImplicitT, int>;
92         constexpr ImplicitT e(42);
93         constexpr int x = 10;
94         constexpr P p = {e, x};
95         static_assert(p.first.value == 42, "");
96         static_assert(p.second == 10, "");
97     }
98 #endif
99 
100   return 0;
101 }
102