Lazuli
Loading...
Searching...
No Matches
list.c
Go to the documentation of this file.
1/*
2 * SPDX-License-Identifier: GPL-3.0-only
3 * This file is part of Lazuli.
4 */
5
14#include <Lazuli/common.h>
15#include <Lazuli/config.h>
16#include <Lazuli/list.h>
17
18#include <Lazuli/sys/kernel.h>
19#include <Lazuli/sys/memory.h>
20
21void
22List_Append(Lz_LinkedList * const linkedList, Lz_LinkedListElement * const item)
23{
25 if (NULL == linkedList || NULL == item) {
27 }
28 }
29
30 item->next = NULL;
31
32 if (NULL == linkedList->first) {
33 item->prev = NULL;
34 linkedList->first = item;
35 linkedList->last = item;
36
37 return;
38 }
39
40 item->prev = linkedList->last;
41 linkedList->last->next = item;
42 linkedList->last = item;
43}
44
45void
46List_Prepend(Lz_LinkedList * const linkedList,
47 Lz_LinkedListElement * const item)
48{
50 if (NULL == linkedList || NULL == item) {
52 }
53 }
54
55 item->prev = NULL;
56
57 if (NULL == linkedList->first) {
58 item->next = NULL;
59 linkedList->first = item;
60 linkedList->last = item;
61
62 return;
63 }
64
65 item->next = linkedList->first;
66 linkedList->first->prev = item;
67 linkedList->first = item;
68}
69
70void
71List_AppendList(Lz_LinkedList * const linkedListDestination,
72 Lz_LinkedList * const linkedListToMove)
73{
75 if (NULL == linkedListDestination || NULL == linkedListToMove) {
77 }
78 }
79
80 if (NULL == linkedListToMove->first) {
81 return;
82 }
83
84 if (NULL == linkedListDestination->first) {
85 linkedListDestination->first = linkedListToMove->first;
86 } else {
87 linkedListDestination->last->next = linkedListToMove->first;
88 linkedListToMove->first->prev = linkedListDestination->last;
89 }
90
91 linkedListDestination->last = linkedListToMove->last;
92
93 linkedListToMove->first = NULL;
94 linkedListToMove->last = NULL;
95}
96
98List_PickFirst(Lz_LinkedList * const linkedList)
99{
101
103 if (NULL == linkedList) {
105 }
106 }
107
108 if (NULL == linkedList->first) {
109 return NULL;
110 }
111
112 item = linkedList->first;
113
114 linkedList->first = linkedList->first->next;
115
116 if (NULL == linkedList->first) {
117 linkedList->last = NULL;
118 } else {
119 linkedList->first->prev = NULL;
120 }
121
122 item->next = NULL;
123 item->prev = NULL;
124
125 return item;
126}
127
129List_PointFirst(const Lz_LinkedList * const linkedList)
130{
132 if (NULL == linkedList) {
134 }
135 }
136
137 return linkedList->first;
138}
139
140bool
141List_IsEmpty(const Lz_LinkedList * const linkedList)
142{
144 if (NULL == linkedList) {
146 }
147 }
148
149 return (NULL == linkedList->first && NULL == linkedList->last);
150}
151
152void
154 Lz_LinkedListElement * const listItem,
155 Lz_LinkedListElement * const itemToInsert)
156{
158 if (NULL == linkedList || NULL == listItem || NULL == itemToInsert) {
160 }
161 }
162
163 if (linkedList->last == listItem) {
164 linkedList->last = itemToInsert;
165 }
166
167 itemToInsert->next = listItem->next;
168 itemToInsert->prev = listItem;
169 listItem->next = itemToInsert;
170}
171
172void
174 Lz_LinkedListElement * const listItem,
175 Lz_LinkedListElement * const itemToInsert)
176{
178 if (NULL == linkedList || NULL == listItem || NULL == itemToInsert) {
180 }
181 }
182
183 if (linkedList->first == listItem) {
184 linkedList->first = itemToInsert;
185 }
186
187 itemToInsert->next = listItem;
188 itemToInsert->prev = listItem->prev;
189 listItem->prev = itemToInsert;
190}
191
192/*
193 * TODO: Prove that itemToRemove belongs to linkedList.
194 * The same can be done for other functions such as List_InsertBefore...
195 */
197List_Remove(Lz_LinkedList * const linkedList,
198 Lz_LinkedListElement * const itemToRemove)
199{
200 Lz_LinkedListElement * previousElement;
201
203 if (NULL == linkedList || NULL == itemToRemove) {
205 }
206 }
207
208 previousElement = itemToRemove->prev;
209
210 if (NULL == itemToRemove->prev) {
211 linkedList->first = itemToRemove->next;
212 } else {
213 itemToRemove->prev->next = itemToRemove->next;
214 }
215
216 if (NULL == itemToRemove->next) {
217 linkedList->last = itemToRemove->prev;
218 } else {
219 itemToRemove->next->prev = itemToRemove->prev;
220 }
221
222 itemToRemove->prev = NULL;
223 itemToRemove->next = NULL;
224
225 return previousElement;
226}
227
229List_PointElementAt(const Lz_LinkedList * const linkedList, const size_t index)
230{
232 size_t currentIndex = 0;
233
235 if (NULL == linkedList) {
237 }
238 }
239
240 List_UntypedForEach(linkedList, item) {
241 if (currentIndex == index) {
242 return item;
243 }
244
245 ++currentIndex;
246 }
247
248 return NULL;
249}
250
251void
253{
254 const Lz_LinkedList linkedListInit = LINKED_LIST_INIT;
255
257 if (NULL == linkedList) {
259 }
260 }
261
262 Memory_Copy(&linkedListInit, linkedList, sizeof(linkedListInit));
263}
264
265void
267{
268 const Lz_LinkedListElement linkedListElementInit = LINKED_LIST_ELEMENT_INIT;
269
271 if (NULL == item) {
273 }
274 }
275
276 Memory_Copy(&linkedListElementInit, item, sizeof(linkedListElementInit));
277}
Basic type definitions and useful macros.
#define NULL
NULL pointer.
Definition common.h:70
Include appropriate config file.
const bool LZ_CONFIG_CHECK_NULL_PARAMETERS_IN_LISTS
When 1, always check for NULL functions parameters in linked lists implementation.
void Kernel_ManageFailure(void)
Manage a failure that can happen in a function call.
Definition kernel.c:95
Kernel symbols definition.
void List_Append(Lz_LinkedList *const linkedList, Lz_LinkedListElement *const item)
Insert an Lz_LinkedListElement as the last element of an existing Lz_LinkedList.
Definition list.c:22
bool List_IsEmpty(const Lz_LinkedList *const linkedList)
Test if an Lz_LinkedList is empty.
Definition list.c:141
Lz_LinkedListElement * List_PickFirst(Lz_LinkedList *const linkedList)
Return the first element of an existing linked list.
Definition list.c:98
Lz_LinkedListElement * List_Remove(Lz_LinkedList *const linkedList, Lz_LinkedListElement *const itemToRemove)
Remove an element from an Lz_LinkedList.
Definition list.c:197
void List_AppendList(Lz_LinkedList *const linkedListDestination, Lz_LinkedList *const linkedListToMove)
Move the content of an Lz_LinkedList to the end of an existing Lz_LinkedList.
Definition list.c:71
Lz_LinkedListElement * List_PointFirst(const Lz_LinkedList *const linkedList)
Return a pointer to the first element of an existing linked list.
Definition list.c:129
void List_InitLinkedList(Lz_LinkedList *const linkedList)
Initialize an Lz_LinkedList.
Definition list.c:252
void List_Prepend(Lz_LinkedList *const linkedList, Lz_LinkedListElement *const item)
Insert an Lz_LinkedListElement as the first element of an existing Lz_LinkedList.
Definition list.c:46
void List_InsertAfter(Lz_LinkedList *const linkedList, Lz_LinkedListElement *const listItem, Lz_LinkedListElement *const itemToInsert)
Insert an element after another in an Lz_LinkedList.
Definition list.c:153
Lz_LinkedListElement * List_PointElementAt(const Lz_LinkedList *const linkedList, const size_t index)
Point to an indexed element in an Lz_LinkedList, starting at index 0.
Definition list.c:229
void List_InitLinkedListElement(Lz_LinkedListElement *const item)
Initialize an Lz_LinkedListElement.
Definition list.c:266
void List_InsertBefore(Lz_LinkedList *const linkedList, Lz_LinkedListElement *const listItem, Lz_LinkedListElement *const itemToInsert)
Insert an element before another in a Lz_LinkedList.
Definition list.c:173
Doubly linked lists interface.
#define List_UntypedForEach(LINKEDLIST, ITEM)
Run through an Lz_LinkedList like a for loop.
Definition list.h:146
#define LINKED_LIST_INIT
Define the initialization value for the type Lz_LinkedList.
Definition list.h:47
#define LINKED_LIST_ELEMENT_INIT
Define the initialization value for the type Lz_LinkedListElement.
Definition list.h:52
void Memory_Copy(const void *source, void *destination, const size_t size)
Copy bytes from one location to another in main memory.
Definition memory.c:73
Memory management API.
Represents the main container for doubly linked elements.
Definition list.h:36
Lz_LinkedListElement * first
A pointer to the first element of the linked list.
Definition list.h:38
Lz_LinkedListElement * last
A pointer to the last element of the linked list.
Definition list.h:41
Represents an element of a doubly linked list.
Definition list.h:25
struct _Lz_LinkedListElement * next
A pointer to the next element in the list.
Definition list.h:27
struct _Lz_LinkedListElement * prev
A pointer to the previous element in the list.
Definition list.h:30