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 // template<class U, class V> pair& operator=(tuple<U, V>&& p);
17
18 #include <utility>
19 #include <tuple>
20 #include <array>
21 #include <memory>
22 #include <cassert>
23
24 // Clang warns about missing braces when initializing std::array.
25 #if defined(__clang__)
26 #pragma clang diagnostic ignored "-Wmissing-braces"
27 #endif
28
29 struct CountingType {
30 static int constructed;
31 static int copy_constructed;
32 static int move_constructed;
33 static int assigned;
34 static int copy_assigned;
35 static int move_assigned;
resetCountingType36 static void reset() {
37 constructed = copy_constructed = move_constructed = 0;
38 assigned = copy_assigned = move_assigned = 0;
39 }
CountingTypeCountingType40 CountingType() : value(0) { ++constructed; }
CountingTypeCountingType41 CountingType(int v) : value(v) { ++constructed; }
CountingTypeCountingType42 CountingType(CountingType const& o) : value(o.value) { ++constructed; ++copy_constructed; }
CountingTypeCountingType43 CountingType(CountingType&& o) : value(o.value) { ++constructed; ++move_constructed; o.value = -1;}
44
operator =CountingType45 CountingType& operator=(CountingType const& o) {
46 ++assigned;
47 ++copy_assigned;
48 value = o.value;
49 return *this;
50 }
operator =CountingType51 CountingType& operator=(CountingType&& o) {
52 ++assigned;
53 ++move_assigned;
54 value = o.value;
55 o.value = -1;
56 return *this;
57 }
58 int value;
59 };
60 int CountingType::constructed;
61 int CountingType::copy_constructed;
62 int CountingType::move_constructed;
63 int CountingType::assigned;
64 int CountingType::copy_assigned;
65 int CountingType::move_assigned;
66
main()67 int main()
68 {
69 using C = CountingType;
70 {
71 using P = std::pair<int, C>;
72 using T = std::tuple<int, C>;
73 T t(42, C{42});
74 P p(101, C{101});
75 C::reset();
76 p = t;
77 assert(C::constructed == 0);
78 assert(C::assigned == 1);
79 assert(C::copy_assigned == 1);
80 assert(C::move_assigned == 0);
81 assert(p.first == 42);
82 assert(p.second.value == 42);
83 }
84 {
85 using P = std::pair<int, C>;
86 using T = std::tuple<int, C>;
87 T t(42, -42);
88 P p(101, 101);
89 C::reset();
90 p = std::move(t);
91 assert(C::constructed == 0);
92 assert(C::assigned == 1);
93 assert(C::copy_assigned == 0);
94 assert(C::move_assigned == 1);
95 assert(p.first == 42);
96 assert(p.second.value == -42);
97 }
98 {
99 using P = std::pair<C, C>;
100 using T = std::array<C, 2>;
101 T t = {42, -42};
102 P p{101, 101};
103 C::reset();
104 p = t;
105 assert(C::constructed == 0);
106 assert(C::assigned == 2);
107 assert(C::copy_assigned == 2);
108 assert(C::move_assigned == 0);
109 assert(p.first.value == 42);
110 assert(p.second.value == -42);
111 }
112 {
113 using P = std::pair<C, C>;
114 using T = std::array<C, 2>;
115 T t = {42, -42};
116 P p{101, 101};
117 C::reset();
118 p = t;
119 assert(C::constructed == 0);
120 assert(C::assigned == 2);
121 assert(C::copy_assigned == 2);
122 assert(C::move_assigned == 0);
123 assert(p.first.value == 42);
124 assert(p.second.value == -42);
125 }
126 {
127 using P = std::pair<C, C>;
128 using T = std::array<C, 2>;
129 T t = {42, -42};
130 P p{101, 101};
131 C::reset();
132 p = std::move(t);
133 assert(C::constructed == 0);
134 assert(C::assigned == 2);
135 assert(C::copy_assigned == 0);
136 assert(C::move_assigned == 2);
137 assert(p.first.value == 42);
138 assert(p.second.value == -42);
139 }
140 }
141