Wed, 31 Dec 2025 16:40:12 +0100
update ucx to version 4.0
| 845 | 1 | /* |
| 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. | |
| 3 | * | |
| 4 | * Copyright 2025 Mike Becker, Olaf Wintermann All rights reserved. | |
| 5 | * | |
| 6 | * Redistribution and use in source and binary forms, with or without | |
| 7 | * modification, are permitted provided that the following conditions are met: | |
| 8 | * | |
| 9 | * 1. Redistributions of source code must retain the above copyright | |
| 10 | * notice, this list of conditions and the following disclaimer. | |
| 11 | * | |
| 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
| 13 | * notice, this list of conditions and the following disclaimer in the | |
| 14 | * documentation and/or other materials provided with the distribution. | |
| 15 | * | |
| 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
| 17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
| 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE | |
| 20 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
| 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
| 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
| 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
| 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
| 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| 26 | * POSSIBILITY OF SUCH DAMAGE. | |
| 27 | */ | |
| 28 | /** | |
| 29 | * @file kv_list.h | |
| 30 | * @brief Linked list implementation with key/value-lookup. | |
| 31 | * @author Mike Becker | |
| 32 | * @author Olaf Wintermann | |
| 33 | * @copyright 2-Clause BSD License | |
| 34 | */ | |
| 35 | ||
| 36 | #ifndef UCX_KV_LIST_H | |
| 37 | #define UCX_KV_LIST_H | |
| 38 | ||
| 39 | #include "common.h" | |
| 40 | #include "list.h" | |
| 41 | #include "map.h" | |
| 42 | ||
| 43 | /** | |
| 44 | * Allocates a linked list with a lookup-map for storing elements with @p elem_size bytes each. | |
| 45 | * | |
| 46 | * If @p elem_size is #CX_STORE_POINTERS, the created list stores pointers instead of | |
| 47 | * copies of the added elements, and the compare function will be automatically set | |
| 1016 | 48 | * to cx_cmp_ptr(). |
| 845 | 49 | * |
| 50 | * After creating the list, it can also be used as a map after converting the pointer | |
| 51 | * to a CxMap pointer with cxKvListAsMap(). | |
| 52 | * When you want to use the list interface again, you can also convert the map pointer back | |
| 53 | * with cxKvListAsList(). | |
| 54 | * | |
| 55 | * @param allocator the allocator for allocating the list nodes | |
| 56 | * (if @c NULL, the cxDefaultAllocator will be used) | |
| 57 | * @param elem_size the size of each element in bytes | |
| 58 | * @return the created list | |
| 59 | * @see cxKvListAsMap() | |
| 60 | * @see cxKvListAsList() | |
| 61 | */ | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1016
diff
changeset
|
62 | CX_EXTERN CX_NODISCARD CX_MALLOC CX_DEALLOC(cxListFree, 1) |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1016
diff
changeset
|
63 | CxList *cxKvListCreate(const CxAllocator *allocator, |
| 1016 | 64 | size_t elem_size); |
| 845 | 65 | |
| 66 | /** | |
| 67 | * Allocates a linked list with a lookup-map for storing elements with @p elem_size bytes each. | |
| 68 | * | |
| 69 | * If @p elem_size is #CX_STORE_POINTERS, the created list stores pointers instead of | |
| 70 | * copies of the added elements, and the compare function will be automatically set | |
| 1016 | 71 | * to cx_cmp_ptr(). |
| 845 | 72 | * |
| 73 | * This function creates the list with cxKvListCreate() and immediately applies | |
| 74 | * cxKvListAsMap(). If you want to use the returned object as a list, you can call | |
| 75 | * cxKvListAsList() later. | |
| 76 | * | |
| 77 | * @param allocator the allocator for allocating the list nodes | |
| 78 | * (if @c NULL, the cxDefaultAllocator will be used) | |
| 79 | * @param elem_size the size of each element in bytes | |
| 80 | * @return the created list wrapped into the CxMap interface | |
| 81 | * @see cxKvListAsMap() | |
| 82 | * @see cxKvListAsList() | |
| 83 | */ | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1016
diff
changeset
|
84 | CX_EXTERN CX_NODISCARD CX_MALLOC CX_DEALLOC(cxMapFree, 1) |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1016
diff
changeset
|
85 | CxMap *cxKvListCreateAsMap(const CxAllocator *allocator, |
| 1016 | 86 | size_t elem_size); |
| 845 | 87 | |
| 88 | /** | |
| 89 | * Converts a map pointer belonging to a key-value-List back to the original list pointer. | |
| 90 | * | |
| 91 | * @param map a map pointer that was returned by a call to cxKvListAsMap() | |
| 92 | * @return the original list pointer | |
| 93 | */ | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1016
diff
changeset
|
94 | CX_EXTERN CX_NODISCARD CX_NONNULL CX_RETURNS_NONNULL |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1016
diff
changeset
|
95 | CxList *cxKvListAsList(CxMap *map); |
| 845 | 96 | |
| 97 | /** | |
| 98 | * Converts a map pointer belonging to a key-value-List back to the original list pointer. | |
| 99 | * | |
| 1016 | 100 | * @param list a list created by cxKvListCreate() |
| 845 | 101 | * @return a map pointer that lets you use the list as if it was a map |
| 102 | */ | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1016
diff
changeset
|
103 | CX_EXTERN CX_NODISCARD CX_NONNULL CX_RETURNS_NONNULL |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1016
diff
changeset
|
104 | CxMap *cxKvListAsMap(CxList *list); |
| 845 | 105 | |
| 106 | /** | |
| 107 | * Sets or updates the key of a list item. | |
| 108 | * | |
| 109 | * This is, for example, useful when you have inserted an element using the CxList interface, | |
| 110 | * and now you want to associate this element with a key. | |
| 111 | * | |
| 112 | * @param list the list | |
| 113 | * @param index the index of the element in the list | |
| 114 | * @param key the key | |
| 115 | * @retval zero success | |
| 116 | * @retval non-zero memory allocation failure or the index is out of bounds | |
| 117 | * @see cxKvListSetKey() | |
| 118 | */ | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1016
diff
changeset
|
119 | CX_EXTERN CX_NONNULL |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1016
diff
changeset
|
120 | int cx_kv_list_set_key(CxList *list, size_t index, CxHashKey key); |
| 845 | 121 | |
| 122 | /** | |
| 123 | * Inserts an item into the list at the specified index and associates it with the specified key. | |
| 124 | * | |
| 125 | * @param list the list | |
| 126 | * @param index the index the inserted element shall have | |
| 127 | * @param key the key | |
| 128 | * @param value the value | |
| 129 | * @retval zero success | |
| 130 | * @retval non-zero memory allocation failure or the index is out of bounds | |
| 131 | * @see cxKvListInsert() | |
| 132 | */ | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1016
diff
changeset
|
133 | CX_EXTERN CX_NONNULL |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1016
diff
changeset
|
134 | int cx_kv_list_insert(CxList *list, size_t index, CxHashKey key, void *value); |
| 845 | 135 | |
| 136 | /** | |
| 137 | * Sets or updates the key of a list item. | |
| 138 | * | |
| 139 | * This is, for example, useful when you have inserted an element using the CxList interface, | |
| 140 | * and now you want to associate this element with a key. | |
| 141 | * | |
| 142 | * @param list (@c CxList*) the list | |
| 143 | * @param index (@c size_t) the index of the element in the list | |
| 144 | * @param key (any supported key type) the key | |
| 145 | * @retval zero success | |
| 146 | * @retval non-zero memory allocation failure or the index is out of bounds | |
| 147 | * @see CX_HASH_KEY() | |
| 148 | */ | |
| 149 | #define cxKvListSetKey(list, index, key) cx_kv_list_set_key(list, index, CX_HASH_KEY(key)) | |
| 150 | ||
| 151 | /** | |
| 152 | * Inserts an item into the list at the specified index and associates it with the specified key. | |
| 153 | * | |
| 154 | * @param list (@c CxList*) the list | |
| 155 | * @param index (@c size_t) the index the inserted element shall have | |
| 156 | * @param key (any supported key type) the key | |
| 157 | * @param value (@c void*) the value | |
| 158 | * @retval zero success | |
| 159 | * @retval non-zero memory allocation failure or the index is out of bounds | |
| 160 | * @see CX_HASH_KEY() | |
| 161 | */ | |
| 162 | #define cxKvListInsert(list, index, key, value) cx_kv_list_insert(list, index, CX_HASH_KEY(key), value) | |
| 163 | ||
| 164 | /** | |
| 165 | * Removes the key of a list item. | |
| 166 | * | |
| 167 | * This can be useful if you want to explicitly remove an item from the lookup map. | |
| 168 | * | |
| 169 | * If no key is associated with the item, nothing happens, and this function returns zero. | |
| 170 | * | |
| 171 | * @param list the list | |
| 172 | * @param index the index of the element in the list | |
| 173 | * @retval zero success | |
| 174 | * @retval non-zero the index is out of bounds | |
| 175 | */ | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1016
diff
changeset
|
176 | CX_EXTERN CX_NONNULL |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1016
diff
changeset
|
177 | int cxKvListRemoveKey(CxList *list, size_t index); |
| 845 | 178 | |
| 179 | /** | |
| 180 | * Returns the key of a list item. | |
| 181 | * | |
| 182 | * @param list the list | |
| 183 | * @param index the index of the element in the list | |
| 184 | * @return a pointer to the key or @c NULL when the index is out of bounds or the item does not have a key | |
| 185 | */ | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1016
diff
changeset
|
186 | CX_EXTERN CX_NONNULL CX_NODISCARD |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1016
diff
changeset
|
187 | const CxHashKey *cxKvListGetKey(CxList *list, size_t index); |
| 845 | 188 | |
| 189 | /** | |
| 190 | * Adds an item into the list and associates it with the specified key. | |
| 191 | * | |
| 192 | * @param list (@c CxList*) the list | |
| 193 | * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key | |
| 194 | * @param value (@c void*) the value | |
| 195 | * @retval zero success | |
| 196 | * @retval non-zero memory allocation failure | |
| 197 | */ | |
| 198 | #define cxKvListAdd(list, key, value) cxKvListInsert(list, (list)->collection.size, key, value) | |
| 199 | ||
| 200 | #endif // UCX_KV_LIST_H |