Thu, 25 Sep 2025 14:49:48 +0200
add kv-list files to MSVC project files
resolves #461 for MSVC
1390 | 1 | # Key/Value List |
2 | ||
3 | The key/value list is a linked list of key/value pairs. | |
4 | It implements both the `CxList` and `CxMap` interfaces. | |
5 | ||
6 | ```C | |
7 | #include <cx/kv_list.h> | |
8 | ||
9 | CxList *cxKvListCreate(const CxAllocator *allocator, | |
10 | cx_compare_func comparator, size_t elem_size); | |
11 | ||
12 | CxList *cxKvListCreateSimple(size_t elem_size); | |
13 | ||
14 | CxMap *cxKvListCreateAsMap(const CxAllocator *allocator, | |
15 | cx_compare_func comparator, size_t elem_size); | |
16 | ||
17 | CxMap *cxKvListCreateAsMapSimple(size_t elem_size); | |
18 | ``` | |
19 | ||
20 | The lists are created as usual linked lists with an additional map to look up items by key. | |
21 | The map is created with the same allocator as the list. | |
22 | You can use either interface to access the list. | |
23 | Also, defining destructors on either interface will work as if you defined them on the list. | |
24 | Using the list interface to insert items will insert them without an assigned key, | |
25 | but you can always set a key later using the `cxKvListSetKey()` function (see [](#special-functions) below). | |
26 | ||
27 | > The special thing about key/value lists when used with the map interface is, | |
28 | > that when you iterate over the map, the elements are returned in the order they appear in the list. | |
29 | > In contrast, a normal hash map will return the elements in arbitrary order. | |
30 | > This way you can use a key/value list as an ordered map. | |
31 | > {style="note"} | |
32 | ||
33 | ## Converting between the Interfaces | |
34 | ||
35 | To easily convert between the `CxList` and `CxMap` interfaces, we provide the following functions. | |
36 | ||
37 | ```C | |
38 | #include <cx/kv_list.h> | |
39 | ||
40 | CxMap *cxKvListAsMap(CxList *list); | |
41 | ||
42 | CxList *cxKvListAsList(CxMap *map); | |
43 | ``` | |
44 | ||
45 | They must only be used on lists that have been created as key/value lists. | |
46 | Using them with other lists will result in undefined behavior. | |
47 | ||
48 | ## Special Functions | |
49 | ||
50 | The key/value list has some special functions that are not part of the `CxList` or `CxMap` interface. | |
51 | They also may only be used with lists that have been created as key/value lists. | |
52 | Using them with other lists will result in undefined behavior. | |
53 | ||
54 | ```C | |
55 | #include <cx/kv_list.h> | |
56 | ||
57 | int cxKvListSetKey(CxList *list, size_t index, KeyType key); | |
58 | ||
59 | int cxKvListRemoveKey(CxList *list, size_t index); | |
60 | ||
1394 | 61 | const CxHashKey *cxKvListGetKey(CxList *list, size_t index); |
62 | ||
1390 | 63 | int cxKvListAdd(CxList *list, KeyType key, void *value); |
64 | ||
65 | int cxKvListInsert(CxList *list, size_t index, | |
66 | KeyType key, void *value); | |
67 | ``` | |
68 | ||
69 | > All functions working with keys are implemented as generics, so that the following types are supported: | |
70 | > `CxHashKey`, `cxstring`, `cxmutstr`, `const char*`, and `char*`. | |
71 | > When we write `KeyType`, we mean any of these types. | |
72 | > {style="note"} | |
73 | ||
74 | The `cxKvListSetKey()` and `cxKvListRemoveKey()` functions are used to set or remove the key of an element. | |
75 | They return zero on success and non-zero on failure. | |
76 | A failure can happen when the index is out of bounds or when a memory allocation failed. | |
77 | The `cxKvListSetKey()` function also returns non-zero if the key already exists for _another_ element. | |
1394 | 78 | With `cxKvListGetKey()`, you can retrieve the key of an element. |
79 | This function returns `NULL` when an element has no key assigned or the index is out of bounds. | |
1390 | 80 | |
81 | With the `cxKvListAdd()` and `cxKvListInsert()` functions, you can add a new element to the list and immediately assign a key to it. | |
82 | The `cxKvListAdd()` function will add the element at the end of the list, | |
83 | while the `cxKvListInsert()` function will insert the element at the specified index. | |
84 | ||
85 | > The effect of `cxKvListAdd()` using the list interface and `cxMapPut()` using the map interface is the same. |