1 //===----------------------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
13 // template <class T1, class T2> struct pair
15 // template<class U = T1, class V = T2> pair(U&&, V&&);
21 #include "archetypes.h"
22 #include "test_convertible.h"
24 #include "test_macros.h"
25 using namespace ImplicitTypes
; // Get implicitly archetypes
27 template <class T1
, class T1Arg
,
28 bool CanCopy
= true, bool CanConvert
= CanCopy
>
30 using P1
= std::pair
<T1
, int>;
31 using P2
= std::pair
<int, T1
>;
32 using T2
= int const&;
33 static_assert(std::is_constructible
<P1
, T1Arg
, T2
>::value
== CanCopy
, "");
34 static_assert(test_convertible
<P1
, T1Arg
, T2
>() == CanConvert
, "");
35 static_assert(std::is_constructible
<P2
, T2
, T1Arg
>::value
== CanCopy
, "");
36 static_assert(test_convertible
<P2
, T2
, T1Arg
>() == CanConvert
, "");
40 constexpr explicit ExplicitT(int x
) : value(x
) {}
45 constexpr ImplicitT(int x
) : value(x
) {}
52 typedef std::pair
<std::unique_ptr
<int>, short*> P
;
53 P
p(std::unique_ptr
<int>(new int(3)), nullptr);
54 assert(*p
.first
== 3);
55 assert(p
.second
== nullptr);
58 // Test non-const lvalue and rvalue types
59 test_sfinae
<AllCtors
, AllCtors
&>();
60 test_sfinae
<AllCtors
, AllCtors
&&>();
61 test_sfinae
<ExplicitTypes::AllCtors
, ExplicitTypes::AllCtors
&, true, false>();
62 test_sfinae
<ExplicitTypes::AllCtors
, ExplicitTypes::AllCtors
&&, true, false>();
63 test_sfinae
<CopyOnly
, CopyOnly
&>();
64 test_sfinae
<CopyOnly
, CopyOnly
&&>();
65 test_sfinae
<ExplicitTypes::CopyOnly
, ExplicitTypes::CopyOnly
&, true, false>();
66 test_sfinae
<ExplicitTypes::CopyOnly
, ExplicitTypes::CopyOnly
&&, true, false>();
67 test_sfinae
<MoveOnly
, MoveOnly
&, false>();
68 test_sfinae
<MoveOnly
, MoveOnly
&&>();
69 test_sfinae
<ExplicitTypes::MoveOnly
, ExplicitTypes::MoveOnly
&, false>();
70 test_sfinae
<ExplicitTypes::MoveOnly
, ExplicitTypes::MoveOnly
&&, true, false>();
71 test_sfinae
<NonCopyable
, NonCopyable
&, false>();
72 test_sfinae
<NonCopyable
, NonCopyable
&&, false>();
73 test_sfinae
<ExplicitTypes::NonCopyable
, ExplicitTypes::NonCopyable
&, false>();
74 test_sfinae
<ExplicitTypes::NonCopyable
, ExplicitTypes::NonCopyable
&&, false>();
77 // Test converting types
78 test_sfinae
<ConvertingType
, int&>();
79 test_sfinae
<ConvertingType
, const int&>();
80 test_sfinae
<ConvertingType
, int&&>();
81 test_sfinae
<ConvertingType
, const int&&>();
82 test_sfinae
<ExplicitTypes::ConvertingType
, int&, true, false>();
83 test_sfinae
<ExplicitTypes::ConvertingType
, const int&, true, false>();
84 test_sfinae
<ExplicitTypes::ConvertingType
, int&&, true, false>();
85 test_sfinae
<ExplicitTypes::ConvertingType
, const int&&, true, false>();
88 { // explicit constexpr test
89 constexpr std::pair
<ExplicitT
, ExplicitT
> p(42, 43);
90 static_assert(p
.first
.value
== 42, "");
91 static_assert(p
.second
.value
== 43, "");
93 { // implicit constexpr test
94 constexpr std::pair
<ImplicitT
, ImplicitT
> p
= {42, 43};
95 static_assert(p
.first
.value
== 42, "");
96 static_assert(p
.second
.value
== 43, "");
100 // Test support for http://wg21.link/P1951, default arguments for pair's constructor.
101 // Basically, this turns copies for brace initialization into moves.
102 #if TEST_STD_VER > 20
105 TrackInit() = default;
106 constexpr TrackInit(TrackInit
const& other
) : wasMoveInit(other
.wasMoveInit
), wasCopyInit(true) { }
107 constexpr TrackInit(TrackInit
&& other
) : wasMoveInit(true), wasCopyInit(other
.wasCopyInit
) { }
108 bool wasMoveInit
= false;
109 bool wasCopyInit
= false;
112 // Explicit constructor
115 std::pair
<TrackInit
, int> p({}, 3);
116 assert( p
.first
.wasMoveInit
);
117 assert(!p
.first
.wasCopyInit
);
120 std::pair
<int, TrackInit
> p(3, {});
121 assert( p
.second
.wasMoveInit
);
122 assert(!p
.second
.wasCopyInit
);
126 // Implicit constructor
129 std::pair
<TrackInit
, int> p
= {{}, 3};
130 assert( p
.first
.wasMoveInit
);
131 assert(!p
.first
.wasCopyInit
);
134 std::pair
<int, TrackInit
> p
= {3, {}};
135 assert( p
.second
.wasMoveInit
);
136 assert(!p
.second
.wasCopyInit
);
140 #endif // TEST_STD_VER > 20