Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / libcxx / test / std / utilities / utility / pairs / pairs.pair / assign_rv_pair.pass.cpp
blob8e5d9c39ae8868a786b6289f408af5561573467b
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 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: c++03
11 // <utility>
13 // template <class T1, class T2> struct pair
15 // pair& operator=(pair&& p);
17 #include <utility>
18 #include <memory>
19 #include <cassert>
21 #include "test_macros.h"
22 #include "archetypes.h"
24 struct CountAssign {
25 int copied = 0;
26 int moved = 0;
27 TEST_CONSTEXPR_CXX20 CountAssign() = default;
28 TEST_CONSTEXPR_CXX20 CountAssign& operator=(CountAssign const&) {
29 ++copied;
30 return *this;
32 TEST_CONSTEXPR_CXX20 CountAssign& operator=(CountAssign&&) {
33 ++moved;
34 return *this;
38 struct NotAssignable {
39 NotAssignable& operator=(NotAssignable const&) = delete;
40 NotAssignable& operator=(NotAssignable&&) = delete;
43 struct MoveAssignable {
44 MoveAssignable& operator=(MoveAssignable const&) = delete;
45 MoveAssignable& operator=(MoveAssignable&&) = default;
48 struct CopyAssignable {
49 CopyAssignable& operator=(CopyAssignable const&) = default;
50 CopyAssignable& operator=(CopyAssignable&&) = delete;
53 TEST_CONSTEXPR_CXX20 bool test() {
55 typedef std::pair<ConstexprTestTypes::MoveOnly, int> P;
56 P p1(3, 4);
57 P p2;
58 p2 = std::move(p1);
59 assert(p2.first.value == 3);
60 assert(p2.second == 4);
63 using P = std::pair<int&, int&&>;
64 int x = 42;
65 int y = 101;
66 int x2 = -1;
67 int y2 = 300;
68 P p1(x, std::move(y));
69 P p2(x2, std::move(y2));
70 p1 = std::move(p2);
71 assert(p1.first == x2);
72 assert(p1.second == y2);
75 using P = std::pair<int, ConstexprTestTypes::DefaultOnly>;
76 static_assert(!std::is_move_assignable<P>::value, "");
79 // The move decays to the copy constructor
80 using P = std::pair<CountAssign, ConstexprTestTypes::CopyOnly>;
81 static_assert(std::is_move_assignable<P>::value, "");
82 P p;
83 P p2;
84 p = std::move(p2);
85 assert(p.first.moved == 0);
86 assert(p.first.copied == 1);
87 assert(p2.first.moved == 0);
88 assert(p2.first.copied == 0);
91 using P = std::pair<CountAssign, ConstexprTestTypes::MoveOnly>;
92 static_assert(std::is_move_assignable<P>::value, "");
93 P p;
94 P p2;
95 p = std::move(p2);
96 assert(p.first.moved == 1);
97 assert(p.first.copied == 0);
98 assert(p2.first.moved == 0);
99 assert(p2.first.copied == 0);
102 using P1 = std::pair<int, NotAssignable>;
103 using P2 = std::pair<NotAssignable, int>;
104 using P3 = std::pair<NotAssignable, NotAssignable>;
105 static_assert(!std::is_move_assignable<P1>::value, "");
106 static_assert(!std::is_move_assignable<P2>::value, "");
107 static_assert(!std::is_move_assignable<P3>::value, "");
110 // We assign through the reference and don't move out of the incoming ref,
111 // so this doesn't work (but would if the type were CopyAssignable).
112 using P1 = std::pair<MoveAssignable&, int>;
113 static_assert(!std::is_move_assignable<P1>::value, "");
115 // ... works if it's CopyAssignable
116 using P2 = std::pair<CopyAssignable&, int>;
117 static_assert(std::is_move_assignable<P2>::value, "");
119 // For rvalue-references, we can move-assign if the type is MoveAssignable
120 // or CopyAssignable (since in the worst case the move will decay into a copy).
121 using P3 = std::pair<MoveAssignable&&, int>;
122 using P4 = std::pair<CopyAssignable&&, int>;
123 static_assert(std::is_move_assignable<P3>::value, "");
124 static_assert(std::is_move_assignable<P4>::value, "");
126 // In all cases, we can't move-assign if the types are not assignable,
127 // since we assign through the reference.
128 using P5 = std::pair<NotAssignable&, int>;
129 using P6 = std::pair<NotAssignable&&, int>;
130 static_assert(!std::is_move_assignable<P5>::value, "");
131 static_assert(!std::is_move_assignable<P6>::value, "");
133 return true;
136 int main(int, char**) {
137 test();
138 #if TEST_STD_VER >= 20
139 static_assert(test());
140 #endif
142 return 0;