Mstdlib-1.24.0
m_llist_str.h
1/* The MIT License (MIT)
2 *
3 * Copyright (c) 2015 Monetra Technologies, LLC.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 * THE SOFTWARE.
22 */
23
24#ifndef __M_LLIST_STR_H__
25#define __M_LLIST_STR_H__
26
27/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
28
29#include <mstdlib/base/m_defs.h>
30#include <mstdlib/base/m_types.h>
31#include <mstdlib/base/m_sort.h>
32
33/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
34
35__BEGIN_DECLS
36
37/*! \addtogroup m_llist_str Linked List - String
38 * \ingroup m_llist
39 *
40 * Linked list for storing values.
41 *
42 * The list can be used in multiple ways:
43 * - Unsorted.
44 * - Sorted.
45 * - Queue (FIFO) (really just unsorted).
46 * - Priority Queue (really just sorted).
47 *
48 * A linked list is not indexable. Iteration and find are supported.
49 *
50 * Sorted notes:
51 * - Sorting is implemented as a skip list. This should provide near O(long(n)) performance.
52 * Performance nearing a sorted M_list_t.
53 * - Sorting is stable. If an element with a matching value is already in the list then it
54 * will be inserted after. Find will always find the first matching element in the list.
55 *
56 * @{
57 */
58
59struct M_llist_str;
60/* Currently a direct map to M_list private opaque type,
61 * simply using casting to prevent the 'wrap' overhead of mallocing when it
62 * is not necessary */
63typedef struct M_llist_str M_llist_str_t;
64
65struct M_llist_str_node;
66/* Currently a direct map to M_list private opaque type,
67 * simply using casting to prevent the 'wrap' overhead of mallocing when it
68 * is not necessary */
69typedef struct M_llist_str_node M_llist_str_node_t;
70
71
72/*! Flags for controlling the behavior of the list. */
73typedef enum {
74 M_LLIST_STR_NONE = 0, /*!< List mode. */
75 M_LLIST_STR_SORTASC = 1 << 0, /*!< Sort asc. */
76 M_LLIST_STR_SORTDESC = 1 << 1, /*!< Sort desc. */
77 M_LLIST_STR_CASECMP = 1 << 2, /*!< Compare is case insensitive. */
78 M_LLIST_STR_CIRCULAR = 1 << 3 /*!< Circular list. Cannnot be used with SORT flags. */
80
81
82/*! Type of matching that should be used when searching/modifying a value in the list. */
83typedef enum {
84 M_LLIST_STR_MATCH_VAL = 0, /*!< Match based on the value. */
85 M_LLIST_STR_MATCH_PTR = 1 << 0, /*!< Match the pointer itself. */
86 M_LLIST_STR_MATCH_ALL = 1 << 1 /*!< Include all instances. */
88
89
90/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
91
92/*! Create a new list.
93 *
94 * A list is a linked list. The list can be, optionally, kept in sorted
95 * order. The sorted order is determined by the flags.
96 *
97 * \param[in] flags M_llist_str_flags_t flags controlling behavior.
98 *
99 * \return Allocated linked list.
100 *
101 * \see M_llist_str_destroy
102 */
103M_API M_llist_str_t *M_llist_str_create(M_uint32 flags) M_MALLOC;
104
105
106/*! Use the provided callback and thunk for sorting.
107 *
108 * \warning
109 * This function will only succeed if the linked list was created with sorting enabled, and no strings have been
110 * added to the list yet.
111 *
112 * \param d the llist_str to update
113 * \param equality_cb callback that should be used for sorting
114 * \param equality_thunk thunk to pass to callback, may be \c NULL. Ownership of thunk remains with caller.
115 * \return M_TRUE on success, M_FALSE if error
116 */
117M_API M_bool M_llist_str_change_sorting(M_llist_str_t *d, M_sort_compar_t equality_cb, void *equality_thunk);
118
119
120/*! Destroy the list.
121 *
122 * \param[in] d The linked list to destroy.
123 */
124M_API void M_llist_str_destroy(M_llist_str_t *d) M_FREE(1);
125
126
127/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
128
129/*! Insert a value into the list.
130 *
131 * If sorted the value will be inserted in sorted order. Otherwise it will be
132 * appended to the end of the list.
133 *
134 * \param[in,out] d The list.
135 * \param[in] val The value to insert.
136 *
137 * \return Pointer to M_llist_str_node_t container object of new node on success,
138 * otherwise NULL.
139 *
140 * \see m_llist_str_insert_first
141 */
143
144
145/*! Insert a value into the list as the first node.
146 *
147 * Only applies to unsorted lists.
148 *
149 * \param[in,out] d The list.
150 * \param[in] val The value to insert.
151 *
152 * \return Pointer to M_llist_str_node_t container object of new node on success,
153 * otherwise NULL.
154 *
155 * \see M_llist_str_insert
156 */
158
159
160/*! Insert a value into the list before a given node.
161 *
162 * Only applies to unsorted lists.
163 *
164 * \param[in,out] n The node to insert before. Cannot be NULL.
165 * \param[in] val The value to insert.
166 *
167 * \return Pointer to M_llist_str_node_t container object of new node on success,
168 * otherwise NULL.
169 *
170 * \see M_llist_str_insert_after
171 */
173
174
175/*! Insert a value into the list after a given node.
176 *
177 * Only applies to unsorted lists.
178 *
179 * \param[in,out] n The node to insert after. Cannot be NULL.
180 * \param[in] val The value to insert.
181 *
182 * \return Pointer to M_llist_str_node_t container object of new node on success,
183 * otherwise NULL.
184 *
185 * \see M_llist_str_insert_before
186 */
188
189
190/*! Set the node as the first node in the circular list.
191 *
192 * Only applies to circular lists.
193 *
194 * \param[in] n The node that should be considered first.
195 */
197
198
199/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
200
201/*! Move a node before another node in the list.
202 *
203 * \param[in] move The node to move.
204 * \param[in] before The node that move should be placed before.
205 *
206 * \return M_TRUE on sucess, otherwise M_FALSE.
207 */
209
210
211/*! Move a node after another node in the list.
212 *
213 * \param[in] move The node to move.
214 * \param[in] after The node that move should be placed after.
215 *
216 * \return M_TRUE on sucess, otherwise M_FALSE.
217 */
219
220
221/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
222
223/*! The length of the list.
224 *
225 * \param[in] d The list.
226 *
227 * \return the length of the list.
228 */
229M_API size_t M_llist_str_len(const M_llist_str_t *d);
230
231
232/*! Count the number of times a value occurs in the list.
233 *
234 * \param[in] d The list.
235 * \param[in] val The value to search for.
236 * \param[in] type M_llist_str_match_type_t type of how the val should be matched.
237 * valid values are:
238 * - M_LLIST_STR_MATCH_VAL
239 * - M_LLIST_STR_MATCH_PTR
240 *
241 * \return The number of times val appears in the list.
242 */
243M_API size_t M_llist_str_count(const M_llist_str_t *d, const char *val, M_uint32 type);
244
245
246/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
247
248/*! Get the first node in the list.
249 *
250 * \param[in] d The list.
251 *
252 * \return Node or NULL.
253 *
254 * \see M_llist_str_last
255 * \see M_llist_str_find
256 */
258
259
260/*! Get the last node in the list.
261 *
262 * \param[in] d The list.
263 *
264 * \return Node or NULL.
265 *
266 * \see M_llist_str_first
267 * \see M_llist_str_find
268 */
270
271
272/*! Find a node for the given value in the list.
273 *
274 * \param[in] d The list.
275 * \param[in] val The value to search for.
276 * \param[in] type M_llist_str_match_type_t type of how the val should be matched.
277 * valid values are:
278 * - M_LLIST_STR_MATCH_VAL
279 * - M_LLIST_STR_MATCH_PTR
280 *
281 * \return Node or NULL.
282 *
283 * \see M_llist_str_first
284 * \see M_llist_str_last
285 */
286M_API M_llist_str_node_t *M_llist_str_find(const M_llist_str_t *d, const char *val, M_uint32 type);
287
288
289/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
290
291/*! Take the node from the list and return its value.
292 *
293 * The element will be removed from the list and its value returned. The caller is
294 * responsible for freeing the value.
295 *
296 * \param[in] n The node.
297 *
298 * \return The node's value.
299 *
300 * \see M_llist_str_node_val
301 */
303
304
305/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
306
307/*! Remove a node from the list.
308 *
309 * The value will be free'd using the value_free callback.
310 *
311 * \param[in] n The node.
312 *
313 * \return M_TRUE on success otherwise M_FALSE.
314 *
315 * \see M_llist_str_remove_val
316 */
318
319
320/*! Remove node(s) from the list matching a given value.
321 *
322 * The value will be free'd using the value_free callback.
323 *
324 * \param[in,out] d The list.
325 * \param[in] val The value to search for.
326 * \param[in] type M_llist_str_match_type_t type of how the val should be matched.
327 * valid values are:
328 * - M_LLIST_STR_MATCH_VAL (removes one/first)
329 * - M_LLIST_STR_MATCH_PTR (removes one/first)
330 * - M_LLIST_STR_MATCH_ALL
331 *
332 * \return M_TRUE on success otherwise M_FALSE.
333 *
334 * \see M_llist_str_remove_node
335 */
336M_API size_t M_llist_str_remove_val(M_llist_str_t *d, const char *val, M_uint32 type);
337
338
339/*! Remove duplicate values from the list.
340 *
341 * \param[in] d The list.
342 */
344
345
346/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
347
348/*! Get the next node, the one after a given node.
349 *
350 * \param[in] n The node.
351 *
352 * \return Node or NULL.
353 *
354 * \see M_llist_str_node_prev
355 */
357
358
359/*! Get the previous node, the one before a given node.
360 *
361 * \param[in] n The node.
362 *
363 * \return Node or NULL.
364 *
365 * \see M_llist_str_node_next
366 */
368
369
370/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
371
372/*! Get the value for a node.
373 *
374 * \param[in] n The node.
375 *
376 * \return The node's value.
377 *
378 * \see M_llist_str_take_node
379 */
380M_API const char *M_llist_str_node_val(const M_llist_str_node_t *n);
381
382
383/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
384
385/*! Duplicate an existing list. Will copy all elements of the list.
386 *
387 * \param[in] d list to duplicate.
388 *
389 * \return New list.
390 */
392
393
394/*! Merge two lists together.
395 *
396 * The second (src) list will be destroyed automatically upon completion of this function. Any value pointers for the
397 * list will be directly copied over to the destination list, they will not be duplicated.
398 *
399 * \param[in,out] dest Pointer by reference to the list receiving the values.
400 * if this is NULL, the pointer will simply be switched out for src.
401 * \param[in,out] src Pointer to the list giving up its values.
402 * \param[in] include_duplicates When M_TRUE any values in 'dest' that also exist in
403 * 'src' will be included in 'dest'. When M_FALSE any
404 * duplicate values will not be added to 'dest'.
405 */
406M_API void M_llist_str_merge(M_llist_str_t **dest, M_llist_str_t *src, M_bool include_duplicates) M_FREE(2);
407
408/*! @} */
409
410__END_DECLS
411
412#endif /* __M_LLIST_STR_H__ */
413
void M_llist_str_set_first(M_llist_str_node_t *n)
M_llist_str_node_t * M_llist_str_insert_first(M_llist_str_t *d, const char *val)
M_llist_str_node_t * M_llist_str_insert_after(M_llist_str_node_t *n, const char *val)
struct M_llist_str_node M_llist_str_node_t
Definition: m_llist_str.h:69
char * M_llist_str_take_node(M_llist_str_node_t *n)
void M_llist_str_merge(M_llist_str_t **dest, M_llist_str_t *src, M_bool include_duplicates) M_FREE(2)
M_llist_str_t * M_llist_str_duplicate(const M_llist_str_t *d) M_MALLOC
size_t M_llist_str_remove_val(M_llist_str_t *d, const char *val, M_uint32 type)
M_bool M_llist_str_move_after(M_llist_str_node_t *move, M_llist_str_node_t *after)
size_t M_llist_str_count(const M_llist_str_t *d, const char *val, M_uint32 type)
const char * M_llist_str_node_val(const M_llist_str_node_t *n)
M_bool M_llist_str_change_sorting(M_llist_str_t *d, M_sort_compar_t equality_cb, void *equality_thunk)
M_llist_str_flags_t
Definition: m_llist_str.h:73
M_bool M_llist_str_remove_node(M_llist_str_node_t *n)
void M_llist_str_remove_duplicates(M_llist_str_t *d)
M_llist_str_node_t * M_llist_str_insert(M_llist_str_t *d, const char *val)
M_llist_str_node_t * M_llist_str_insert_before(M_llist_str_node_t *n, const char *val)
M_llist_str_node_t * M_llist_str_last(const M_llist_str_t *d)
struct M_llist_str M_llist_str_t
Definition: m_llist_str.h:63
M_llist_str_node_t * M_llist_str_first(const M_llist_str_t *d)
M_llist_str_t * M_llist_str_create(M_uint32 flags) M_MALLOC
M_llist_str_node_t * M_llist_str_find(const M_llist_str_t *d, const char *val, M_uint32 type)
M_llist_str_node_t * M_llist_str_node_next(const M_llist_str_node_t *n)
M_llist_str_match_type_t
Definition: m_llist_str.h:83
M_llist_str_node_t * M_llist_str_node_prev(const M_llist_str_node_t *n)
size_t M_llist_str_len(const M_llist_str_t *d)
M_bool M_llist_str_move_before(M_llist_str_node_t *move, M_llist_str_node_t *before)
void M_llist_str_destroy(M_llist_str_t *d) M_FREE(1)
@ M_LLIST_STR_CASECMP
Definition: m_llist_str.h:77
@ M_LLIST_STR_NONE
Definition: m_llist_str.h:74
@ M_LLIST_STR_SORTDESC
Definition: m_llist_str.h:76
@ M_LLIST_STR_CIRCULAR
Definition: m_llist_str.h:78
@ M_LLIST_STR_SORTASC
Definition: m_llist_str.h:75
@ M_LLIST_STR_MATCH_ALL
Definition: m_llist_str.h:86
@ M_LLIST_STR_MATCH_PTR
Definition: m_llist_str.h:85
@ M_LLIST_STR_MATCH_VAL
Definition: m_llist_str.h:84
int(* M_sort_compar_t)(const void *arg1, const void *arg2, void *thunk)
Definition: m_sort.h:78