]>
Commit | Line | Data |
---|---|---|
6458742a | 1 | // { dg-do run { target c++17 } } |
b95170d3 | 2 | |
99dee823 | 3 | // Copyright (C) 2015-2021 Free Software Foundation, Inc. |
b95170d3 VV |
4 | // |
5 | // This file is part of the GNU ISO C++ Library. This library is free | |
6 | // software; you can redistribute it and/or modify it under the | |
7 | // terms of the GNU General Public License as published by the | |
8 | // Free Software Foundation; either version 3, or (at your option) | |
9 | // any later version. | |
10 | ||
11 | // This library is distributed in the hope that it will be useful, | |
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | // GNU General Public License for more details. | |
15 | ||
16 | // You should have received a copy of the GNU General Public License along | |
17 | // with this library; see the file COPYING3. If not see | |
18 | // <http://www.gnu.org/licenses/>. | |
19 | ||
20 | #include <utility> | |
21 | #include <map> | |
22 | #include <testsuite_hooks.h> | |
23 | ||
b95170d3 VV |
24 | struct Val |
25 | { | |
26 | bool moved_from_ctor = false; | |
27 | bool moved_from_assign = false; | |
28 | int val; | |
29 | Val(int val = 0) : val(val) {} | |
30 | Val(const Val& other) : val(other.val) | |
31 | { | |
32 | } | |
33 | Val(Val&& other) : val(other.val) | |
34 | { | |
35 | other.moved_from_ctor = true; | |
36 | } | |
37 | Val& operator=(Val&& other) | |
38 | { | |
39 | val = other.val; | |
40 | other.moved_from_assign = true; | |
6ec3c9c8 | 41 | return *this; |
b95170d3 VV |
42 | } |
43 | Val& operator=(const Val& other) | |
44 | { | |
45 | val = other.val; | |
6ec3c9c8 | 46 | return *this; |
b95170d3 VV |
47 | } |
48 | }; | |
49 | ||
50 | bool operator<(const Val& a, const Val& b) | |
51 | { | |
52 | return a.val < b.val; | |
53 | } | |
54 | ||
55 | void test01() | |
56 | { | |
57 | typedef std::map<int, Val> Map; | |
58 | Map m; | |
59 | auto res1 = m.insert_or_assign(0, Val(5)); | |
60 | VERIFY(res1.second); | |
61 | VERIFY(res1.first != m.end()); | |
62 | VERIFY(m[0].val == 5); | |
63 | Val v1{6}; | |
64 | VERIFY(m.size() == 1); | |
65 | auto res2 = m.insert_or_assign(0, std::move(v1)); | |
66 | VERIFY(!res2.second); | |
67 | VERIFY(res2.first == res1.first); | |
68 | VERIFY(m[0].val == 6); | |
69 | VERIFY(!v1.moved_from_ctor); | |
70 | VERIFY(v1.moved_from_assign); | |
71 | VERIFY(m.size() == 1); | |
72 | v1.moved_from_assign = false; | |
73 | auto res3 = m.insert_or_assign(1, std::move(v1)); | |
74 | VERIFY(res3.first != res1.first && res3.first != m.end()); | |
75 | VERIFY(res3.second); | |
76 | VERIFY(m[0].val == 6); | |
77 | VERIFY(m[1].val == 6); | |
78 | VERIFY(v1.moved_from_ctor); | |
79 | VERIFY(!v1.moved_from_assign); | |
80 | VERIFY(m.size() == 2); | |
81 | } | |
82 | ||
83 | void test02() | |
84 | { | |
85 | typedef std::map<int, Val> Map; | |
86 | Map m; | |
87 | auto res1 = m.insert_or_assign(m.begin(), 0, Val(5)); | |
88 | VERIFY(res1 != m.end()); | |
89 | VERIFY(m[0].val == 5); | |
90 | Val v1{6}; | |
91 | VERIFY(m.size() == 1); | |
92 | auto res2 = m.insert_or_assign(m.begin(), 0, std::move(v1)); | |
93 | VERIFY(res2 == res1); | |
94 | VERIFY(m[0].val == 6); | |
95 | VERIFY(!v1.moved_from_ctor); | |
96 | VERIFY(v1.moved_from_assign); | |
97 | VERIFY(m.size() == 1); | |
98 | v1.moved_from_assign = false; | |
99 | auto res3 = m.insert_or_assign(m.begin(), 1, std::move(v1)); | |
100 | VERIFY(res3 != res1 && res3 != m.end()); | |
101 | VERIFY(m[0].val == 6); | |
102 | VERIFY(m[1].val == 6); | |
103 | VERIFY(v1.moved_from_ctor); | |
104 | VERIFY(!v1.moved_from_assign); | |
105 | VERIFY(m.size() == 2); | |
106 | } | |
107 | ||
108 | void test03() | |
109 | { | |
110 | typedef std::map<Val, Val> Map; | |
111 | Map m; | |
112 | auto res1 = m.insert_or_assign(0, Val(5)); | |
113 | VERIFY(res1.second); | |
114 | VERIFY(res1.first != m.end()); | |
115 | VERIFY(m[0].val == 5); | |
116 | Val k1{0}; | |
117 | Val v1{6}; | |
118 | VERIFY(m.size() == 1); | |
119 | auto res2 = m.insert_or_assign(std::move(k1), std::move(v1)); | |
120 | VERIFY(!res2.second); | |
121 | VERIFY(res2.first == res1.first); | |
122 | VERIFY(m[0].val == 6); | |
123 | VERIFY(!k1.moved_from_ctor); | |
124 | VERIFY(!k1.moved_from_assign); | |
125 | VERIFY(!v1.moved_from_ctor); | |
126 | VERIFY(v1.moved_from_assign); | |
127 | VERIFY(m.size() == 1); | |
128 | Val k2{1}; | |
129 | v1.moved_from_assign = false; | |
130 | auto res3 = m.insert_or_assign(std::move(k2), std::move(v1)); | |
131 | VERIFY(res3.first != res1.first && res3.first != m.end()); | |
132 | VERIFY(res3.second); | |
133 | VERIFY(m[0].val == 6); | |
134 | VERIFY(m[1].val == 6); | |
135 | VERIFY(k2.moved_from_ctor); | |
136 | VERIFY(!k2.moved_from_assign); | |
137 | VERIFY(v1.moved_from_ctor); | |
138 | VERIFY(!v1.moved_from_assign); | |
139 | VERIFY(m.size() == 2); | |
140 | } | |
141 | ||
142 | void test04() | |
143 | { | |
144 | typedef std::map<Val, Val> Map; | |
145 | Map m; | |
146 | auto res1 = m.insert_or_assign(m.begin(), 0, Val(5)); | |
147 | VERIFY(res1 != m.end()); | |
148 | VERIFY(m[0].val == 5); | |
149 | Val k1{0}; | |
150 | Val v1{6}; | |
151 | VERIFY(m.size() == 1); | |
152 | auto res2 = m.insert_or_assign(m.begin(), std::move(k1), std::move(v1)); | |
153 | VERIFY(res2 == res1); | |
154 | VERIFY(m[0].val == 6); | |
155 | VERIFY(!k1.moved_from_ctor); | |
156 | VERIFY(!k1.moved_from_assign); | |
157 | VERIFY(!v1.moved_from_ctor); | |
158 | VERIFY(v1.moved_from_assign); | |
159 | VERIFY(m.size() == 1); | |
160 | Val k2{1}; | |
161 | v1.moved_from_assign = false; | |
162 | auto res3 = m.insert_or_assign(m.begin(), std::move(k2), std::move(v1)); | |
163 | VERIFY(res3 != res1 && res3 != m.end()); | |
164 | VERIFY(m[0].val == 6); | |
165 | VERIFY(m[1].val == 6); | |
166 | VERIFY(k2.moved_from_ctor); | |
167 | VERIFY(!k2.moved_from_assign); | |
168 | VERIFY(v1.moved_from_ctor); | |
169 | VERIFY(!v1.moved_from_assign); | |
170 | VERIFY(m.size() == 2); | |
171 | } | |
172 | ||
173 | void test05() | |
174 | { | |
175 | typedef std::map<int, Val> Map; | |
176 | Map m; | |
177 | auto res1 = m.insert_or_assign(0, Val(5)); | |
178 | VERIFY(res1.second); | |
179 | VERIFY(res1.first != m.end()); | |
180 | VERIFY(m[0].val == 5); | |
181 | Val v1{6}; | |
182 | VERIFY(m.size() == 1); | |
183 | auto res2 = m.insert_or_assign(0, v1); | |
184 | VERIFY(!res2.second); | |
185 | VERIFY(res2.first == res1.first); | |
186 | VERIFY(m[0].val == 6); | |
187 | VERIFY(!v1.moved_from_ctor); | |
188 | VERIFY(!v1.moved_from_assign); | |
189 | VERIFY(m.size() == 1); | |
190 | auto res3 = m.insert_or_assign(1, v1); | |
191 | VERIFY(res3.first != res1.first && res3.first != m.end()); | |
192 | VERIFY(res3.second); | |
193 | VERIFY(m[0].val == 6); | |
194 | VERIFY(m[1].val == 6); | |
195 | VERIFY(!v1.moved_from_ctor); | |
196 | VERIFY(!v1.moved_from_assign); | |
197 | VERIFY(m.size() == 2); | |
198 | } | |
199 | ||
200 | void test06() | |
201 | { | |
202 | typedef std::map<int, Val> Map; | |
203 | Map m; | |
204 | auto res1 = m.insert_or_assign(m.begin(), 0, Val(5)); | |
205 | VERIFY(res1 != m.end()); | |
206 | VERIFY(m[0].val == 5); | |
207 | Val v1{6}; | |
208 | VERIFY(m.size() == 1); | |
209 | auto res2 = m.insert_or_assign(m.begin(), 0, v1); | |
210 | VERIFY(res2 == res1); | |
211 | VERIFY(m[0].val == 6); | |
212 | VERIFY(!v1.moved_from_ctor); | |
213 | VERIFY(!v1.moved_from_assign); | |
214 | VERIFY(m.size() == 1); | |
215 | auto res3 = m.insert_or_assign(m.begin(), 1, v1); | |
216 | VERIFY(res3 != res1 && res3 != m.end()); | |
217 | VERIFY(m[0].val == 6); | |
218 | VERIFY(m[1].val == 6); | |
219 | VERIFY(!v1.moved_from_ctor); | |
220 | VERIFY(!v1.moved_from_assign); | |
221 | VERIFY(m.size() == 2); | |
222 | } | |
223 | ||
224 | void test07() | |
225 | { | |
226 | typedef std::map<Val, Val> Map; | |
227 | Map m; | |
228 | auto res1 = m.insert_or_assign(0, Val(5)); | |
229 | VERIFY(res1.second); | |
230 | VERIFY(res1.first != m.end()); | |
231 | VERIFY(m[0].val == 5); | |
232 | Val k1{0}; | |
233 | Val v1{6}; | |
234 | VERIFY(m.size() == 1); | |
235 | auto res2 = m.insert_or_assign(k1, v1); | |
236 | VERIFY(!res2.second); | |
237 | VERIFY(res2.first == res1.first); | |
238 | VERIFY(m[0].val == 6); | |
239 | VERIFY(!k1.moved_from_ctor); | |
240 | VERIFY(!k1.moved_from_assign); | |
241 | VERIFY(!v1.moved_from_ctor); | |
242 | VERIFY(!v1.moved_from_assign); | |
243 | VERIFY(m.size() == 1); | |
244 | Val k2{1}; | |
245 | auto res3 = m.insert_or_assign(k2, v1); | |
246 | VERIFY(res3.first != res1.first && res3.first != m.end()); | |
247 | VERIFY(res3.second); | |
248 | VERIFY(m[0].val == 6); | |
249 | VERIFY(m[1].val == 6); | |
250 | VERIFY(!k2.moved_from_ctor); | |
251 | VERIFY(!k2.moved_from_assign); | |
252 | VERIFY(!v1.moved_from_ctor); | |
253 | VERIFY(!v1.moved_from_assign); | |
254 | VERIFY(m.size() == 2); | |
255 | } | |
256 | ||
257 | void test08() | |
258 | { | |
259 | typedef std::map<Val, Val> Map; | |
260 | Map m; | |
261 | auto res1 = m.insert_or_assign(m.begin(), 0, Val(5)); | |
262 | VERIFY(res1 != m.end()); | |
263 | VERIFY(m[0].val == 5); | |
264 | Val k1{0}; | |
265 | Val v1{6}; | |
266 | VERIFY(m.size() == 1); | |
267 | auto res2 = m.insert_or_assign(m.begin(), k1, v1); | |
268 | VERIFY(res2 == res1); | |
269 | VERIFY(m[0].val == 6); | |
270 | VERIFY(!k1.moved_from_ctor); | |
271 | VERIFY(!k1.moved_from_assign); | |
272 | VERIFY(!v1.moved_from_ctor); | |
273 | VERIFY(!v1.moved_from_assign); | |
274 | VERIFY(m.size() == 1); | |
275 | Val k2{1}; | |
276 | auto res3 = m.insert_or_assign(m.begin(), k2, v1); | |
277 | VERIFY(res3 != res1 && res3 != m.end()); | |
278 | VERIFY(m[0].val == 6); | |
279 | VERIFY(m[1].val == 6); | |
280 | VERIFY(!k2.moved_from_ctor); | |
281 | VERIFY(!k2.moved_from_assign); | |
282 | VERIFY(!v1.moved_from_ctor); | |
283 | VERIFY(!v1.moved_from_assign); | |
284 | VERIFY(m.size() == 2); | |
285 | } | |
286 | ||
287 | int main() | |
288 | { | |
289 | test01(); | |
290 | test02(); | |
291 | test03(); | |
292 | test04(); | |
293 | test05(); | |
294 | test06(); | |
295 | test07(); | |
296 | test08(); | |
297 | return 0; | |
298 | } |