docs/Writerside/topics/kv_list.h.md

changeset 1390
ff077f793c5d
--- /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 <cx/kv_list.h>
+
+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 <cx/kv_list.h>
+
+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 <cx/kv_list.h>
+
+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.

mercurial