aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTucker Evans <tuckerevans24@gmail.com>2020-07-24 15:38:15 -0400
committerTucker Evans <tuckerevans24@gmail.com>2020-07-24 15:56:31 -0400
commitbc540d32e8d2ff16ffe688b02f18d565651e4b10 (patch)
treeaefaefaeb7451086eacfde86d5d523798bd1964e
parent1cd08117d9506d72bf4bf87a12ad4720d0892407 (diff)
Add swap function for maps
-rw-r--r--collections/map/map.adoc26
-rw-r--r--collections/map/map.c49
-rw-r--r--collections/map/map.h2
3 files changed, 77 insertions, 0 deletions
diff --git a/collections/map/map.adoc b/collections/map/map.adoc
index c42a99a..740df3c 100644
--- a/collections/map/map.adoc
+++ b/collections/map/map.adoc
@@ -119,6 +119,32 @@ assert(strcmp(tmp, "FOUR") == 0);
free(tmp);
----
+[[map_swap]]
++void map_swap(map *self, void *i, void *j)+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Swaps values at keys +i+ and +j+, does nothing if +i+ or +j+ are invalid keys.
+
+Examples
+^^^^^^^^
+[source,c]
+----
+#include "map.h"
+#include <string.h>
+
+char *str1 = "ONE";
+char *str2 = "TWO";
+
+map *dict = map_new((cmp_func) strcmp);
+
+map_insert(dict, str1, strdup(str2));
+map_insert(dict, str2, strdup(str3));
+
+map_swap(dict, str1, str2);
+
+assert(strcmp(str1, map_index(dict, str1)) == 0);
+assert(strcmp(str2, map_index(dict, str2)) == 0);
+----
+
[[map_set_val]]
+void* map_set_val(map *self, void *key, void *val)+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/collections/map/map.c b/collections/map/map.c
index 5ad0b65..b0e095e 100644
--- a/collections/map/map.c
+++ b/collections/map/map.c
@@ -497,6 +497,55 @@ void *key;
return ret;
}
+void map_swap(root, ikey, jkey)
+map *root;
+void *ikey, *jkey;
+{
+ struct map_node *tmp, *inode, *jnode;
+ void *tmp_val;
+ int cmp;
+
+ tmp = root->root;
+
+searchi:
+ if (!tmp)
+ return;
+
+ cmp = root->cmp(ikey, tmp->key);
+ if (cmp < 0) {
+ tmp = tmp->left;
+ goto searchi;
+ }
+ if (cmp > 0) {
+ tmp = tmp->right;
+ goto searchi;
+ }
+
+ inode = tmp;
+
+ tmp = root->root;
+searchj:
+ if (!tmp)
+ return;
+
+ cmp = root->cmp(jkey, tmp->key);
+ if (cmp < 0) {
+ tmp = tmp->left;
+ goto searchj;
+ }
+ if (cmp > 0) {
+ tmp = tmp->right;
+ goto searchj;
+ }
+
+ jnode = tmp;
+ tmp_val = jnode->val;
+ jnode->val = inode->val;
+ inode->val = tmp_val;
+
+ return;
+}
+
void map_clear_aux(root)
struct map_node *root;
{
diff --git a/collections/map/map.h b/collections/map/map.h
index 81718c1..c6fb83d 100644
--- a/collections/map/map.h
+++ b/collections/map/map.h
@@ -17,6 +17,8 @@ void* map_remove(map*, void*);
void* map_set_val(map*, void*, void*);
void* map_index(map*, void*);
+void map_swap(map*, void*, void*);
+
int map_check_key_ptr(map*, void*);
void* map_set_key(map*, void*);