Revert "[libc] Use best-fit binary trie to make malloc logarithmic" (#117065)
[llvm-project.git] / libcxx / test / std / containers / associative / map / map.modifiers / insert_or_assign.pass.cpp
blobb865888eaf79580d48cacc33d880ff755084efe0
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 //===----------------------------------------------------------------------===//
8 //
9 // UNSUPPORTED: c++03, c++11, c++14
11 // <map>
13 // class map
15 // template <class M>
16 // pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj); // C++17
17 // template <class M>
18 // pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj); // C++17
19 // template <class M>
20 // iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); // C++17
21 // template <class M>
22 // iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); // C++17
24 #include <map>
25 #include <cassert>
26 #include <iterator>
27 #include <tuple>
29 #include "test_macros.h"
31 class Moveable
33 Moveable(const Moveable&);
34 Moveable& operator=(const Moveable&);
36 int int_;
37 double double_;
38 public:
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;
47 return *this;
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;}
60 int main(int, char**)
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;
65 M m;
66 R 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
82 Moveable mv1(5, 5.0);
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
90 Moveable mv2(9, 9.0);
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;
109 M m;
110 R 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;
137 M m;
138 M::iterator r;
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
173 // wrong hint: end()
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;
205 M m;
206 M::iterator r;
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
249 // wrong hint: end()
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
288 return 0;