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 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: c++03, c++11, c++14
16 // pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj); // C++17
18 // pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj); // C++17
20 // iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); // C++17
22 // iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); // C++17
29 #include "test_macros.h"
33 Moveable(const Moveable
&);
34 Moveable
& operator=(const Moveable
&);
39 Moveable() : int_(0), double_(0) {}
40 Moveable(int i
, double d
) : int_(i
), double_(d
) {}
41 Moveable(Moveable
&& x
)
42 : int_(x
.int_
), double_(x
.double_
)
43 {x
.int_
= -1; x
.double_
= -1;}
44 Moveable
& operator=(Moveable
&& x
)
45 {int_
= x
.int_
; x
.int_
= -1;
46 double_
= x
.double_
; x
.double_
= -1;
50 bool operator==(const Moveable
& x
) const
51 {return int_
== x
.int_
&& double_
== x
.double_
;}
52 bool operator<(const Moveable
& x
) const
53 {return int_
< x
.int_
|| (int_
== x
.int_
&& double_
< x
.double_
);}
55 int get() const {return int_
;}
56 bool moved() const {return int_
== -1;}
62 { // pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj);
63 typedef std::map
<int, Moveable
> M
;
64 typedef std::pair
<M::iterator
, bool> R
;
67 for ( int i
= 0; i
< 20; i
+= 2 )
68 m
.emplace ( i
, Moveable(i
, (double) i
));
69 assert(m
.size() == 10);
71 for (int i
=0; i
< 20; i
+= 2)
73 Moveable
mv(i
+1, i
+1);
74 r
= m
.insert_or_assign(i
, std::move(mv
));
75 assert(m
.size() == 10);
76 assert(!r
.second
); // was not inserted
77 assert(mv
.moved()); // was moved from
78 assert(r
.first
->first
== i
); // key
79 assert(r
.first
->second
.get() == i
+1); // value
83 r
= m
.insert_or_assign(-1, std::move(mv1
));
84 assert(m
.size() == 11);
85 assert(r
.second
); // was inserted
86 assert(mv1
.moved()); // was moved from
87 assert(r
.first
->first
== -1); // key
88 assert(r
.first
->second
.get() == 5); // value
91 r
= m
.insert_or_assign(3, std::move(mv2
));
92 assert(m
.size() == 12);
93 assert(r
.second
); // was inserted
94 assert(mv2
.moved()); // was moved from
95 assert(r
.first
->first
== 3); // key
96 assert(r
.first
->second
.get() == 9); // value
98 Moveable
mv3(-1, 5.0);
99 r
= m
.insert_or_assign(117, std::move(mv3
));
100 assert(m
.size() == 13);
101 assert(r
.second
); // was inserted
102 assert(mv3
.moved()); // was moved from
103 assert(r
.first
->first
== 117); // key
104 assert(r
.first
->second
.get() == -1); // value
106 { // pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj);
107 typedef std::map
<Moveable
, Moveable
> M
;
108 typedef std::pair
<M::iterator
, bool> R
;
111 for ( int i
= 0; i
< 20; i
+= 2 )
112 m
.emplace ( Moveable(i
, (double) i
), Moveable(i
+1, (double) i
+1));
113 assert(m
.size() == 10);
115 Moveable
mvkey1(2, 2.0);
116 Moveable
mv1(4, 4.0);
117 r
= m
.insert_or_assign(std::move(mvkey1
), std::move(mv1
));
118 assert(m
.size() == 10);
119 assert(!r
.second
); // was not inserted
120 assert(!mvkey1
.moved()); // was not moved from
121 assert(mv1
.moved()); // was moved from
122 assert(r
.first
->first
== mvkey1
); // key
123 assert(r
.first
->second
.get() == 4); // value
125 Moveable
mvkey2(3, 3.0);
126 Moveable
mv2(5, 5.0);
127 r
= m
.try_emplace(std::move(mvkey2
), std::move(mv2
));
128 assert(m
.size() == 11);
129 assert(r
.second
); // was inserted
130 assert(mv2
.moved()); // was moved from
131 assert(mvkey2
.moved()); // was moved from
132 assert(r
.first
->first
.get() == 3); // key
133 assert(r
.first
->second
.get() == 5); // value
135 { // iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);
136 typedef std::map
<int, Moveable
> M
;
139 for ( int i
= 0; i
< 20; i
+= 2 )
140 m
.emplace ( i
, Moveable(i
, (double) i
));
141 assert(m
.size() == 10);
142 M::const_iterator it
= m
.find(2);
144 Moveable
mv1(3, 3.0);
145 r
= m
.insert_or_assign(it
, 2, std::move(mv1
));
146 assert(m
.size() == 10);
147 assert(mv1
.moved()); // was moved from
148 assert(r
->first
== 2); // key
149 assert(r
->second
.get() == 3); // value
151 Moveable
mv2(5, 5.0);
152 r
= m
.insert_or_assign(it
, 3, std::move(mv2
));
153 assert(m
.size() == 11);
154 assert(mv2
.moved()); // was moved from
155 assert(r
->first
== 3); // key
156 assert(r
->second
.get() == 5); // value
158 // wrong hint: begin()
159 Moveable
mv3(7, 7.0);
160 r
= m
.insert_or_assign(m
.begin(), 4, std::move(mv3
));
161 assert(m
.size() == 11);
162 assert(mv3
.moved()); // was moved from
163 assert(r
->first
== 4); // key
164 assert(r
->second
.get() == 7); // value
166 Moveable
mv4(9, 9.0);
167 r
= m
.insert_or_assign(m
.begin(), 5, std::move(mv4
));
168 assert(m
.size() == 12);
169 assert(mv4
.moved()); // was moved from
170 assert(r
->first
== 5); // key
171 assert(r
->second
.get() == 9); // value
174 Moveable
mv5(11, 11.0);
175 r
= m
.insert_or_assign(m
.end(), 6, std::move(mv5
));
176 assert(m
.size() == 12);
177 assert(mv5
.moved()); // was moved from
178 assert(r
->first
== 6); // key
179 assert(r
->second
.get() == 11); // value
181 Moveable
mv6(13, 13.0);
182 r
= m
.insert_or_assign(m
.end(), 7, std::move(mv6
));
183 assert(m
.size() == 13);
184 assert(mv6
.moved()); // was moved from
185 assert(r
->first
== 7); // key
186 assert(r
->second
.get() == 13); // value
188 // wrong hint: third element
189 Moveable
mv7(15, 15.0);
190 r
= m
.insert_or_assign(std::next(m
.begin(), 2), 8, std::move(mv7
));
191 assert(m
.size() == 13);
192 assert(mv7
.moved()); // was moved from
193 assert(r
->first
== 8); // key
194 assert(r
->second
.get() == 15); // value
196 Moveable
mv8(17, 17.0);
197 r
= m
.insert_or_assign(std::next(m
.begin(), 2), 9, std::move(mv8
));
198 assert(m
.size() == 14);
199 assert(mv8
.moved()); // was moved from
200 assert(r
->first
== 9); // key
201 assert(r
->second
.get() == 17); // value
203 { // iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);
204 typedef std::map
<Moveable
, Moveable
> M
;
207 for ( int i
= 0; i
< 20; i
+= 2 )
208 m
.emplace ( Moveable(i
, (double) i
), Moveable(i
+1, (double) i
+1));
209 assert(m
.size() == 10);
210 M::const_iterator it
= std::next(m
.cbegin());
212 Moveable
mvkey1(2, 2.0);
213 Moveable
mv1(4, 4.0);
214 r
= m
.insert_or_assign(it
, std::move(mvkey1
), std::move(mv1
));
215 assert(m
.size() == 10);
216 assert(mv1
.moved()); // was moved from
217 assert(!mvkey1
.moved()); // was not moved from
218 assert(r
->first
== mvkey1
); // key
219 assert(r
->second
.get() == 4); // value
221 Moveable
mvkey2(3, 3.0);
222 Moveable
mv2(5, 5.0);
223 r
= m
.insert_or_assign(it
, std::move(mvkey2
), std::move(mv2
));
224 assert(m
.size() == 11);
225 assert(mv2
.moved()); // was moved from
226 assert(mvkey2
.moved()); // was moved from
227 assert(r
->first
.get() == 3); // key
228 assert(r
->second
.get() == 5); // value
230 // wrong hint: begin()
231 Moveable
mvkey3(6, 6.0);
232 Moveable
mv3(8, 8.0);
233 r
= m
.insert_or_assign(m
.begin(), std::move(mvkey3
), std::move(mv3
));
234 assert(m
.size() == 11);
235 assert(mv3
.moved()); // was moved from
236 assert(!mvkey3
.moved()); // was not moved from
237 assert(r
->first
== mvkey3
); // key
238 assert(r
->second
.get() == 8); // value
240 Moveable
mvkey4(7, 7.0);
241 Moveable
mv4(9, 9.0);
242 r
= m
.insert_or_assign(m
.begin(), std::move(mvkey4
), std::move(mv4
));
243 assert(m
.size() == 12);
244 assert(mv4
.moved()); // was moved from
245 assert(mvkey4
.moved()); // was moved from
246 assert(r
->first
.get() == 7); // key
247 assert(r
->second
.get() == 9); // value
250 Moveable
mvkey5(8, 8.0);
251 Moveable
mv5(10, 10.0);
252 r
= m
.insert_or_assign(m
.end(), std::move(mvkey5
), std::move(mv5
));
253 assert(m
.size() == 12);
254 assert(mv5
.moved()); // was moved from
255 assert(!mvkey5
.moved()); // was not moved from
256 assert(r
->first
== mvkey5
); // key
257 assert(r
->second
.get() == 10); // value
259 Moveable
mvkey6(9, 9.0);
260 Moveable
mv6(11, 11.0);
261 r
= m
.insert_or_assign(m
.end(), std::move(mvkey6
), std::move(mv6
));
262 assert(m
.size() == 13);
263 assert(mv6
.moved()); // was moved from
264 assert(mvkey6
.moved()); // was moved from
265 assert(r
->first
.get() == 9); // key
266 assert(r
->second
.get() == 11); // value
268 // wrong hint: third element
269 Moveable
mvkey7(10, 10.0);
270 Moveable
mv7(12, 12.0);
271 r
= m
.insert_or_assign(std::next(m
.begin(), 2), std::move(mvkey7
), std::move(mv7
));
272 assert(m
.size() == 13);
273 assert(mv7
.moved()); // was moved from
274 assert(!mvkey7
.moved()); // was not moved from
275 assert(r
->first
== mvkey7
); // key
276 assert(r
->second
.get() == 12); // value
278 Moveable
mvkey8(11, 11.0);
279 Moveable
mv8(13, 13.0);
280 r
= m
.insert_or_assign(std::next(m
.begin(), 2), std::move(mvkey8
), std::move(mv8
));
281 assert(m
.size() == 14);
282 assert(mv8
.moved()); // was moved from
283 assert(mvkey8
.moved()); // was moved from
284 assert(r
->first
.get() == 11); // key
285 assert(r
->second
.get() == 13); // value