libcdsb/src/map/copy.c

122 lines
3.1 KiB
C

/* This software is licensed by the MIT License, see LICENSE file */
/* Copyright © 2022 Gregory Lirent */
#include "include.h"
static inline mnode_t* libcdsb_builtin_duplicate(const mnode_t* s, mnode_t* p, const vtype t) {
mnode_t* x;
x = mnode_create(vnode_duplicate(&s->key, t), p, s->colored);
x->type = s->type;
x->value = vnode_duplicate(&s->value, s->type);
return x;
}
/*#####################################################################################################################*/
map_t map_copy(const map_t* s) {
map_t x;
stack_t z;
stack_init(&z);
stack_push(&z, s->root);
x.type = s->type;
if (!mnode_is_empty(s->root)) {
x.root = libcdsb_builtin_duplicate(s->root, mnode_empty, s->type);
stack_push(&z, x.root);
do {
mnode_t *p0 = stack_pop(&z);
mnode_t *p1 = stack_pop(&z);
if (!mnode_is_empty(p1->left)) {
p0->left = libcdsb_builtin_duplicate(p1->left, p0, s->type);
stack_push_many(&z, 2, p1->left, p0->left);
}
if (!mnode_is_empty(p1->right)) {
p0->right = libcdsb_builtin_duplicate(p1->right, p0, s->type);
stack_push_many(&z, 2, p1->right, p0->right);
}
} while (!is_null(z.value));
} else x.root = mnode_empty;
return x;
}
map_t* map_duplicate(const map_t* s) {
map_t* x;
stack_t z;
stack_init(&z);
stack_push(&z, s->root);
x = malloc(sizeof(*x));
x->type = s->type;
if (!mnode_is_empty(s->root)) {
x->root = libcdsb_builtin_duplicate(s->root, mnode_empty, s->type);
stack_push(&z, x->root);
do {
mnode_t *p0 = stack_pop(&z);
mnode_t *p1 = stack_pop(&z);
if (!mnode_is_empty(p1->left)) {
p0->left = libcdsb_builtin_duplicate(p1->left, p0, s->type);
stack_push_many(&z, 2, p1->left, p0->left);
}
if (!mnode_is_empty(p1->right)) {
p0->right = libcdsb_builtin_duplicate(p1->right, p0, s->type);
stack_push_many(&z, 2, p1->right, p0->right);
}
} while (!is_null(z.value));
} else x->root = mnode_empty;
return x;
}
void map_copy_init(map_t* x, const map_t* s) {
stack_t z;
stack_init(&z);
stack_push(&z, s->root);
x->type = s->type;
if (!mnode_is_empty(s->root)) {
x->root = libcdsb_builtin_duplicate(s->root, mnode_empty, s->type);
stack_push(&z, x->root);
do {
mnode_t *p0 = stack_pop(&z);
mnode_t *p1 = stack_pop(&z);
if (!mnode_is_empty(p1->left)) {
p0->left = libcdsb_builtin_duplicate(p1->left, p0, s->type);
stack_push_many(&z, 2, p1->left, p0->left);
}
if (!mnode_is_empty(p1->right)) {
p0->right = libcdsb_builtin_duplicate(p1->right, p0, s->type);
stack_push_many(&z, 2, p1->right, p0->right);
}
} while (!is_null(z.value));
} else x->root = mnode_empty;
}