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 T, class U> struct pair;
15 // pair(pair const&) = default;
16 // pair(pair &&) = default;
17 // pair& operator=(pair const&);
18 // pair& operator=(pair&&);
20 // Test that the copy/move constructors and assignment operators are
21 // correctly defined or deleted based on the properties of `T` and `U`.
27 #include "archetypes.h"
29 #include "test_macros.h"
30 using namespace ImplicitTypes
; // Get implicitly archetypes
32 namespace ConstructorTest
{
34 template <class T1
, bool CanCopy
= true, bool CanMove
= CanCopy
> void test() {
35 using P1
= std::pair
<T1
, int>;
36 using P2
= std::pair
<int, T1
>;
37 static_assert(std::is_copy_constructible
<P1
>::value
== CanCopy
, "");
38 static_assert(std::is_move_constructible
<P1
>::value
== CanMove
, "");
39 static_assert(std::is_copy_constructible
<P2
>::value
== CanCopy
, "");
40 static_assert(std::is_move_constructible
<P2
>::value
== CanMove
, "");
43 } // namespace ConstructorTest
45 void test_constructors_exist() {
46 using namespace ConstructorTest
;
50 test
<int &&, false, true>();
53 test
<const int &&, false, true>();
58 test
<Copyable
&&, false, true>();
61 test
<NonCopyable
, false>();
62 test
<NonCopyable
&, true>();
63 test
<NonCopyable
&&, false, true>();
66 // Even though CopyOnly has an explicitly deleted move constructor
67 // pair's move constructor is only implicitly deleted and therefore
68 // it doesn't participate in overload resolution.
69 test
<CopyOnly
, true, true>();
70 test
<CopyOnly
&, true>();
71 test
<CopyOnly
&&, false, true>();
74 test
<MoveOnly
, false, true>();
75 test
<MoveOnly
&, true>();
76 test
<MoveOnly
&&, false, true>();
80 namespace AssignmentOperatorTest
{
82 template <class T1
, bool CanCopy
= true, bool CanMove
= CanCopy
> void test() {
83 using P1
= std::pair
<T1
, int>;
84 using P2
= std::pair
<int, T1
>;
85 static_assert(std::is_copy_assignable
<P1
>::value
== CanCopy
, "");
86 static_assert(std::is_move_assignable
<P1
>::value
== CanMove
, "");
87 static_assert(std::is_copy_assignable
<P2
>::value
== CanCopy
, "");
88 static_assert(std::is_move_assignable
<P2
>::value
== CanMove
, "");
91 } // namespace AssignmentOperatorTest
93 void test_assignment_operator_exists() {
94 using namespace AssignmentOperatorTest
;
99 test
<const int, false>();
100 test
<const int &, false>();
101 test
<const int &&, false>();
109 test
<NonCopyable
, false>();
110 test
<NonCopyable
&, false>();
111 test
<NonCopyable
&&, false>();
114 test
<CopyOnly
, true>();
115 test
<CopyOnly
&, true>();
116 test
<CopyOnly
&&, true>();
119 test
<MoveOnly
, false, true>();
120 test
<MoveOnly
&, false, false>();
121 test
<MoveOnly
&&, false, true>();
125 int main(int, char**) {
126 test_constructors_exist();
127 test_assignment_operator_exists();