1 /***********************************************************************************************************************************
2 List Handler
3 ***********************************************************************************************************************************/
4 #ifndef COMMON_TYPE_LIST_H
5 #define COMMON_TYPE_LIST_H
6 
7 #include <limits.h>
8 
9 /***********************************************************************************************************************************
10 List object
11 ***********************************************************************************************************************************/
12 typedef struct List List;
13 
14 #include "common/memContext.h"
15 #include "common/type/object.h"
16 #include "common/type/param.h"
17 #include "common/type/string.h"
18 
19 /***********************************************************************************************************************************
20 Sort orders
21 ***********************************************************************************************************************************/
22 typedef enum
23 {
24     sortOrderNone,
25     sortOrderAsc,
26     sortOrderDesc,
27 } SortOrder;
28 
29 /***********************************************************************************************************************************
30 Define initial size of a list
31 ***********************************************************************************************************************************/
32 #define LIST_INITIAL_SIZE                                           8
33 
34 /***********************************************************************************************************************************
35 Item was not found in the list
36 ***********************************************************************************************************************************/
37 #define LIST_NOT_FOUND                                              UINT_MAX
38 
39 /***********************************************************************************************************************************
40 Function type for comparing items in the list
41 
42 The return value should be -1 when item1 < item2, 0 when item1 == item2, and 1 when item2 > item1.
43 ***********************************************************************************************************************************/
44 typedef int ListComparator(const void *item1, const void *item2);
45 
46 // General purpose list comparator for Strings or structs with a String as the first member
47 int lstComparatorStr(const void *item1, const void *item2);
48 
49 // General purpose list comparator for zero-terminated strings or structs with a zero-terminated string as the first member
50 int lstComparatorZ(const void *item1, const void *item2);
51 
52 /***********************************************************************************************************************************
53 Constructors
54 ***********************************************************************************************************************************/
55 typedef struct ListParam
56 {
57     VAR_PARAM_HEADER;
58     SortOrder sortOrder;
59     ListComparator *comparator;
60 } ListParam;
61 
62 #define lstNewP(itemSize, ...)                                                                                                     \
63     lstNew(itemSize, (ListParam){VAR_PARAM_INIT, __VA_ARGS__})
64 
65 List *lstNew(size_t itemSize, ListParam param);
66 
67 /***********************************************************************************************************************************
68 Getters/Setters
69 ***********************************************************************************************************************************/
70 typedef struct ListPub
71 {
72     MemContext *memContext;                                         // Mem context
73     unsigned int listSize;                                          // List size
74 } ListPub;
75 
76 // Set a new comparator
77 List *lstComparatorSet(List *this, ListComparator *comparator);
78 
79 // Memory context for this list
80 __attribute__((always_inline)) static inline MemContext *
lstMemContext(const List * const this)81 lstMemContext(const List *const this)
82 {
83     return THIS_PUB(List)->memContext;
84 }
85 
86 // List size
87 __attribute__((always_inline)) static inline unsigned int
lstSize(const List * const this)88 lstSize(const List *const this)
89 {
90     return THIS_PUB(List)->listSize;
91 }
92 
93 // Is the list empty?
94 __attribute__((always_inline)) static inline bool
lstEmpty(const List * const this)95 lstEmpty(const List *const this)
96 {
97     return lstSize(this) == 0;
98 }
99 
100 /***********************************************************************************************************************************
101 Functions
102 ***********************************************************************************************************************************/
103 // Clear items from a list
104 List *lstClear(List *this);
105 
106 // Get an item from the list
107 void *lstGet(const List *this, unsigned int listIdx);
108 void *lstGetLast(const List *this);
109 
110 // Find an item in the list
111 void *lstFind(const List *this, const void *item);
112 void *lstFindDefault(const List *this, const void *item, void *itemDefault);
113 unsigned int lstFindIdx(const List *this, const void *item);
114 
115 // Does an item exist in the list?
116 __attribute__((always_inline)) static inline bool
lstExists(const List * const this,const void * const item)117 lstExists(const List *const this, const void *const item)
118 {
119     return lstFind(this, item) != NULL;
120 }
121 
122 // Get the index of a list item
123 unsigned int lstIdx(const List *this, const void *item);
124 
125 // Insert an item into the list
126 void *lstInsert(List *this, unsigned int listIdx, const void *item);
127 
128 // Add an item to the end of the list
129 __attribute__((always_inline)) static inline void *
lstAdd(List * const this,const void * const item)130 lstAdd(List *const this, const void *const item)
131 {
132     return lstInsert(this, lstSize(this), item);
133 }
134 
135 // Move to a new parent mem context
136 __attribute__((always_inline)) static inline List *
lstMove(List * const this,MemContext * const parentNew)137 lstMove(List *const this, MemContext *const parentNew)
138 {
139     return objMove(this, parentNew);
140 }
141 
142 // Remove an item from the list
143 bool lstRemove(List *this, const void *item);
144 List *lstRemoveIdx(List *this, unsigned int listIdx);
145 List *lstRemoveLast(List *this);
146 
147 // List sort
148 List *lstSort(List *this, SortOrder sortOrder);
149 
150 /***********************************************************************************************************************************
151 Destructor
152 ***********************************************************************************************************************************/
153 __attribute__((always_inline)) static inline void
lstFree(List * const this)154 lstFree(List *const this)
155 {
156     objFree(this);
157 }
158 
159 /***********************************************************************************************************************************
160 Macros for function logging
161 ***********************************************************************************************************************************/
162 String *lstToLog(const List *this);
163 
164 #define FUNCTION_LOG_LIST_TYPE                                                                                                     \
165     List *
166 #define FUNCTION_LOG_LIST_FORMAT(value, buffer, bufferSize)                                                                        \
167     FUNCTION_LOG_STRING_OBJECT_FORMAT(value, lstToLog, buffer, bufferSize)
168 
169 #endif
170