aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--map.c22
-rw-r--r--map.h2
2 files changed, 24 insertions, 0 deletions
diff --git a/map.c b/map.c
index 5fde157..57dc761 100644
--- a/map.c
+++ b/map.c
@@ -284,6 +284,28 @@ void map_clear(Map *map)
map->v = NULL;
}
+static bool copy(Map *dest, Map n)
+{
+ if (!n.v) {
+ return copy(dest, n.u.n->child[0]) &&
+ copy(dest, n.u.n->child[1]);
+ } else {
+ if (!map_put(dest, n.u.s, n.v) && map_get(dest, n.u.s) != n.v) {
+ map_delete(dest, n.u.s);
+ return map_put(dest, n.u.s, n.v);
+ }
+ return true;
+ }
+}
+
+bool map_copy(Map *dest, Map *src)
+{
+ if (!src || !src->u.n)
+ return true;
+
+ return copy(dest, *src);
+}
+
bool map_empty(const Map *map)
{
return map->u.n == NULL;
diff --git a/map.h b/map.h
index 078c9c6..0540fab 100644
--- a/map.h
+++ b/map.h
@@ -21,6 +21,8 @@ bool map_put(Map*, const char *key, const void *value);
/* Remove a member from the map. Returns the removed entry or NULL
* if there was no entry found using the given key*/
void *map_delete(Map*, const char *key);
+/* Copy all entries from `src' into `dest', overwrites existing entries in `dest' */
+bool map_copy(Map *dest, Map *src);
/* Ordered iteration over a map, call handle for every entry. If handle
* returns false, the iteration will stop. */
void map_iterate(const Map*, bool (*handle)(const char *key, void *value, void *data), const void *data);