source: mainline/uspace/lib/cpp/src/__bits/test/unordered_map.cpp

Last change on this file was 32d53a7, checked in by Dzejrou <dzejrou@…>, 7 years ago

cpp: removed the highest_deleted test, which belonged to std::map and was irrelevant in std::unordered_map

  • Property mode set to 100644
File size: 10.2 KB
Line 
1/*
2 * Copyright (c) 2018 Jaroslav Jindrak
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <__bits/test/tests.hpp>
30#include <initializer_list>
31#include <unordered_map>
32#include <string>
33#include <sstream>
34#include <utility>
35
36namespace std::test
37{
38 bool unordered_map_test::run(bool report)
39 {
40 report_ = report;
41 start();
42
43 test_constructors_and_assignment();
44 test_histogram();
45 test_emplace_insert();
46 test_multi();
47
48 return end();
49 }
50
51 const char* unordered_map_test::name()
52 {
53 return "unordered_map";
54 }
55
56 void unordered_map_test::test_constructors_and_assignment()
57 {
58 auto check1 = {1, 2, 3, 4, 5, 6, 7};
59 auto src1 = {
60 std::pair<const int, int>{3, 3},
61 std::pair<const int, int>{1, 1},
62 std::pair<const int, int>{5, 5},
63 std::pair<const int, int>{2, 2},
64 std::pair<const int, int>{7, 7},
65 std::pair<const int, int>{6, 6},
66 std::pair<const int, int>{4, 4}
67 };
68
69 std::unordered_map<int, int> m1{src1};
70 test_contains(
71 "initializer list initialization",
72 check1.begin(), check1.end(), m1
73 );
74 test_eq("size", m1.size(), 7U);
75
76 std::unordered_map<int, int> m2{src1.begin(), src1.end()};
77 test_contains(
78 "iterator range initialization",
79 check1.begin(), check1.end(), m2
80 );
81
82 std::unordered_map<int, int> m3{m1};
83 test_contains(
84 "copy initialization",
85 check1.begin(), check1.end(), m3
86 );
87
88 std::unordered_map<int, int> m4{std::move(m1)};
89 test_contains(
90 "move initialization",
91 check1.begin(), check1.end(), m4
92 );
93 test_eq("move initialization - origin empty", m1.size(), 0U);
94 test_eq("empty", m1.empty(), true);
95
96 m1 = m4;
97 test_contains(
98 "copy assignment",
99 check1.begin(), check1.end(), m1
100 );
101
102 m4 = std::move(m1);
103 test_contains(
104 "move assignment",
105 check1.begin(), check1.end(), m4
106 );
107 test_eq("move assignment - origin empty", m1.size(), 0U);
108
109 m1 = src1;
110 test_contains(
111 "initializer list assignment",
112 check1.begin(), check1.end(), m1
113 );
114 }
115
116 void unordered_map_test::test_histogram()
117 {
118 std::string str{"a b a a c d b e a b b e d c a e"};
119 std::unordered_map<std::string, std::size_t> unordered_map{};
120 std::istringstream iss{str};
121 std::string word{};
122
123 while (iss >> word)
124 ++unordered_map[word];
125
126 test_eq("histogram pt1", unordered_map["a"], 5U);
127 test_eq("histogram pt2", unordered_map["b"], 4U);
128 test_eq("histogram pt3", unordered_map["c"], 2U);
129 test_eq("histogram pt4", unordered_map["d"], 2U);
130 test_eq("histogram pt5", unordered_map["e"], 3U);
131 test_eq("histogram pt6", unordered_map["f"], 0U);
132 test_eq("at", unordered_map.at("a"), 5U);
133 }
134
135 void unordered_map_test::test_emplace_insert()
136 {
137 std::unordered_map<int, int> map1{};
138
139 auto res1 = map1.emplace(1, 2);
140 test_eq("first emplace succession", res1.second, true);
141 test_eq("first emplace equivalence pt1", res1.first->first, 1);
142 test_eq("first emplace equivalence pt2", res1.first->second, 2);
143
144 auto res2 = map1.emplace(1, 3);
145 test_eq("second emplace failure", res2.second, false);
146 test_eq("second emplace equivalence pt1", res2.first->first, 1);
147 test_eq("second emplace equivalence pt2", res2.first->second, 2);
148
149 auto res3 = map1.emplace_hint(map1.begin(), 2, 4);
150 test_eq("first emplace_hint succession", (res3 != map1.end()), true);
151 test_eq("first emplace_hint equivalence pt1", res3->first, 2);
152 test_eq("first emplace_hint equivalence pt2", res3->second, 4);
153
154 auto res4 = map1.emplace_hint(map1.begin(), 2, 5);
155 test_eq("second emplace_hint failure", (res4 != map1.end()), true);
156 test_eq("second emplace_hint equivalence pt1", res4->first, 2);
157 test_eq("second emplace_hint equivalence pt2", res4->second, 4);
158
159 std::unordered_map<int, std::string> map2{};
160 auto res5 = map2.insert(std::pair<const int, const char*>{5, "A"});
161 test_eq("conversion insert succession", res5.second, true);
162 test_eq("conversion insert equivalence pt1", res5.first->first, 5);
163 test_eq("conversion insert equivalence pt2", res5.first->second, std::string{"A"});
164
165 auto res6 = map2.insert(std::pair<const int, std::string>{6, "B"});
166 test_eq("first insert succession", res6.second, true);
167 test_eq("first insert equivalence pt1", res6.first->first, 6);
168 test_eq("first insert equivalence pt2", res6.first->second, std::string{"B"});
169
170 auto res7 = map2.insert(std::pair<const int, std::string>{6, "C"});
171 test_eq("second insert failure", res7.second, false);
172 test_eq("second insert equivalence pt1", res7.first->first, 6);
173 test_eq("second insert equivalence pt2", res7.first->second, std::string{"B"});
174
175 auto res8 = map2.insert_or_assign(6, std::string{"D"});
176 test_eq("insert_or_*assign* result", res8.second, false);
177 test_eq("insert_or_*assign* equivalence pt1", res8.first->first, 6);
178 test_eq("insert_or_*assign* equivalence pt2", res8.first->second, std::string{"D"});
179
180 auto res9 = map2.insert_or_assign(7, std::string{"E"});
181 test_eq("*insert*_or_assign result", res9.second, true);
182 test_eq("*insert*_or_assign equivalence pt1", res9.first->first, 7);
183 test_eq("*insert*_or_assign equivalence pt2", res9.first->second, std::string{"E"});
184
185 map2.erase(map2.find(7));
186 test_eq("erase", map2.find(7), map2.end());
187
188 auto res10 = map2.erase(6);
189 test_eq("erase by key pt1", res10, 1U);
190 auto res11 = map2.erase(6);
191 test_eq("erase by key pt2", res11, 0U);
192
193 auto res12 = map2.insert(std::pair<const int, const char*>{11, "test"});
194 test_eq("insert with constructible argument pt1", res12.second, true);
195 test_eq("insert with constructible argument pt2", res12.first->first, 11);
196 test_eq("insert with constructible argument pt3", res12.first->second, std::string{"test"});
197
198 std::unordered_map<int, int> map3{};
199 map3[1] = 1;
200 auto res13 = map3.count(1);
201 test_eq("count", res13, 1U);
202
203 map2.clear();
204 test_eq("clear", map2.empty(), true);
205 }
206
207 void unordered_map_test::test_multi()
208 {
209 auto check_keys = {1, 2, 3, 4, 5, 6, 7};
210 auto check_counts = {1U, 1U, 2U, 1U, 1U, 3U, 1U};
211 auto src = {
212 std::pair<const int, int>{3, 3},
213 std::pair<const int, int>{6, 6},
214 std::pair<const int, int>{1, 1},
215 std::pair<const int, int>{5, 5},
216 std::pair<const int, int>{6, 6},
217 std::pair<const int, int>{3, 3},
218 std::pair<const int, int>{2, 2},
219 std::pair<const int, int>{7, 7},
220 std::pair<const int, int>{6, 6},
221 std::pair<const int, int>{4, 4}
222 };
223
224 std::unordered_multimap<int, int> mmap{src};
225 test_contains_multi(
226 "multi construction",
227 check_keys.begin(), check_keys.end(),
228 check_counts.begin(), mmap
229 );
230
231 auto res1 = mmap.count(6);
232 test_eq("multi count", res1, 3U);
233
234 auto res2 = mmap.emplace(7, 2);
235 test_eq("multi duplicit emplace pt1", res2->first, 7);
236 test_eq("multi duplicit emplace pt2", res2->second, 2);
237 test_eq("multi duplicit emplace pt3", mmap.count(7), 2U);
238
239 auto res3 = mmap.emplace(8, 5);
240 test_eq("multi unique emplace pt1", res3->first, 8);
241 test_eq("multi unique emplace pt2", res3->second, 5);
242 test_eq("multi unique emplace pt3", mmap.count(8), 1U);
243
244 auto res4 = mmap.insert(std::pair<const int, int>{8, 6});
245 test_eq("multi duplicit insert pt1", res4->first, 8);
246 test_eq("multi duplicit insert pt2", res4->second, 6);
247 test_eq("multi duplicit insert pt3", mmap.count(8), 2U);
248
249 auto res5 = mmap.insert(std::pair<const int, int>{9, 8});
250 test_eq("multi unique insert pt1", res5->first, 9);
251 test_eq("multi unique insert pt2", res5->second, 8);
252 test_eq("multi unique insert pt3", mmap.count(9), 1U);
253
254 auto res6 = mmap.erase(8);
255 test_eq("multi erase by key pt1", res6, 2U);
256 test_eq("multi erase by key pt2", mmap.count(8), 0U);
257
258 // To check that the bucket still works.
259 mmap.insert(std::pair<const int, int>{8, 8});
260 test_eq("multi erase keeps bucket intact", (mmap.find(8) != mmap.end()), true);
261
262 auto res7 = mmap.erase(mmap.find(7));
263 test_eq("multi erase by iterator pt1", res7->first, 7);
264 test_eq("multi erase by iterator pt2", mmap.count(7), 1U);
265 }
266}
Note: See TracBrowser for help on using the repository browser.