aboutsummaryrefslogtreecommitdiff
path: root/linked_list.inc.h
blob: a878d0752719ee100e6b23b8ea4ac0d330ba25ac (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#ifndef TYPE
#error "Set TYPE before including this file"
#else

int CONSTRUCTOR_DECL ( LLIST(TYPE) ) {
	this->length = 0;
	NEW(LINK(TYPE), head);
	NEW(LINK(TYPE), tail);
	this->head = head;
	this->tail = tail;
	head->after = tail;
	tail->before = head;
	this->cur  = head;
	return 0;
}

int FREE_DECL( LLIST(TYPE) ) {
	LINK(TYPE) *node, *next;
	node = this->head->after;
	while (node->after != NULL) {
		next = node->after;
		if (node->value != NULL) {
			FFREE(TYPE, node->value);
		}
		// free(node);
		node = next;
	}
	free (this->head);
	free (this->tail);
	this->length = 0;
	return 0;
}

int CONSTRUCTOR_DECL ( LINK(TYPE) ) {
	this->before = NULL;
	this->after  = NULL;
	this->value  = NULL;
	return 0;
}

int CONSTRUCTOR_DECL ( LINK(TYPE), TYPE* val ) {
	this->before = NULL;
	this->after  = NULL;
	this->value  = val;
	return 0;
}

int LLIST_CONS(TYPE) ( LLIST(TYPE)* lst, TYPE* val) {
	NEW(LINK(TYPE), l, val);

	l->after = lst->head->after;
	lst->head->after = l;
	l->after->before = l;
	l->before = lst->head;
	++lst->length;

	// TODO do I want to change that?
	lst->cur = l;

	return 0;
}

int DEEP_COPY(LLIST(TYPE)) ( LLIST(TYPE)* dest, LLIST(TYPE)* src ) {
	LINK(TYPE)* n = src->head->after;

	while (n->after != NULL) {
		NEW(TYPE, cpy);
		DEEP_COPY(TYPE)(cpy, n->value);
		LLIST_CONS(TYPE) ( dest, cpy );
		n = n->after;
	}

	return 0;
}

/*
 * TODO
 * this or cons links wrong, creating infinite loops.
 */
int APPEND(LLIST(TYPE)) ( LLIST(TYPE)* dest, LLIST(TYPE)* new ) {

	dest->tail->before->after = new->head->after;
	new->head->after->before = dest->tail->before;
	LINK(TYPE)* old_tail = dest->tail;
	dest->tail = new->tail;
	dest->length += new->length;

	// free(old_tail);
	// free(new->head);

	/*
	 * TODO `new` can now be handled as an empty husk.
	 * Somehow it needs to be collected
	 */

	return 0;
}

#endif /* TYPE */