Sun, 24 Aug 2025 17:11:53 +0200
create a header file for the new key-value-lists
kick-off for issue #461
/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /** * @file kv_list.h * @brief Linked list implementation with key/value-lookup. * @author Mike Becker * @author Olaf Wintermann * @copyright 2-Clause BSD License */ #ifndef UCX_KV_LIST_H #define UCX_KV_LIST_H #include "common.h" #include "list.h" #include "map.h" #ifdef __cplusplus extern "C" { #endif /** * Allocates a linked list with a lookup-map for storing elements with @p elem_size bytes each. * * If @p elem_size is #CX_STORE_POINTERS, the created list stores pointers instead of * copies of the added elements, and the compare function will be automatically set * to cx_cmp_ptr(), if none is given. * * After creating the list, it can also be used as a map after converting the pointer * to a CxMap pointer with cxKvListAsMap(). * When you want to use the list interface again, you can also convert the map pointer back * with cxKvListAsList(). * * @param allocator the allocator for allocating the list nodes * (if @c NULL, the cxDefaultAllocator will be used) * @param comparator the comparator for the elements * (if @c NULL, and the list is not storing pointers, sort and find * functions will not work) * @param elem_size the size of each element in bytes * @return the created list * @see cxKvListAsMap() * @see cxKvListAsList() */ cx_attr_nodiscard cx_attr_malloc cx_attr_dealloc(cxListFree, 1) cx_attr_export CxList *cxKvListCreate( const CxAllocator *allocator, cx_compare_func comparator, size_t elem_size ); /** * Allocates a linked list with a lookup-map for storing elements with @p elem_size bytes each. * * If @p elem_size is #CX_STORE_POINTERS, the created list stores pointers instead of * copies of the added elements, and the compare function will be automatically set * to cx_cmp_ptr(), if none is given. * * This function creates the list with cxKvListCreate() and immediately applies * cxKvListAsMap(). If you want to use the returned object as a list, you can call * cxKvListAsList() later. * * @param allocator the allocator for allocating the list nodes * (if @c NULL, the cxDefaultAllocator will be used) * @param comparator the comparator for the elements * (if @c NULL, and the list is not storing pointers, sort and find * functions will not work) * @param elem_size the size of each element in bytes * @return the created list wrapped into the CxMap interface * @see cxKvListAsMap() * @see cxKvListAsList() */ cx_attr_nodiscard cx_attr_malloc cx_attr_dealloc(cxMapFree, 1) cx_attr_export CxMap *cxKvListCreateAsMap( const CxAllocator *allocator, cx_compare_func comparator, size_t elem_size ); /** * Allocates a linked list with a lookup-map for storing elements with @p elem_size bytes each. * * The list will use cxDefaultAllocator and no comparator function. If you want * to call functions that need a comparator, you must either set one immediately * after list creation or use cxKvListCreate(). * * If @p elem_size is #CX_STORE_POINTERS, the created list stores pointers instead of * copies of the added elements, and the compare function will be automatically set * to cx_cmp_ptr(). * * After creating the list, it can also be used as a map after converting the pointer * to a CxMap pointer with cxKvListAsMap(). * When you want to use the list interface again, you can also convert the map pointer back * with cxKvListAsList(). * * @param elem_size (@c size_t) the size of each element in bytes * @return (@c CxList*) the created list * @see cxKvListAsMap() * @see cxKvListAsList() */ #define cxKvListCreateSimple(elem_size) cxKvListCreate(NULL, NULL, elem_size) /** * Allocates a linked list with a lookup-map for storing elements with @p elem_size bytes each. * * The list will use cxDefaultAllocator and no comparator function. If you want * to call functions that need a comparator, you must either set one immediately * after list creation or use cxKvListCreate(). * * If @p elem_size is #CX_STORE_POINTERS, the created list stores pointers instead of * copies of the added elements, and the compare function will be automatically set * to cx_cmp_ptr(). * * This macro behaves as if the list was created with cxKvListCreateSimple() and * immediately followed up by cxKvListAsMap(). * If you want to use the returned object as a list, you can call cxKvListAsList() later. * * @param elem_size (@c size_t) the size of each element in bytes * @return (@c CxMap*) the created list wrapped into the CxMap interface * @see cxKvListAsMap() * @see cxKvListAsList() */ #define cxKvListCreateAsMapSimple(elem_size) cxKvListCreateAsMap(NULL, NULL, elem_size) /** * Converts a map pointer belonging to a key-value-List back to the original list pointer. * * @param map a map pointer that was returned by a call to cxKvListAsMap() * @return the original list pointer */ cx_attr_nodiscard cx_attr_nonnull cx_attr_returns_nonnull cx_attr_export CxList *cxKvListAsList(CxMap *map); /** * Converts a map pointer belonging to a key-value-List back to the original list pointer. * * @param list a list created by cxKvListCreate() or cxKvListCreateSimple() * @return a map pointer that lets you use the list as if it was a map */ cx_attr_nodiscard cx_attr_nonnull cx_attr_returns_nonnull cx_attr_export CxMap *cxKvListAsMap(CxList *list); /** * Sets or updates the key of a list item. * * This is, for example, useful when you have inserted an element using the CxList interface, * and now you want to associate this element with a key. * * @param list (@c CxList*) the list * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key * @param index (@c size_t) the index of the element in the list * @retval zero success * @retval non-zero memory allocation failure or the index is out of bounds */ #define cxKvListSetKey(list, key, index) /** * Removes the key for a list item. * * This can be useful if you want to explicitly remove an item from the lookup map, * for example, when you want to prevent a deletion by cxMapClear(). * * @param list (@c CxList*) the list * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key * @param index (@c size_t) the index of the element in the list * @retval zero success * @retval non-zero the index is out of bounds */ #define cxKvListRemoveKey(list, key, index) /** * Inserts an item into the list at the specified index and associates it with the specified key. * * @param list (@c CxList*) the list * @param index (@c size_t) the index the inserted element shall have * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key * @param value (@c void*) the value * @retval zero success * @retval non-zero memory allocation failure or the index is out of bounds */ #define cxKvListInsert(list, index, key, value) /** * Adds an item into the list and associates it with the specified key. * * @param list (@c CxList*) the list * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key * @param value (@c void*) the value * @retval zero success * @retval non-zero memory allocation failure or the index is out of bounds */ #define cxKvListAdd(list, index, key, value) cxKvListInsert(list, list->collection.size, key, value) #ifdef __cplusplus } // extern "C" #endif #endif // UCX_KV_LIST_H