UNIXworkcode

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 #ifdef __cplusplus 44 extern "C" { 45 #endif 46 47 /** 48 * Allocates a linked list with a lookup-map for storing elements with @p elem_size bytes each. 49 * 50 * If @p elem_size is #CX_STORE_POINTERS, the created list stores pointers instead of 51 * copies of the added elements, and the compare function will be automatically set 52 * to cx_cmp_ptr(). 53 * 54 * After creating the list, it can also be used as a map after converting the pointer 55 * to a CxMap pointer with cxKvListAsMap(). 56 * When you want to use the list interface again, you can also convert the map pointer back 57 * with cxKvListAsList(). 58 * 59 * @param allocator the allocator for allocating the list nodes 60 * (if @c NULL, the cxDefaultAllocator will be used) 61 * @param elem_size the size of each element in bytes 62 * @return the created list 63 * @see cxKvListAsMap() 64 * @see cxKvListAsList() 65 */ 66 cx_attr_nodiscard cx_attr_malloc cx_attr_dealloc(cxListFree, 1) 67 CX_EXPORT CxList *cxKvListCreate(const CxAllocator *allocator, 68 size_t elem_size); 69 70 /** 71 * Allocates a linked list with a lookup-map for storing elements with @p elem_size bytes each. 72 * 73 * If @p elem_size is #CX_STORE_POINTERS, the created list stores pointers instead of 74 * copies of the added elements, and the compare function will be automatically set 75 * to cx_cmp_ptr(). 76 * 77 * This function creates the list with cxKvListCreate() and immediately applies 78 * cxKvListAsMap(). If you want to use the returned object as a list, you can call 79 * cxKvListAsList() later. 80 * 81 * @param allocator the allocator for allocating the list nodes 82 * (if @c NULL, the cxDefaultAllocator will be used) 83 * @param elem_size the size of each element in bytes 84 * @return the created list wrapped into the CxMap interface 85 * @see cxKvListAsMap() 86 * @see cxKvListAsList() 87 */ 88 cx_attr_nodiscard cx_attr_malloc cx_attr_dealloc(cxMapFree, 1) 89 CX_EXPORT CxMap *cxKvListCreateAsMap(const CxAllocator *allocator, 90 size_t elem_size); 91 92 /** 93 * Converts a map pointer belonging to a key-value-List back to the original list pointer. 94 * 95 * @param map a map pointer that was returned by a call to cxKvListAsMap() 96 * @return the original list pointer 97 */ 98 cx_attr_nodiscard cx_attr_nonnull cx_attr_returns_nonnull 99 CX_EXPORT CxList *cxKvListAsList(CxMap *map); 100 101 /** 102 * Converts a map pointer belonging to a key-value-List back to the original list pointer. 103 * 104 * @param list a list created by cxKvListCreate() 105 * @return a map pointer that lets you use the list as if it was a map 106 */ 107 cx_attr_nodiscard cx_attr_nonnull cx_attr_returns_nonnull 108 CX_EXPORT CxMap *cxKvListAsMap(CxList *list); 109 110 /** 111 * Sets or updates the key of a list item. 112 * 113 * This is, for example, useful when you have inserted an element using the CxList interface, 114 * and now you want to associate this element with a key. 115 * 116 * @param list the list 117 * @param index the index of the element in the list 118 * @param key the key 119 * @retval zero success 120 * @retval non-zero memory allocation failure or the index is out of bounds 121 * @see cxKvListSetKey() 122 */ 123 cx_attr_nonnull 124 CX_EXPORT int cx_kv_list_set_key(CxList *list, size_t index, CxHashKey key); 125 126 /** 127 * Inserts an item into the list at the specified index and associates it with the specified key. 128 * 129 * @param list the list 130 * @param index the index the inserted element shall have 131 * @param key the key 132 * @param value the value 133 * @retval zero success 134 * @retval non-zero memory allocation failure or the index is out of bounds 135 * @see cxKvListInsert() 136 */ 137 cx_attr_nonnull 138 CX_EXPORT int cx_kv_list_insert(CxList *list, size_t index, CxHashKey key, void *value); 139 140 /** 141 * Sets or updates the key of a list item. 142 * 143 * This is, for example, useful when you have inserted an element using the CxList interface, 144 * and now you want to associate this element with a key. 145 * 146 * @param list (@c CxList*) the list 147 * @param index (@c size_t) the index of the element in the list 148 * @param key (any supported key type) the key 149 * @retval zero success 150 * @retval non-zero memory allocation failure or the index is out of bounds 151 * @see CX_HASH_KEY() 152 */ 153 #define cxKvListSetKey(list, index, key) cx_kv_list_set_key(list, index, CX_HASH_KEY(key)) 154 155 /** 156 * Inserts an item into the list at the specified index and associates it with the specified key. 157 * 158 * @param list (@c CxList*) the list 159 * @param index (@c size_t) the index the inserted element shall have 160 * @param key (any supported key type) the key 161 * @param value (@c void*) the value 162 * @retval zero success 163 * @retval non-zero memory allocation failure or the index is out of bounds 164 * @see CX_HASH_KEY() 165 */ 166 #define cxKvListInsert(list, index, key, value) cx_kv_list_insert(list, index, CX_HASH_KEY(key), value) 167 168 169 /** 170 * Removes the key of a list item. 171 * 172 * This can be useful if you want to explicitly remove an item from the lookup map. 173 * 174 * If no key is associated with the item, nothing happens, and this function returns zero. 175 * 176 * @param list the list 177 * @param index the index of the element in the list 178 * @retval zero success 179 * @retval non-zero the index is out of bounds 180 */ 181 cx_attr_nonnull 182 CX_EXPORT int cxKvListRemoveKey(CxList *list, size_t index); 183 184 /** 185 * Returns the key of a list item. 186 * 187 * @param list the list 188 * @param index the index of the element in the list 189 * @return a pointer to the key or @c NULL when the index is out of bounds or the item does not have a key 190 */ 191 cx_attr_nonnull 192 CX_EXPORT const CxHashKey *cxKvListGetKey(CxList *list, size_t index); 193 194 /** 195 * Adds an item into the list and associates it with the specified key. 196 * 197 * @param list (@c CxList*) the list 198 * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key 199 * @param value (@c void*) the value 200 * @retval zero success 201 * @retval non-zero memory allocation failure 202 */ 203 #define cxKvListAdd(list, key, value) cxKvListInsert(list, (list)->collection.size, key, value) 204 205 #ifdef __cplusplus 206 } // extern "C" 207 #endif 208 209 #endif // UCX_KV_LIST_H 210