/* This software is licensed by the MIT License, see LICENSE file */ /* Copyright © 2022 Gregory Lirent */ #include "include.h" #include "../__internal/assert.h" arr_t array_copy(const arr_t* s) { arr_t x = { .mem = 0, .size = 0, .type = 0 }; if (s->size > 0) { assert(!is_null(s->mem)); x.type = s->type; x.size = s->size; if (s->type >= VTYPE_STRING) { void *p, *v, *e; void (*init)(void*, const void*); x.mem = p = malloc(array_allocated_nmemb(s)); v = s->mem; e = array_end(&x); switch (s->type) { default: abort(); case VTYPE_STRING: init = (void*)string_copy_init; break; case VTYPE_ARRAY: init = (void*) array_copy_init; break; case VTYPE_LIST: init = (void*) list_copy_init; break; case VTYPE_MAP: init = (void*) map_copy_init; break; case VTYPE_SET: init = (void*) vset_copy_init; break; } do { init(p, v); p += vtype_size(x.type); v += vtype_size(x.type); } while (p < e); } else x.mem = memndup(s->mem, array_allocated_nmemb(s)); } return x; } arr_t* array_duplicate(const arr_t* s) { arr_t* x = malloc(sizeof(*x)); if (s->size > 0) { assert(!is_null(s->mem)); x->type = s->type; x->size = s->size; if (s->type >= VTYPE_STRING) { void *p, *v, *e; void (*init)(void*, const void*); x->mem = p = malloc(array_allocated_nmemb(s)); v = s->mem; e = array_end(x); switch (s->type) { default: abort(); case VTYPE_STRING: init = (void*)string_copy_init; break; case VTYPE_ARRAY: init = (void*) array_copy_init; break; case VTYPE_LIST: init = (void*) list_copy_init; break; case VTYPE_MAP: init = (void*) map_copy_init; break; case VTYPE_SET: init = (void*) vset_copy_init; break; } do { init(p, v); p += vtype_size(x->type); v += vtype_size(x->type); } while (p < e); } else x->mem = memndup(s->mem, array_allocated_nmemb(s)); } else memset(x, 0, sizeof(*x)); return x; } void array_copy_init(arr_t* x, const arr_t* s) { if (s->size > 0) { assert(!is_null(s->mem)); x->type = s->type; x->size = s->size; if (s->type >= VTYPE_STRING) { void *p, *v, *e; void (*init)(void*, const void*); x->mem = p = malloc(array_allocated_nmemb(s)); v = s->mem; e = array_end(x); switch (s->type) { default: abort(); case VTYPE_STRING: init = (void*)string_copy_init; break; case VTYPE_ARRAY: init = (void*) array_copy_init; break; case VTYPE_LIST: init = (void*) list_copy_init; break; case VTYPE_MAP: init = (void*) map_copy_init; break; case VTYPE_SET: init = (void*) vset_copy_init; break; } do { init(p, v); p += vtype_size(x->type); v += vtype_size(x->type); } while (p < e); } else x->mem = memndup(s->mem, array_allocated_nmemb(s)); } else memset(x, 0, sizeof(*x)); }