From ca88afbf5b6efe15e9b7f571df28b12357eb9f92 Mon Sep 17 00:00:00 2001 From: Tomas Kallup Date: Tue, 17 Dec 2024 23:54:35 +0100 Subject: [PATCH] Fix hashmap put all for create + test case Closes: #1695 --- lib/std/collections/hashmap.c3 | 7 +++++-- lib/std/collections/map.c3 | 7 +++++-- releasenotes.md | 1 + test/unit/stdlib/collections/map.c3 | 32 ++++++++++++++++++++++++++--- 4 files changed, 40 insertions(+), 7 deletions(-) diff --git a/lib/std/collections/hashmap.c3 b/lib/std/collections/hashmap.c3 index f83f8e9dc..62bedc105 100644 --- a/lib/std/collections/hashmap.c3 +++ b/lib/std/collections/hashmap.c3 @@ -470,8 +470,11 @@ fn void HashMap.put_all_for_create(&map, HashMap* other_map) @private if (!other_map.count) return; foreach (Entry *e : other_map.table) { - if (!e) continue; - map.put_for_create(e.key, e.value); + while (e) + { + map.put_for_create(e.key, e.value); + e = e.next; + } } } diff --git a/lib/std/collections/map.c3 b/lib/std/collections/map.c3 index 885cadb5f..bb5c1077c 100644 --- a/lib/std/collections/map.c3 +++ b/lib/std/collections/map.c3 @@ -131,8 +131,11 @@ fn Map new_from_map(Map other_map, Allocator allocator = null) if (!other_map_impl.count) return (Map)map; foreach (Entry *e : other_map_impl.table) { - if (!e) continue; - map._put_for_create(e.key, e.value); + while (e) + { + map._put_for_create(e.key, e.value); + e = e.next; + } } return (Map)map; } diff --git a/releasenotes.md b/releasenotes.md index a3d1ee377..390e54a68 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -7,6 +7,7 @@ None ### Fixes - Fix case trying to initialize a `char[*]*` from a String. +- Fix Map & HashMap `put_all_for_create` not copying all elements, causing `init_from_map` to create incomplete copy. ### Stdlib changes - Increase BitWriter.write_bits limit up to 32 bits. diff --git a/test/unit/stdlib/collections/map.c3 b/test/unit/stdlib/collections/map.c3 index 2cbdab9b9..0382f6e8a 100644 --- a/test/unit/stdlib/collections/map.c3 +++ b/test/unit/stdlib/collections/map.c3 @@ -4,7 +4,8 @@ import std::collections::map; import std::sort; import std::io; -def Map = HashMap(); +def TestHashMap = HashMap(); +def TestMap = Map(); struct MapTest { @@ -15,7 +16,7 @@ def List = List(); fn void map() { - Map m; + TestHashMap m; assert(!m.is_initialized()); m.temp_init(); assert(m.is_initialized()); @@ -57,10 +58,35 @@ fn void map() fn void map_remove() { - Map m; + TestHashMap m; assert(!@ok(m.remove("A"))); m.temp_init(); assert(!@ok(m.remove("A"))); m.set("A", 0); assert(@ok(m.remove("A"))); } + +fn void map_copy() +{ + TestHashMap hash_map; + hash_map.temp_init(); + + hash_map.set("aa", 1); + hash_map.set("b", 2); + hash_map.set("bb", 1); + + TestHashMap hash_map_copy; + hash_map_copy.temp_init_from_map(&hash_map); + + assert(hash_map_copy.len() == hash_map.len()); + + TestMap map = map::temp()(); + + map.set("aa", 1); + map.set("b", 2); + map.set("bb", 1); + + TestMap map_copy = map::temp_from_map()(map); + + assert(map_copy.len() == map.len()); +}