Add list base
This commit is contained in:
parent
5eeb9677d5
commit
22001e480e
77
src/list/base.c
Normal file
77
src/list/base.c
Normal 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
109
src/list/copy.c
Normal 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
28
src/list/include.h
Normal 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 */
|
Loading…
Reference in New Issue
Block a user