diff -r bbdc4aee8534 -r ff077f793c5d docs/Writerside/topics/kv_list.h.md --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/Writerside/topics/kv_list.h.md Wed Sep 24 23:50:15 2025 +0200 @@ -0,0 +1,81 @@ +# Key/Value List + +The key/value list is a linked list of key/value pairs. +It implements both the `CxList` and `CxMap` interfaces. + +```C +#include + +CxList *cxKvListCreate(const CxAllocator *allocator, + cx_compare_func comparator, size_t elem_size); + +CxList *cxKvListCreateSimple(size_t elem_size); + +CxMap *cxKvListCreateAsMap(const CxAllocator *allocator, + cx_compare_func comparator, size_t elem_size); + +CxMap *cxKvListCreateAsMapSimple(size_t elem_size); +``` + +The lists are created as usual linked lists with an additional map to look up items by key. +The map is created with the same allocator as the list. +You can use either interface to access the list. +Also, defining destructors on either interface will work as if you defined them on the list. +Using the list interface to insert items will insert them without an assigned key, +but you can always set a key later using the `cxKvListSetKey()` function (see [](#special-functions) below). + +> The special thing about key/value lists when used with the map interface is, +> that when you iterate over the map, the elements are returned in the order they appear in the list. +> In contrast, a normal hash map will return the elements in arbitrary order. +> This way you can use a key/value list as an ordered map. +> {style="note"} + +## Converting between the Interfaces + +To easily convert between the `CxList` and `CxMap` interfaces, we provide the following functions. + +```C +#include + +CxMap *cxKvListAsMap(CxList *list); + +CxList *cxKvListAsList(CxMap *map); +``` + +They must only be used on lists that have been created as key/value lists. +Using them with other lists will result in undefined behavior. + +## Special Functions + +The key/value list has some special functions that are not part of the `CxList` or `CxMap` interface. +They also may only be used with lists that have been created as key/value lists. +Using them with other lists will result in undefined behavior. + +```C +#include + +int cxKvListSetKey(CxList *list, size_t index, KeyType key); + +int cxKvListRemoveKey(CxList *list, size_t index); + +int cxKvListAdd(CxList *list, KeyType key, void *value); + +int cxKvListInsert(CxList *list, size_t index, + KeyType key, void *value); +``` + +> All functions working with keys are implemented as generics, so that the following types are supported: +> `CxHashKey`, `cxstring`, `cxmutstr`, `const char*`, and `char*`. +> When we write `KeyType`, we mean any of these types. +> {style="note"} + +The `cxKvListSetKey()` and `cxKvListRemoveKey()` functions are used to set or remove the key of an element. +They return zero on success and non-zero on failure. +A failure can happen when the index is out of bounds or when a memory allocation failed. +The `cxKvListSetKey()` function also returns non-zero if the key already exists for _another_ element. + +With the `cxKvListAdd()` and `cxKvListInsert()` functions, you can add a new element to the list and immediately assign a key to it. +The `cxKvListAdd()` function will add the element at the end of the list, +while the `cxKvListInsert()` function will insert the element at the specified index. + +> The effect of `cxKvListAdd()` using the list interface and `cxMapPut()` using the map interface is the same.