1 //===----------------------------------------------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 // UNSUPPORTED: c++98, c++03
11
12 // <utility>
13
14 // template <class T1, class T2> struct pair
15
16 // pair& operator=(pair const& p);
17
18 #include <utility>
19 #include <memory>
20 #include <cassert>
21
22
23 struct NonAssignable {
24 NonAssignable& operator=(NonAssignable const&) = delete;
25 NonAssignable& operator=(NonAssignable&&) = delete;
26 };
27 struct CopyAssignable {
28 CopyAssignable() = default;
29 CopyAssignable(CopyAssignable const&) = default;
30 CopyAssignable& operator=(CopyAssignable const&) = default;
31 CopyAssignable& operator=(CopyAssignable&&) = delete;
32 };
33 struct MoveAssignable {
34 MoveAssignable() = default;
35 MoveAssignable& operator=(MoveAssignable const&) = delete;
36 MoveAssignable& operator=(MoveAssignable&&) = default;
37 };
38
39 struct CountAssign {
40 static int copied;
41 static int moved;
resetCountAssign42 static void reset() { copied = moved = 0; }
43 CountAssign() = default;
operator =CountAssign44 CountAssign& operator=(CountAssign const&) { ++copied; return *this; }
operator =CountAssign45 CountAssign& operator=(CountAssign&&) { ++moved; return *this; }
46 };
47 int CountAssign::copied = 0;
48 int CountAssign::moved = 0;
49
50 struct Incomplete;
51 extern Incomplete inc_obj;
52
main()53 int main()
54 {
55 {
56 typedef std::pair<CopyAssignable, short> P;
57 const P p1(CopyAssignable(), 4);
58 P p2;
59 p2 = p1;
60 assert(p2.second == 4);
61 }
62 {
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 = p2;
71 assert(p1.first == x2);
72 assert(p1.second == y2);
73 }
74 {
75 using P = std::pair<int, NonAssignable>;
76 static_assert(!std::is_copy_assignable<P>::value, "");
77 }
78 {
79 CountAssign::reset();
80 using P = std::pair<CountAssign, CopyAssignable>;
81 static_assert(std::is_copy_assignable<P>::value, "");
82 P p;
83 P p2;
84 p = p2;
85 assert(CountAssign::copied == 1);
86 assert(CountAssign::moved == 0);
87 }
88 {
89 using P = std::pair<int, MoveAssignable>;
90 static_assert(!std::is_copy_assignable<P>::value, "");
91 }
92 {
93 using P = std::pair<int, Incomplete&>;
94 static_assert(!std::is_copy_assignable<P>::value, "");
95 P p(42, inc_obj);
96 assert(&p.second == &inc_obj);
97 }
98 }
99
100 struct Incomplete {};
101 Incomplete inc_obj;
102