1 /**
2  * @file lv_ll.h
3  * Handle linked lists. The nodes are dynamically allocated by the 'lv_mem' module.
4  */
5 
6 #ifndef LV_LL_H
7 #define LV_LL_H
8 
9 #ifdef __cplusplus
10 extern "C" {
11 #endif
12 
13 /*********************
14  *      INCLUDES
15  *********************/
16 #include <stdint.h>
17 #include <stddef.h>
18 #include <stdbool.h>
19 
20 /*********************
21  *      DEFINES
22  *********************/
23 
24 /**********************
25  *      TYPEDEFS
26  **********************/
27 
28 /** Dummy type to make handling easier*/
29 typedef uint8_t lv_ll_node_t;
30 
31 /** Description of a linked list*/
32 typedef struct {
33     uint32_t n_size;
34     lv_ll_node_t * head;
35     lv_ll_node_t * tail;
36 } lv_ll_t;
37 
38 /**********************
39  * GLOBAL PROTOTYPES
40  **********************/
41 
42 /**
43  * Initialize linked list
44  * @param ll_p pointer to lv_ll_t variable
45  * @param node_size the size of 1 node in bytes
46  */
47 void _lv_ll_init(lv_ll_t * ll_p, uint32_t node_size);
48 
49 /**
50  * Add a new head to a linked list
51  * @param ll_p pointer to linked list
52  * @return pointer to the new head
53  */
54 void * _lv_ll_ins_head(lv_ll_t * ll_p);
55 
56 /**
57  * Insert a new node in front of the n_act node
58  * @param ll_p pointer to linked list
59  * @param n_act pointer a node
60  * @return pointer to the new node
61  */
62 void * _lv_ll_ins_prev(lv_ll_t * ll_p, void * n_act);
63 
64 /**
65  * Add a new tail to a linked list
66  * @param ll_p pointer to linked list
67  * @return pointer to the new tail
68  */
69 void * _lv_ll_ins_tail(lv_ll_t * ll_p);
70 
71 /**
72  * Remove the node 'node_p' from 'll_p' linked list.
73  * It does not free the memory of node.
74  * @param ll_p pointer to the linked list of 'node_p'
75  * @param node_p pointer to node in 'll_p' linked list
76  */
77 void _lv_ll_remove(lv_ll_t * ll_p, void * node_p);
78 
79 /**
80  * Remove and free all elements from a linked list. The list remain valid but become empty.
81  * @param ll_p pointer to linked list
82  */
83 void _lv_ll_clear(lv_ll_t * ll_p);
84 
85 /**
86  * Move a node to a new linked list
87  * @param ll_ori_p pointer to the original (old) linked list
88  * @param ll_new_p pointer to the new linked list
89  * @param node pointer to a node
90  * @param head true: be the head in the new list
91  *             false be the tail in the new list
92  */
93 void _lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node, bool head);
94 
95 /**
96  * Return with head node of the linked list
97  * @param ll_p pointer to linked list
98  * @return pointer to the head of 'll_p'
99  */
100 void * _lv_ll_get_head(const lv_ll_t * ll_p);
101 
102 /**
103  * Return with tail node of the linked list
104  * @param ll_p pointer to linked list
105  * @return pointer to the tail of 'll_p'
106  */
107 void * _lv_ll_get_tail(const lv_ll_t * ll_p);
108 
109 /**
110  * Return with the pointer of the next node after 'n_act'
111  * @param ll_p pointer to linked list
112  * @param n_act pointer a node
113  * @return pointer to the next node
114  */
115 void * _lv_ll_get_next(const lv_ll_t * ll_p, const void * n_act);
116 
117 /**
118  * Return with the pointer of the previous node after 'n_act'
119  * @param ll_p pointer to linked list
120  * @param n_act pointer a node
121  * @return pointer to the previous node
122  */
123 void * _lv_ll_get_prev(const lv_ll_t * ll_p, const void * n_act);
124 
125 /**
126  * Return the length of the linked list.
127  * @param ll_p pointer to linked list
128  * @return length of the linked list
129  */
130 uint32_t _lv_ll_get_len(const lv_ll_t * ll_p);
131 
132 /**
133  * TODO
134  * @param ll_p
135  * @param n1_p
136  * @param n2_p
137 void lv_ll_swap(lv_ll_t * ll_p, void * n1_p, void * n2_p);
138  */
139 
140 /**
141  * Move a node before an other node in the same linked list
142  * @param ll_p pointer to a linked list
143  * @param n_act pointer to node to move
144  * @param n_after pointer to a node which should be after `n_act`
145  */
146 void _lv_ll_move_before(lv_ll_t * ll_p, void * n_act, void * n_after);
147 
148 /**
149  * Check if a linked list is empty
150  * @param ll_p pointer to a linked list
151  * @return true: the linked list is empty; false: not empty
152  */
153 bool _lv_ll_is_empty(lv_ll_t * ll_p);
154 
155 /**********************
156  *      MACROS
157  **********************/
158 
159 #define _LV_LL_READ(list, i) for(i = _lv_ll_get_head(list); i != NULL; i = _lv_ll_get_next(list, i))
160 
161 #define _LV_LL_READ_BACK(list, i) for(i = _lv_ll_get_tail(list); i != NULL; i = _lv_ll_get_prev(list, i))
162 
163 #ifdef __cplusplus
164 } /*extern "C"*/
165 #endif
166 
167 #endif
168