@@ -74,6 +74,272 @@ GTEST_TEST(hashmap, indexed_operator_trivial_different_type)
7474 };
7575 };
7676
77+ // Non constant
78+ {
79+ const auto result = test ();
80+ hud_assert_true (std::get<0 >(result));
81+ hud_assert_true (std::get<1 >(result));
82+ hud_assert_true (std::get<2 >(result));
83+ }
84+ // Constant
85+ {
86+ constexpr auto result = test ();
87+ hud_assert_true (std::get<0 >(result));
88+ hud_assert_true (std::get<1 >(result));
89+ hud_assert_true (std::get<2 >(result));
90+ }
91+ }
92+
93+ GTEST_TEST (hashmap, indexed_operator_non_trivial_copy_same_type)
94+ {
95+ const auto test = []()
96+ {
97+ using key_type = hud_test::non_bitwise_type;
98+ using value_type = hud_test::non_bitwise_type;
99+ hud::hashmap<key_type, value_type> map;
100+
101+ const key_type key = 123 ;
102+
103+ // Should add default value 0
104+ map[key];
105+ auto &value = map.find (key)->value ();
106+ bool ok_default = value.id () == 0 ;
107+ ok_default &= value.constructor_count () == 0 ;
108+ ok_default &= value.copy_constructor_count () == 0 ;
109+ ok_default &= value.move_constructor_count () == 0 ;
110+ ok_default &= value.copy_assign_count () == 0 ;
111+ ok_default &= value.move_assign_count () == 0 ;
112+
113+ // Should add key, 0
114+ const value_type to_copy = value_type {1 };
115+ map[key] = to_copy;
116+ auto &value_ok = map.find (key)->value ();
117+ bool ok = value_ok.id () == 1 ;
118+ ok &= value_ok.constructor_count () == 1 ;
119+ ok &= value_ok.copy_constructor_count () == 0 ;
120+ ok &= value_ok.move_constructor_count () == 0 ;
121+ ok &= value_ok.copy_assign_count () == 1 ;
122+ ok &= value_ok.move_assign_count () == 0 ;
123+
124+ // Should replace value of key to 2
125+ const value_type to_copy_2 = value_type {2 };
126+ map[key] = to_copy_2;
127+ auto &value_replace = map.find (key)->value ();
128+ bool ok_replace = value_replace.id () == 2 ;
129+ ok_replace &= value_replace.constructor_count () == 1 ;
130+ ok_replace &= value_replace.copy_constructor_count () == 0 ;
131+ ok_replace &= value_replace.move_constructor_count () == 0 ;
132+ ok_replace &= value_replace.copy_assign_count () == 1 ;
133+ ok_replace &= value_replace.move_assign_count () == 0 ;
134+
135+ return std::tuple {
136+ ok_default,
137+ ok,
138+ ok_replace
139+ };
140+ };
141+
142+ // Non constant
143+ {
144+ const auto result = test ();
145+ hud_assert_true (std::get<0 >(result));
146+ hud_assert_true (std::get<1 >(result));
147+ hud_assert_true (std::get<2 >(result));
148+ }
149+ // Constant
150+ {
151+ constexpr auto result = test ();
152+ hud_assert_true (std::get<0 >(result));
153+ hud_assert_true (std::get<1 >(result));
154+ hud_assert_true (std::get<2 >(result));
155+ }
156+ }
157+
158+ GTEST_TEST (hashmap, indexed_operator_non_trivial_copy_different_type)
159+ {
160+ const auto test = []()
161+ {
162+ using key_type = hud_test::non_bitwise_type;
163+ using value_type = hud_test::non_bitwise_type;
164+
165+ using other_key_type = hud_test::non_bitwise_type2;
166+ using other_value_type = hud_test::non_bitwise_type2;
167+ static_assert (!hud::is_same_v<key_type, other_key_type>);
168+ static_assert (!hud::is_same_v<value_type, other_value_type>);
169+
170+ hud::hashmap<key_type, value_type> map;
171+ const other_key_type key = other_key_type {123 };
172+
173+ // Should add default value 0
174+ map[key];
175+ auto &value = map.find (key)->value ();
176+ bool ok_default = value.id () == 0 ;
177+ ok_default &= value.constructor_count () == 0 ;
178+ ok_default &= value.copy_constructor_count () == 0 ;
179+ ok_default &= value.move_constructor_count () == 0 ;
180+ ok_default &= value.copy_assign_count () == 0 ;
181+ ok_default &= value.move_assign_count () == 0 ;
182+
183+ // Should add key, 0
184+ const other_value_type to_copy = other_value_type {1 };
185+ map[key] = to_copy;
186+ auto &value_ok = map.find (key)->value ();
187+ bool ok = value_ok.id () == 1 ;
188+ ok &= value_ok.constructor_count () == 1 ;
189+ ok &= value_ok.copy_constructor_count () == 0 ;
190+ ok &= value_ok.move_constructor_count () == 0 ;
191+ ok &= value_ok.copy_assign_count () == 1 ;
192+ ok &= value_ok.move_assign_count () == 0 ;
193+
194+ // Should replace value of key to 2
195+ const other_value_type to_copy_2 = other_value_type {2 };
196+ map[key] = to_copy_2;
197+ auto &value_replace = map.find (key)->value ();
198+ bool ok_replace = value_replace.id () == 2 ;
199+ ok_replace &= value_replace.constructor_count () == 1 ;
200+ ok_replace &= value_replace.copy_constructor_count () == 0 ;
201+ ok_replace &= value_replace.move_constructor_count () == 0 ;
202+ ok_replace &= value_replace.copy_assign_count () == 1 ;
203+ ok_replace &= value_replace.move_assign_count () == 0 ;
204+
205+ return std::tuple {
206+ ok_default,
207+ ok,
208+ ok_replace
209+ };
210+ };
211+
212+ // Non constant
213+ {
214+ const auto result = test ();
215+ hud_assert_true (std::get<0 >(result));
216+ hud_assert_true (std::get<1 >(result));
217+ hud_assert_true (std::get<2 >(result));
218+ }
219+ // Constant
220+ {
221+ constexpr auto result = test ();
222+ hud_assert_true (std::get<0 >(result));
223+ hud_assert_true (std::get<1 >(result));
224+ hud_assert_true (std::get<2 >(result));
225+ }
226+ }
227+
228+ GTEST_TEST (hashmap, indexed_operator_non_trivial_move_same_type)
229+ {
230+ const auto test = []()
231+ {
232+ using key_type = hud_test::non_bitwise_type;
233+ using value_type = hud_test::non_bitwise_type;
234+ hud::hashmap<key_type, value_type> map;
235+
236+ const key_type key = 123 ;
237+
238+ // Should add default value 0
239+ map[key];
240+ auto &value = map.find (key)->value ();
241+ bool ok_default = value.id () == 0 ;
242+ ok_default &= value.constructor_count () == 0 ;
243+ ok_default &= value.copy_constructor_count () == 0 ;
244+ ok_default &= value.move_constructor_count () == 0 ;
245+ ok_default &= value.copy_assign_count () == 0 ;
246+ ok_default &= value.move_assign_count () == 0 ;
247+
248+ // Should add key, 0
249+ map[key] = value_type {1 };
250+ auto &value_ok = map.find (key)->value ();
251+ bool ok = value_ok.id () == 1 ;
252+ ok &= value_ok.constructor_count () == 1 ;
253+ ok &= value_ok.copy_constructor_count () == 0 ;
254+ ok &= value_ok.move_constructor_count () == 0 ;
255+ ok &= value_ok.copy_assign_count () == 0 ;
256+ ok &= value_ok.move_assign_count () == 1 ;
257+
258+ // Should replace value of key to 2
259+ map[key] = value_type {2 };
260+ auto &value_replace = map.find (key)->value ();
261+ bool ok_replace = value_replace.id () == 2 ;
262+ ok_replace &= value_replace.constructor_count () == 1 ;
263+ ok_replace &= value_replace.copy_constructor_count () == 0 ;
264+ ok_replace &= value_replace.move_constructor_count () == 0 ;
265+ ok_replace &= value_replace.copy_assign_count () == 0 ;
266+ ok_replace &= value_replace.move_assign_count () == 1 ;
267+
268+ return std::tuple {
269+ ok_default,
270+ ok,
271+ ok_replace
272+ };
273+ };
274+
275+ // Non constant
276+ {
277+ const auto result = test ();
278+ hud_assert_true (std::get<0 >(result));
279+ hud_assert_true (std::get<1 >(result));
280+ hud_assert_true (std::get<2 >(result));
281+ }
282+ // Constant
283+ {
284+ constexpr auto result = test ();
285+ hud_assert_true (std::get<0 >(result));
286+ hud_assert_true (std::get<1 >(result));
287+ hud_assert_true (std::get<2 >(result));
288+ }
289+ }
290+
291+ GTEST_TEST (hashmap, indexed_operator_non_trivial_move_different_type)
292+ {
293+ const auto test = []()
294+ {
295+ using key_type = hud_test::non_bitwise_type;
296+ using value_type = hud_test::non_bitwise_type;
297+
298+ using other_key_type = hud_test::non_bitwise_type2;
299+ using other_value_type = hud_test::non_bitwise_type2;
300+ static_assert (!hud::is_same_v<key_type, other_key_type>);
301+ static_assert (!hud::is_same_v<value_type, other_value_type>);
302+
303+ hud::hashmap<key_type, value_type> map;
304+ const other_key_type key = other_key_type {123 };
305+
306+ // Should add default value 0
307+ map[key];
308+ auto &value = map.find (key)->value ();
309+ bool ok_default = value.id () == 0 ;
310+ ok_default &= value.constructor_count () == 0 ;
311+ ok_default &= value.copy_constructor_count () == 0 ;
312+ ok_default &= value.move_constructor_count () == 0 ;
313+ ok_default &= value.copy_assign_count () == 0 ;
314+ ok_default &= value.move_assign_count () == 0 ;
315+
316+ // Should add key, 0
317+ map[key] = other_value_type {1 };
318+ auto &value_ok = map.find (key)->value ();
319+ bool ok = value_ok.id () == 1 ;
320+ ok &= value_ok.constructor_count () == 1 ;
321+ ok &= value_ok.copy_constructor_count () == 0 ;
322+ ok &= value_ok.move_constructor_count () == 0 ;
323+ ok &= value_ok.copy_assign_count () == 0 ;
324+ ok &= value_ok.move_assign_count () == 1 ;
325+
326+ // Should replace value of key to 2
327+ map[key] = other_value_type {2 };
328+ auto &value_replace = map.find (key)->value ();
329+ bool ok_replace = value_replace.id () == 2 ;
330+ ok_replace &= value_replace.constructor_count () == 1 ;
331+ ok_replace &= value_replace.copy_constructor_count () == 0 ;
332+ ok_replace &= value_replace.move_constructor_count () == 0 ;
333+ ok_replace &= value_replace.copy_assign_count () == 0 ;
334+ ok_replace &= value_replace.move_assign_count () == 1 ;
335+
336+ return std::tuple {
337+ ok_default,
338+ ok,
339+ ok_replace
340+ };
341+ };
342+
77343 // Non constant
78344 {
79345 const auto result = test ();
0 commit comments