Mstdlib-1.24.0
m_llist_u64.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_U64_H__
25#define __M_LLIST_U64_H__
26
27/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
28
29#include <mstdlib/base/m_defs.h>
30#include <mstdlib/base/m_types.h>
31
32/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
33
34__BEGIN_DECLS
35
36/*! \addtogroup m_llist_u64 Linked List - uint64
37 * \ingroup m_llist
38 *
39 * Linked list for storing values.
40 *
41 * The list can be used in multiple ways:
42 * - Unsorted.
43 * - Sorted.
44 * - Queue (FIFO) (really just unsorted).
45 * - Priority Queue (really just sorted).
46 *
47 * A linked list is not indexable. Iteration and find are supported.
48 *
49 * Sorted notes:
50 * - Sorting is implemented as a skip list. This should provide near O(long(n)) performance.
51 * Performance nearing a sorted M_list_t.
52 * - Sorting is stable. If an element with a matching value is already in the list then it
53 * will be inserted after. Find will always find the first matching element in the list.
54 *
55 * @{
56 */
57
58struct M_llist_u64;
59/* Currently a direct map to M_list private opaque type,
60 * simply using casting to prevent the 'wrap' overhead of mallocing when it
61 * is not necessary */
62typedef struct M_llist_u64 M_llist_u64_t;
63
64struct M_llist_u64_node;
65/* Currently a direct map to M_list private opaque type,
66 * simply using casting to prevent the 'wrap' overhead of mallocing when it
67 * is not necessary */
68typedef struct M_llist_u64_node M_llist_u64_node_t;
69
70
71/*! Flags for controlling the behavior of the list. */
72typedef enum {
73 M_LLIST_U64_NONE = 0, /*!< List mode. */
74 M_LLIST_U64_SORTASC = 1 << 0, /*!< Sort asc. */
75 M_LLIST_U64_SORTDESC = 1 << 1, /*!< Sort desc. */
76 M_LLIST_U64_CIRCULAR = 1 << 2 /*!< Circular list. */
78
79
80/*! Type of matching that should be used when searching/modifying a value in the list. */
81typedef enum {
82 M_LLIST_U64_MATCH_VAL = 0, /*!< Match based on the value. */
83 M_LLIST_U64_MATCH_ALL = 1 << 0 /*!< Include all instances. */
85
86
87/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
88
89/*! Create a new list.
90 *
91 * A list is a linked list. The list can be, optionally, kept in sorted
92 * order. The sorted order is determined by the flags.
93 *
94 * \param[in] flags M_llist_u64_flags_t flags controlling behavior.
95 *
96 * \return Allocated linked list.
97 *
98 * \see M_llist_u64_destroy
99 */
100M_API M_llist_u64_t *M_llist_u64_create(M_uint32 flags) M_MALLOC;
101
102
103/*! Destroy the list.
104 *
105 * \param[in] d The llist to destory.
106 */
107M_API void M_llist_u64_destroy(M_llist_u64_t *d) M_FREE(1);
108
109
110/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
111
112/*! Insert a value into the list.
113 *
114 * If sorted the value will be inserted in sorted order. Otherwise it will be
115 * appended to the end of the list.
116 *
117 * \param[in,out] d The list.
118 * \param[in] val The value to insert.
119 *
120 * \return Pointer to M_llist_u64_node_t container object of new node on success,
121 * otherwise NULL.
122 *
123 * \see m_llist_u64_insert_first
124 */
126
127
128/*! Insert a value into the list as the first node.
129 *
130 * Only applies to unsorted lists.
131 *
132 * \param[in,out] d The list.
133 * \param[in] val The value to insert.
134 *
135 * \return Pointer to M_llist_u64_node_t container object of new node on success,
136 * otherwise NULL.
137 *
138 * \see M_llist_u64_insert
139 */
141
142
143/*! Insert a value into the list before a given node.
144 *
145 * Only applies to unsorted lists.
146 *
147 * \param[in,out] n The node to insert before. Cannot be NULL.
148 * \param[in] val The value to insert.
149 *
150 * \return Pointer to M_llist_u64_node_t container object of new node on success,
151 * otherwise NULL.
152 *
153 * \see M_llist_u64_insert_after
154 */
156
157
158/*! Insert a value into the list after a given node.
159 *
160 * Only applies to unsorted lists.
161 *
162 * \param[in,out] n The node to insert after. Cannot be NULL.
163 * \param[in] val The value to insert.
164 *
165 * \return Pointer to M_llist_u64_node_t container object of new node on success,
166 * otherwise NULL.
167 *
168 * \see M_llist_u64_insert_before
169 */
171
172
173/*! Set the node as the first node in the circular list.
174 *
175 * Only applies to circular lists.
176 *
177 * \param[in] n The node that should be considered first.
178 */
180
181
182/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
183
184/*! Move a node before another node in the list.
185 *
186 * \param[in] move The node to move.
187 * \param[in] before The node that move should be placed before.
188 *
189 * \return M_TRUE on sucess, otherwise M_FALSE.
190 */
192
193
194/*! Move a node after another node in the list.
195 *
196 * \param[in] move The node to move.
197 * \param[in] after The node that move should be placed after.
198 *
199 * \return M_TRUE on sucess, otherwise M_FALSE.
200 */
202
203
204/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
205
206/*! The length of the list.
207 *
208 * \param[in] d The list.
209 *
210 * \return the length of the list.
211 */
212M_API size_t M_llist_u64_len(const M_llist_u64_t *d);
213
214
215/*! Count the number of times a value occurs in the list.
216 *
217 * \param[in] d The list.
218 * \param[in] val The value to search for.
219 *
220 * \return The number of times val appears in the list.
221 */
222M_API size_t M_llist_u64_count(const M_llist_u64_t *d, M_uint64 val);
223
224
225/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
226
227/*! Get the first node in the list.
228 *
229 * \param[in] d The list.
230 *
231 * \return Node or NULL.
232 *
233 * \see M_llist_u64_last
234 * \see M_llist_u64_find
235 */
237
238
239/*! Get the last node in the list.
240 *
241 * \param[in] d The list.
242 *
243 * \return Node or NULL.
244 *
245 * \see M_llist_u64_first
246 * \see M_llist_u64_find
247 */
249
250
251/*! Find a node for the given value in the list.
252 *
253 * \param[in] d The list.
254 * \param[in] val The value to search for.
255 *
256 * \return Node or NULL.
257 *
258 * \see M_llist_u64_first
259 * \see M_llist_u64_last
260 */
261M_API M_llist_u64_node_t *M_llist_u64_find(const M_llist_u64_t *d, M_uint64 val);
262
263
264/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
265
266/*! Take the node from the list and return its value.
267 *
268 * The element will be removed from the list and its value returned. The caller is
269 * responsible for freeing the value.
270 *
271 * \param[in] n The node.
272 *
273 * \return The node's value.
274 *
275 * \see M_llist_u64_node_val
276 */
278
279
280/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
281
282/*! Remove a node from the list.
283 *
284 * The value will be free'd using the value_free callback.
285 *
286 * \param[in] n The node.
287 *
288 * \return M_TRUE on success otherwise M_FALSE.
289 *
290 * \see M_llist_u64_remove_val
291 */
293
294
295/*! Remove node(s) from the list matching a given value.
296 *
297 * The value will be free'd using the value_free callback.
298 *
299 * \param[in,out] d The list.
300 * \param[in] val The value to search for.
301 * \param[in] type M_llist_u64_match_type_t type of how the val should be matched.
302 * valid values are:
303 * - M_LLIST_U64_MATCH_VAL (removes one/first)
304 * - M_LLIST_U64_MATCH_ALL
305 *
306 * \return M_TRUE on success otherwise M_FALSE.
307 *
308 * \see M_llist_u64_remove_node
309 */
310M_API size_t M_llist_u64_remove_val(M_llist_u64_t *d, M_uint64 val, M_uint32 type);
311
312
313/*! Remove duplicate values from the list.
314 *
315 * \param[in] d The list.
316 */
318
319
320/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
321
322/*! Get the next node, the one after a given node.
323 *
324 * \param[in] n The node.
325 *
326 * \return Node or NULL.
327 *
328 * \see M_llist_u64_node_prev
329 */
331
332
333/*! Get the previous node, the one before a given node.
334 *
335 * \param[in] n The node.
336 *
337 * \return Node or NULL.
338 *
339 * \see M_llist_u64_node_next
340 */
342
343
344/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
345
346/*! Get the value for a node.
347 *
348 * \param[in] n The node.
349 *
350 * \return The node's value.
351 *
352 * \see M_llist_u64_take_node
353 */
355
356
357/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
358
359/*! Duplicate an existing list. Will copy all elements of the list.
360 *
361 * \param[in] d list to duplicate.
362 *
363 * \return New list.
364 */
366
367
368/*! Merge two lists together.
369 *
370 * The second (src) list will be destroyed automatically upon completion of this function. Any value pointers for the
371 * list will be directly copied over to the destination list, they will not be duplicated.
372 *
373 * \param[in,out] dest Pointer by reference to the list receiving the values.
374 * if this is NULL, the pointer will simply be switched out for src.
375 * \param[in,out] src Pointer to the list giving up its values.
376 * \param[in] include_duplicates When M_TRUE any values in 'dest' that also exist in
377 * 'src' will be included in 'dest'. When M_FALSE any
378 * duplicate values will not be added to 'dest'.
379 */
380M_API void M_llist_u64_merge(M_llist_u64_t **dest, M_llist_u64_t *src, M_bool include_duplicates) M_FREE(2);
381
382/*! @} */
383
384__END_DECLS
385
386#endif /* __M_LLIST_U64_H__ */
M_bool M_llist_u64_remove_node(M_llist_u64_node_t *n)
size_t M_llist_u64_remove_val(M_llist_u64_t *d, M_uint64 val, M_uint32 type)
M_bool M_llist_u64_move_after(M_llist_u64_node_t *move, M_llist_u64_node_t *after)
size_t M_llist_u64_len(const M_llist_u64_t *d)
M_llist_u64_t * M_llist_u64_create(M_uint32 flags) M_MALLOC
struct M_llist_u64 M_llist_u64_t
Definition: m_llist_u64.h:62
M_llist_u64_node_t * M_llist_u64_insert_first(M_llist_u64_t *d, M_uint64 val)
void M_llist_u64_set_first(M_llist_u64_node_t *n)
M_uint64 M_llist_u64_take_node(M_llist_u64_node_t *n)
M_llist_u64_match_type_t
Definition: m_llist_u64.h:81
void M_llist_u64_remove_duplicates(M_llist_u64_t *d)
M_llist_u64_node_t * M_llist_u64_insert(M_llist_u64_t *d, M_uint64 val)
M_llist_u64_node_t * M_llist_u64_find(const M_llist_u64_t *d, M_uint64 val)
M_llist_u64_flags_t
Definition: m_llist_u64.h:72
M_llist_u64_node_t * M_llist_u64_node_next(const M_llist_u64_node_t *n)
M_llist_u64_node_t * M_llist_u64_first(const M_llist_u64_t *d)
void M_llist_u64_merge(M_llist_u64_t **dest, M_llist_u64_t *src, M_bool include_duplicates) M_FREE(2)
M_llist_u64_node_t * M_llist_u64_last(const M_llist_u64_t *d)
M_uint64 M_llist_u64_node_val(const M_llist_u64_node_t *n)
M_bool M_llist_u64_move_before(M_llist_u64_node_t *move, M_llist_u64_node_t *before)
M_llist_u64_node_t * M_llist_u64_insert_before(M_llist_u64_node_t *n, M_uint64 val)
M_llist_u64_t * M_llist_u64_duplicate(const M_llist_u64_t *d) M_MALLOC
M_llist_u64_node_t * M_llist_u64_insert_after(M_llist_u64_node_t *n, M_uint64 val)
size_t M_llist_u64_count(const M_llist_u64_t *d, M_uint64 val)
void M_llist_u64_destroy(M_llist_u64_t *d) M_FREE(1)
M_llist_u64_node_t * M_llist_u64_node_prev(const M_llist_u64_node_t *n)
struct M_llist_u64_node M_llist_u64_node_t
Definition: m_llist_u64.h:68
@ M_LLIST_U64_MATCH_ALL
Definition: m_llist_u64.h:83
@ M_LLIST_U64_MATCH_VAL
Definition: m_llist_u64.h:82
@ M_LLIST_U64_SORTDESC
Definition: m_llist_u64.h:75
@ M_LLIST_U64_SORTASC
Definition: m_llist_u64.h:74
@ M_LLIST_U64_CIRCULAR
Definition: m_llist_u64.h:76
@ M_LLIST_U64_NONE
Definition: m_llist_u64.h:73