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 { |
27 | constexpr explicit ExplicitT(int x) : value(x) {} |
28 | constexpr explicit ExplicitT(ExplicitT const& o) : value(o.value) {} |
29 | int value; |
30 | }; |
31 | |
32 | struct ImplicitT { |
33 | constexpr ImplicitT(int x) : value(x) {} |
34 | constexpr ImplicitT(ImplicitT const& o) : value(o.value) {} |
35 | int value; |
36 | }; |
37 | |
38 | template <class T1, |
39 | bool CanCopy = true, bool CanConvert = CanCopy> |
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 | |
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 | |