|
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 |
|
61 int cxKvListAdd(CxList *list, KeyType key, void *value); |
|
62 |
|
63 int cxKvListInsert(CxList *list, size_t index, |
|
64 KeyType key, void *value); |
|
65 ``` |
|
66 |
|
67 > All functions working with keys are implemented as generics, so that the following types are supported: |
|
68 > `CxHashKey`, `cxstring`, `cxmutstr`, `const char*`, and `char*`. |
|
69 > When we write `KeyType`, we mean any of these types. |
|
70 > {style="note"} |
|
71 |
|
72 The `cxKvListSetKey()` and `cxKvListRemoveKey()` functions are used to set or remove the key of an element. |
|
73 They return zero on success and non-zero on failure. |
|
74 A failure can happen when the index is out of bounds or when a memory allocation failed. |
|
75 The `cxKvListSetKey()` function also returns non-zero if the key already exists for _another_ element. |
|
76 |
|
77 With the `cxKvListAdd()` and `cxKvListInsert()` functions, you can add a new element to the list and immediately assign a key to it. |
|
78 The `cxKvListAdd()` function will add the element at the end of the list, |
|
79 while the `cxKvListInsert()` function will insert the element at the specified index. |
|
80 |
|
81 > The effect of `cxKvListAdd()` using the list interface and `cxMapPut()` using the map interface is the same. |