Add list base

This commit is contained in:
Gregory Lirent 2022-06-04 21:59:01 +03:00
parent 5eeb9677d5
commit 22001e480e
3 changed files with 214 additions and 0 deletions

77
src/list/base.c Normal file
View File

@ -0,0 +1,77 @@
/* This software is licensed by the MIT License, see LICENSE file */
/* Copyright © 2022 Gregory Lirent */
#include "include.h"
/*#####################################################################################################################*/
void list_init(list_t* x) {
memset(x, 0, sizeof(*x));
}
void list_free(list_t* x) {
lnode_t* c;
lnode_t* next;
c = x->first;
while (!is_null(c)) {
next = c->next;
vnode_free(c->node, c->type);
free(c);
c = next;
}
memset(x, 0, sizeof(*x));
}
/*#####################################################################################################################*/
size_t list_size(const list_t* x) {
lnode_t* c;
size_t n;
c = x->first;
n = 0;
while (!is_null(c)) {
c = c->next;
++n;
}
return n;
}
/*#####################################################################################################################*/
int list_compare(const list_t* s0, const list_t* s1) {
lnode_t *c0, *c1;
int c;
if (s0 == s1) return 0;
c0 = s0->first;
c1 = s1->first;
for (;;) {
if (is_null(c0) || is_null(c1)) {
return (c0 == c1) ? 0 : (ssize_t)c0 - (ssize_t)c1;
}
c = lnode_compare(c0, c1);
if (c != 0) break;
c0 = c0->next;
c1 = c1->next;
}
for (;;) {
c0 = c0->next;
c1 = c1->next;
if (is_null(c0) || is_null(c1)) {
return (c0 == c1) ? 0 : (ssize_t)c0 - (ssize_t)c1;
}
}
}

109
src/list/copy.c Normal file
View File

@ -0,0 +1,109 @@
/* This software is licensed by the MIT License, see LICENSE file */
/* Copyright © 2022 Gregory Lirent */
#include "include.h"
/*#####################################################################################################################*/
static void init_first(list_t* x, vnode_t v, vtype t) {
lnode_t* node = malloc(sizeof(*node));
node->next = nullptr;
node->prev = nullptr;
node->node = v;
node->type = t;
x->first = node;
x->last = node;
}
static void push_next(list_t* x, vnode_t v, vtype t) {
lnode_t* node = malloc(sizeof(*node));
node->next = nullptr;
node->prev = x->last;
node->node = v;
node->type = t;
x->last = node;
x->last->next = node;
}
/*#####################################################################################################################*/
list_t list_copy(const list_t* s) {
list_t x;
lnode_t* c;
c = s->first;
memset(&x, 0, sizeof(x));
if (is_null(c))
return x;
init_first(&x, vnode_duplicate(&c->node, c->type), c->type);
while (!is_null(c = c->next)) {
push_next(&x, vnode_duplicate(&c->node, c->type), c->type);
}
return x;
}
list_t* list_duplicate(const list_t* s) {
list_t* x;
lnode_t* c;
c = s->first;
x = calloc(sizeof(*x), 1);
if (is_null(c))
return x;
init_first(x, vnode_duplicate(&c->node, c->type), c->type);
while (!is_null(c = c->next)) {
push_next(x, vnode_duplicate(&c->node, c->type), c->type);
}
return x;
}
void list_copy_init(list_t* x, const list_t* s) {
lnode_t* c;
c = s->first;
memset(x, 0, sizeof(*x));
if (is_null(c))
return;
init_first(x, vnode_duplicate(&c->node, c->type), c->type);
while (!is_null(c = c->next)) {
push_next(x, vnode_duplicate(&c->node, c->type), c->type);
}
}
/*#####################################################################################################################*/
void list_extend(list_t* x, const list_t* s) {
lnode_t* c;
c = s->first;
if (is_null(c))
return;
if (is_null(x->first)) {
init_first(x, vnode_duplicate(&c->node, c->type), c->type);
c = c->next;
if (is_null(c))
return;
}
do {
push_next(x, vnode_duplicate(&c->node, c->type), c->type);
} while (!is_null(c = c->next));
}

28
src/list/include.h Normal file
View File

@ -0,0 +1,28 @@
/* This software is licensed by the MIT License, see LICENSE file */
/* Copyright © 2022 Gregory Lirent */
#include "../../include/extra/list.h"
#include "../__internal/vnode.h"
#ifndef LIBCDSB_SRC_LIST_INCLUDE_H
#define LIBCDSB_SRC_LIST_INCLUDE_H
typedef enum libcdsb_list_direction {
LD_PREV = 1,
LD_NEXT = 2
} ldir_t;
typedef struct libcdsb_list_node {
struct libcdsb_list_node* prev;
struct libcdsb_list_node* next;
vnode_t node;
vtype type;
} lnode_t;
#define ldir_dir(cur, d) (&((cur)->prev))[(d)>>1]
#define ldir_inv(cur, d) (&((cur)->prev))[(d)&1]
#define lnode_compare(s0, s1) vnode_compare((s0)->node, (s0)->type, (s1)->node, (s1)->type)
#endif /* LIBCDSB_SRC_LIST_INCLUDE_H */