Less aggressive colour change in the title
[snowy-minesweeper.git] / cdi / cdi-lists.c
blob28fa3e9eaa456f3a774217cf75562b284b1a9aeb
1 #include <stdlib.h>
2 #include <cdi/lists.h>
4 cdi_list_t cdi_list_create(void)
6 return calloc(1, sizeof(struct cdi_list));
9 void cdi_list_destroy(cdi_list_t list)
11 while (list->first) {
12 struct cdi_list_element *next = list->first->next;
13 free(list->first);
14 list->first = next;
17 free(list);
20 cdi_list_t cdi_list_push(cdi_list_t list, void *value)
22 struct cdi_list_element *new = calloc(1, sizeof(*new));
24 new->data = value;
26 new->next = list->first;
27 list->first = new;
28 list->cached_index++;
29 list->size++;
31 return list;
34 void *cdi_list_pop(cdi_list_t list)
36 struct cdi_list_element *first = list->first;
37 if (first) {
38 list->first = first->next;
40 if (list->size) {
41 list->size--;
43 if (list->cached_index) {
44 list->cached_index--;
47 if (!first) {
48 return NULL;
51 void *data = first->data;
52 free(first);
54 return data;
57 size_t cdi_list_empty(cdi_list_t list)
59 return !list->size;
62 void *cdi_list_get(cdi_list_t list, size_t index)
64 struct cdi_list_element *ele;
66 if (list->cached_index && index >= list->cached_index) {
67 ele = list->cached;
68 for (size_t i = list->cached_index; i < index && ele; i++) {
69 ele = ele->next;
71 } else {
72 ele = list->first;
73 for (size_t i = 0; i < index && ele; i++) {
74 ele = ele->next;
78 if (!ele) {
79 return NULL;
82 list->cached_index = index;
83 list->cached = ele;
85 return ele->data;
88 cdi_list_t cdi_list_insert(cdi_list_t list, size_t index, void *value)
90 struct cdi_list_element *new, *ele;
92 if (!index) {
93 return cdi_list_push(list, value);
96 new = calloc(1, sizeof(*new));
97 new->data = value;
99 if (list->cached_index && index > list->cached_index) {
100 ele = list->cached;
101 for (size_t i = list->cached_index; i < index - 1 && ele; i++) {
102 ele = ele->next;
104 } else {
105 ele = list->first;
106 for (size_t i = 0; i < index - 1 && ele; i++) {
107 ele = ele->next;
111 if (!ele) {
112 free(new);
113 return NULL;
116 if (index > 1) {
117 list->cached_index = index - 1;
118 list->cached = ele;
121 new->next = ele->next;
122 ele->next = new;
124 if (index == 1 && list->cached_index) {
125 list->cached_index++;
128 list->size++;
130 return list;
133 void *cdi_list_remove(cdi_list_t list, size_t index)
135 struct cdi_list_element *ele, *old;
137 if (!index) {
138 return cdi_list_pop(list);
141 if (list->cached_index && index > list->cached_index) {
142 ele = list->cached;
143 for (size_t i = list->cached_index; i < index - 1 && ele; i++) {
144 ele = ele->next;
146 } else {
147 ele = list->first;
148 for (size_t i = 0; i < index - 1 && ele; i++) {
149 ele = ele->next;
153 if (!ele || !ele->next) {
154 return NULL;
157 if (index == 1) {
158 list->cached_index--;
159 } else {
160 list->cached_index = index - 1;
161 list->cached = ele;
164 old = ele->next;
165 ele->next = old->next;
167 list->size--;
169 void *data = old->data;
170 free(old);
172 return data;
175 size_t cdi_list_size(cdi_list_t list)
177 return list->size;