source: mainline/uspace/lib/cpp/src/internal/test/unordered_map.cpp@ 9ab4026

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 9ab4026 was c7d7368, checked in by Dzejrou <dzejrou@…>, 7 years ago

cpp: added missing umap test file

  • Property mode set to 100644
File size: 10.3 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 <initializer_list>
30#include <internal/test/tests.hpp>
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 auto res10 = map2.erase(map2.find(7));
186 test_eq("erase", map2.find(7), map2.end());
187 test_eq("highest erased", res10, map2.end());
188
189 auto res11 = map2.erase(6);
190 test_eq("erase by key pt1", res11, 1U);
191 auto res12 = map2.erase(6);
192 test_eq("erase by key pt2", res12, 0U);
193
194 auto res13 = map2.insert(std::pair<const int, const char*>{11, "test"});
195 test_eq("insert with constructible argument pt1", res13.second, true);
196 test_eq("insert with constructible argument pt2", res13.first->first, 11);
197 test_eq("insert with constructible argument pt3", res13.first->second, std::string{"test"});
198
199 std::unordered_map<int, int> map3{};
200 map3[1] = 1;
201 auto res15 = map3.count(1);
202 test_eq("count", res15, 1U);
203
204 map2.clear();
205 test_eq("clear", map2.empty(), true);
206 }
207
208 void unordered_map_test::test_multi()
209 {
210 auto check_keys = {1, 2, 3, 4, 5, 6, 7};
211 auto check_counts = {1U, 1U, 2U, 1U, 1U, 3U, 1U};
212 auto src = {
213 std::pair<const int, int>{3, 3},
214 std::pair<const int, int>{6, 6},
215 std::pair<const int, int>{1, 1},
216 std::pair<const int, int>{5, 5},
217 std::pair<const int, int>{6, 6},
218 std::pair<const int, int>{3, 3},
219 std::pair<const int, int>{2, 2},
220 std::pair<const int, int>{7, 7},
221 std::pair<const int, int>{6, 6},
222 std::pair<const int, int>{4, 4}
223 };
224
225 std::unordered_multimap<int, int> mmap{src};
226 test_contains_multi(
227 "multi construction",
228 check_keys.begin(), check_keys.end(),
229 check_counts.begin(), mmap
230 );
231
232 auto res1 = mmap.count(6);
233 test_eq("multi count", res1, 3U);
234
235 auto res2 = mmap.emplace(7, 2);
236 test_eq("multi duplicit emplace pt1", res2->first, 7);
237 test_eq("multi duplicit emplace pt2", res2->second, 2);
238 test_eq("multi duplicit emplace pt3", mmap.count(7), 2U);
239
240 auto res3 = mmap.emplace(8, 5);
241 test_eq("multi unique emplace pt1", res3->first, 8);
242 test_eq("multi unique emplace pt2", res3->second, 5);
243 test_eq("multi unique emplace pt3", mmap.count(8), 1U);
244
245 auto res4 = mmap.insert(std::pair<const int, int>{8, 6});
246 test_eq("multi duplicit insert pt1", res4->first, 8);
247 test_eq("multi duplicit insert pt2", res4->second, 6);
248 test_eq("multi duplicit insert pt3", mmap.count(8), 2U);
249
250 auto res5 = mmap.insert(std::pair<const int, int>{9, 8});
251 test_eq("multi unique insert pt1", res5->first, 9);
252 test_eq("multi unique insert pt2", res5->second, 8);
253 test_eq("multi unique insert pt3", mmap.count(9), 1U);
254
255 auto res6 = mmap.erase(8);
256 test_eq("multi erase by key pt1", res6, 2U);
257 test_eq("multi erase by key pt2", mmap.count(8), 0U);
258
259 // To check that the bucket still works.
260 mmap.insert(std::pair<const int, int>{8, 8});
261 test_eq("multi erase keeps bucket intact", (mmap.find(8) != mmap.end()), true);
262
263 auto res7 = mmap.erase(mmap.find(7));
264 test_eq("multi erase by iterator pt1", res7->first, 7);
265 test_eq("multi erase by iterator pt2", mmap.count(7), 1U);
266 }
267}
Note: See TracBrowser for help on using the repository browser.