Fri, 07 Jul 2023 18:33:11 +0200
fix typo in mempool.h
720
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
1 | --- |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
2 | title: UCX Features |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
3 | --- |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
4 | |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
5 | <div id="modules"> |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
6 | |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
7 | ------------------------ ------------------------- ------------------- --------------------------------- |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
8 | [Allocator](#allocator) [String](#string) [Buffer](#buffer) [Memory Pool](#memory-pool) |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
9 | [Iterator](#iterator) [Collection](#collection) [List](#list) [Map](#map) |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
10 | [Utilities](#utilities) |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
11 | ------------------------ ------------------------- ------------------- --------------------------------- |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
12 | |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
13 | </div> |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
14 | |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
15 | ## Allocator |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
16 | |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
17 | *Header file:* [allocator.h](api/allocator_8h.html) |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
18 | |
722 | 19 | The UCX allocator provides an interface for implementing an own memory allocation mechanism. |
20 | Various function in UCX provide an additional alternative signature that takes an allocator as | |
21 | argument. A default allocator implementation using the stdlib memory management functions is | |
22 | available via the global symbol `cxDefaultAllocator`. | |
23 | ||
24 | If you want to define your own allocator, you need to initialize the `CxAllocator` structure | |
25 | with a pointer to an allocator class (containing function pointers for the memory management | |
26 | functions) and an optional pointer to an arbitrary memory region that can be used to store | |
27 | state information for the allocator. An example is shown below: | |
28 | ||
29 | ```c | |
30 | struct my_allocator_state { | |
31 | size_t total; | |
32 | size_t avail; | |
727
d92a59f5d261
improve mempool implementation
Mike Becker <universe@uap-core.de>
parents:
725
diff
changeset
|
33 | char mem[]; |
722 | 34 | }; |
35 | ||
36 | static cx_allocator_class my_allocator_class = { | |
37 | my_malloc_impl, | |
38 | my_realloc_impl, // all these functions are somewhere defined | |
39 | my_calloc_impl, | |
40 | my_free_impl | |
41 | }; | |
42 | ||
43 | CxAllocator create_my_allocator(size_t n) { | |
44 | CxAllocator alloc; | |
45 | alloc.cl = &my_allocator_class; | |
46 | alloc.data = calloc(1, sizeof(struct my_allocator_state) + n); | |
47 | return alloc; | |
48 | } | |
49 | ||
50 | void free_my_allocator(CxAllocator *alloc) { | |
51 | free(alloc.data); | |
52 | free(alloc); | |
53 | } | |
54 | ``` | |
55 | ||
720
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
56 | ## String |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
57 | |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
58 | *Header file:* [string.h](api/string_8h.html) |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
59 | |
723
c33e0ac069dd
add web documentation for strings
Mike Becker <universe@uap-core.de>
parents:
722
diff
changeset
|
60 | UCX strings come in two variants: immutable (`cxstring`) and mutable (`cxmutstr`). |
c33e0ac069dd
add web documentation for strings
Mike Becker <universe@uap-core.de>
parents:
722
diff
changeset
|
61 | The functions of UCX are designed to work with immutable strings by default but in situations where it is necessary, |
c33e0ac069dd
add web documentation for strings
Mike Becker <universe@uap-core.de>
parents:
722
diff
changeset
|
62 | the API also provides alternative functions that work directly with mutable strings. |
c33e0ac069dd
add web documentation for strings
Mike Becker <universe@uap-core.de>
parents:
722
diff
changeset
|
63 | Functions that change a string in-place are, of course, only accepting mutable strings. |
c33e0ac069dd
add web documentation for strings
Mike Becker <universe@uap-core.de>
parents:
722
diff
changeset
|
64 | |
c33e0ac069dd
add web documentation for strings
Mike Becker <universe@uap-core.de>
parents:
722
diff
changeset
|
65 | When you are using UCX functions, or defining your own functions, you are sometimes facing the "problem", |
c33e0ac069dd
add web documentation for strings
Mike Becker <universe@uap-core.de>
parents:
722
diff
changeset
|
66 | that the function only accepts arguments of type `cxstring` but you only have a `cxmutstr` at hand. |
c33e0ac069dd
add web documentation for strings
Mike Becker <universe@uap-core.de>
parents:
722
diff
changeset
|
67 | In this case you _should not_ introduce a wrapper function that accepts the `cxmutstr`, |
c33e0ac069dd
add web documentation for strings
Mike Becker <universe@uap-core.de>
parents:
722
diff
changeset
|
68 | but instead you should use the `cx_strcast()` function to cast the argument to the correct type. |
c33e0ac069dd
add web documentation for strings
Mike Becker <universe@uap-core.de>
parents:
722
diff
changeset
|
69 | |
c33e0ac069dd
add web documentation for strings
Mike Becker <universe@uap-core.de>
parents:
722
diff
changeset
|
70 | In general, UCX strings are **not** necessarily zero-terminated. If a function guarantees to return zero-terminated |
c33e0ac069dd
add web documentation for strings
Mike Becker <universe@uap-core.de>
parents:
722
diff
changeset
|
71 | string, it is explicitly mentioned in the documentation of the respective function. |
c33e0ac069dd
add web documentation for strings
Mike Becker <universe@uap-core.de>
parents:
722
diff
changeset
|
72 | As a rule of thumb, you _should not_ pass the strings of a UCX string structure to another API without explicitly |
c33e0ac069dd
add web documentation for strings
Mike Becker <universe@uap-core.de>
parents:
722
diff
changeset
|
73 | ensuring that the string is zero-terminated. |
c33e0ac069dd
add web documentation for strings
Mike Becker <universe@uap-core.de>
parents:
722
diff
changeset
|
74 | |
720
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
75 | ## Buffer |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
76 | |
724
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
77 | *Header file:* [buffer.h](api/buffer_8h.html) |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
78 | |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
79 | Instances of this buffer implementation can be used to read from or write to memory like you would do with a stream. |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
80 | This allows the use of `cx_stream_copy()` (see [Utilities](#utilities)) to copy contents from one buffer to another, |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
81 | or from a file or network streams to the buffer and vice-versa. |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
82 | |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
83 | More features for convenient use of the buffer can be enabled, like automatic memory management and automatic |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
84 | resizing of the buffer space. |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
85 | |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
86 | Since UCX 3.0, the buffer also supports automatic flushing of contents to another stream (or buffer) as an alternative |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
87 | to automatically resizing the buffer space. |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
88 | Please refer to the API doc for the fields prefixed with `flush_` to learn more. |
720
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
89 | |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
90 | ## Memory Pool |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
91 | |
725
c9b882bef838
add docs for the compare.h and printf.h utilities
Mike Becker <universe@uap-core.de>
parents:
724
diff
changeset
|
92 | *Header file:* [mempool.h](api/mempool_8h.html) |
720
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
93 | |
729 | 94 | A memory pool is providing an allocator implementation that automatically deallocates the memory upon its destruction. |
95 | It also allows you to register destructor functions for the allocated memory, which are automatically called before | |
96 | the memory is deallocated. | |
97 | Additionally, you may also register _independent_ destructor functions within a pool in case some external library | |
98 | allocated memory for you, which should be destroyed together with this pool. | |
99 | ||
100 | Many UCX features support the use of an allocator. | |
101 | The [strings](#string), for instance, provide several functions suffixed with `_a` that allow specifying an allocator. | |
102 | You can use this to keep track of the memory occupied by dynamically allocated strings and cleanup everything with | |
103 | just a single call to `cxMempoolDestroy()`. | |
104 | ||
105 | The following code illustrates this on the example of reading a CSV file into memory. | |
106 | ```C | |
107 | #include <stdio.h> | |
108 | #include <cx/mempool.h> | |
109 | #include <cx/linked_list.h> | |
110 | #include <cx/string.h> | |
111 | #include <cx/buffer.h> | |
112 | #include <cx/utils.h> | |
113 | ||
114 | typedef struct { | |
115 | cxstring column_a; | |
116 | cxstring column_b; | |
117 | cxstring column_c; | |
118 | } CSVData; | |
119 | ||
120 | int main(void) { | |
121 | CxMempool* pool = cxBasicMempoolCreate(128); | |
122 | ||
123 | FILE *f = fopen("test.csv", "r"); | |
124 | if (!f) { | |
125 | perror("Cannot open file"); | |
126 | return 1; | |
127 | } | |
128 | // close the file automatically at pool destruction | |
129 | cxMempoolRegister(pool, f, (cx_destructor_func) fclose); | |
130 | ||
131 | // create a buffer using the memory pool for destruction | |
132 | CxBuffer *content = cxBufferCreate(NULL, 256, pool->allocator, CX_BUFFER_AUTO_EXTEND); | |
133 | ||
134 | // read the file into the buffer and turn it into a string | |
135 | cx_stream_copy(f, content, (cx_read_func) fread, (cx_write_func) cxBufferWrite); | |
136 | cxstring contentstr = cx_strn(content->space, content->size); | |
137 | ||
138 | // split the string into lines - use the mempool for allocating the target array | |
139 | cxstring* lines; | |
140 | size_t lc = cx_strsplit_a(pool->allocator, contentstr, | |
141 | CX_STR("\n"), SIZE_MAX, &lines); | |
142 | ||
143 | // skip the header and parse the remaining data into a linked list | |
144 | // the nodes of the linked list shall also be allocated by the mempool | |
145 | CxList* datalist = cxLinkedListCreate(pool->allocator, NULL, sizeof(CSVData)); | |
146 | for (size_t i = 1 ; i < lc ; i++) { | |
147 | if (lines[i].length == 0) continue; | |
148 | cxstring fields[3]; | |
149 | size_t fc = cx_strsplit(lines[i], CX_STR(";"), 3, fields); | |
150 | if (fc != 3) { | |
151 | fprintf(stderr, "Syntax error in line %zu.\n", i); | |
152 | cxMempoolDestroy(pool); | |
153 | return 1; | |
154 | } | |
155 | CSVData* data = cxMalloc(pool->allocator, sizeof(CSVData)); | |
156 | data->column_a = fields[0]; | |
157 | data->column_b = fields[1]; | |
158 | data->column_c = fields[2]; | |
159 | cxListAdd(datalist, data); | |
160 | } | |
161 | ||
162 | // iterate through the list and output the data | |
163 | CxIterator iter = cxListIterator(datalist); | |
164 | cx_foreach(CSVData*, data, iter) { | |
165 | printf("Column A: %.*s | " | |
166 | "Column B: %.*s | " | |
167 | "Column C: %.*s\n", | |
168 | (int)data->column_a.length, data->column_a.ptr, | |
169 | (int)data->column_b.length, data->column_b.ptr, | |
170 | (int)data->column_c.length, data->column_c.ptr | |
171 | ); | |
172 | } | |
173 | ||
174 | // cleanup everything, no manual free() needed | |
175 | cxMempoolDestroy(pool); | |
176 | ||
177 | return 0; | |
178 | } | |
179 | ``` | |
180 | ||
720
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
181 | ## Iterator |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
182 | |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
183 | *Header file:* [iterator.h](api/iterator_8h.html) |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
184 | |
733
2ed01495f838
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
732
diff
changeset
|
185 | In UCX 3 a new feature has been introduced to write own iterators, that work with the `cx_foreach` macro. |
2ed01495f838
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
732
diff
changeset
|
186 | In previous UCX releases there were different hard-coded foreach macros for lists and maps that were not customizable. |
2ed01495f838
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
732
diff
changeset
|
187 | Now, creating an iterator is as simple as creating a `CxIterator` struct and setting the fields in a meaningful way. |
2ed01495f838
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
732
diff
changeset
|
188 | |
2ed01495f838
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
732
diff
changeset
|
189 | You do not always need all fields in the iterator structure, depending on your use case. |
2ed01495f838
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
732
diff
changeset
|
190 | Sometimes you only need the `index` (for example when iterating over simple lists), and other times you will need the |
2ed01495f838
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
732
diff
changeset
|
191 | `slot` and `kv_data` fields (for example when iterating over maps). |
2ed01495f838
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
732
diff
changeset
|
192 | |
2ed01495f838
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
732
diff
changeset
|
193 | Usually an iterator is not mutating the collection it is iterating over. |
2ed01495f838
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
732
diff
changeset
|
194 | In some programming languages it is even disallowed to change the collection while iterating with foreach. |
2ed01495f838
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
732
diff
changeset
|
195 | But sometimes it is desirable to remove an element from the collection while iterating over it. |
2ed01495f838
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
732
diff
changeset
|
196 | This is, what the `CxMutIterator` is for. |
2ed01495f838
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
732
diff
changeset
|
197 | The only differences are, that the `mutating` flag is `true` and the `src_handle` is not const. |
2ed01495f838
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
732
diff
changeset
|
198 | On mutating iterators it is allowed to call the `cxFlagForRemoval()` function, which instructs the iterator to remove |
2ed01495f838
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
732
diff
changeset
|
199 | the current element from the collection on the next call to `cxIteratorNext()` and clear the flag afterward. |
2ed01495f838
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
732
diff
changeset
|
200 | If you are implementing your own iterator, it is up to you to implement this behavior in your `next` method, or |
2ed01495f838
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
732
diff
changeset
|
201 | make the implementation of the `flag_removal` method always return `false`. |
2ed01495f838
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
732
diff
changeset
|
202 | |
720
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
203 | ## Collection |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
204 | |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
205 | *Header file:* [collection.h](api/collection_8h.html) |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
206 | |
730
9fecb2769d32
add documentation for collection.h
Mike Becker <universe@uap-core.de>
parents:
729
diff
changeset
|
207 | Collections in UCX 3 have several common features. |
9fecb2769d32
add documentation for collection.h
Mike Becker <universe@uap-core.de>
parents:
729
diff
changeset
|
208 | If you want to implement an own collection data type that uses the same features, you can use the |
9fecb2769d32
add documentation for collection.h
Mike Becker <universe@uap-core.de>
parents:
729
diff
changeset
|
209 | `CX_COLLECTION_MEMBERS` macro at the beginning of your struct to roll out all members a usual UCX collection has. |
9fecb2769d32
add documentation for collection.h
Mike Becker <universe@uap-core.de>
parents:
729
diff
changeset
|
210 | ```c |
9fecb2769d32
add documentation for collection.h
Mike Becker <universe@uap-core.de>
parents:
729
diff
changeset
|
211 | struct my_fancy_collection_s { |
9fecb2769d32
add documentation for collection.h
Mike Becker <universe@uap-core.de>
parents:
729
diff
changeset
|
212 | CX_COLLECTION_MEMBERS |
9fecb2769d32
add documentation for collection.h
Mike Becker <universe@uap-core.de>
parents:
729
diff
changeset
|
213 | struct my_collection_data_s *data; |
9fecb2769d32
add documentation for collection.h
Mike Becker <universe@uap-core.de>
parents:
729
diff
changeset
|
214 | }; |
9fecb2769d32
add documentation for collection.h
Mike Becker <universe@uap-core.de>
parents:
729
diff
changeset
|
215 | ``` |
9fecb2769d32
add documentation for collection.h
Mike Becker <universe@uap-core.de>
parents:
729
diff
changeset
|
216 | Based on this structure, this header provides some convenience macros for invoking the destructor functions |
9fecb2769d32
add documentation for collection.h
Mike Becker <universe@uap-core.de>
parents:
729
diff
changeset
|
217 | that are part of the basic collection members. |
9fecb2769d32
add documentation for collection.h
Mike Becker <universe@uap-core.de>
parents:
729
diff
changeset
|
218 | The idea of having destructor functions within a collection is that you can destroy the collection _and_ the |
9fecb2769d32
add documentation for collection.h
Mike Becker <universe@uap-core.de>
parents:
729
diff
changeset
|
219 | contents with one single function call. |
9fecb2769d32
add documentation for collection.h
Mike Becker <universe@uap-core.de>
parents:
729
diff
changeset
|
220 | When you are implementing a collection, you are responsible for invoking the destructors at the right places, e.g. |
9fecb2769d32
add documentation for collection.h
Mike Becker <universe@uap-core.de>
parents:
729
diff
changeset
|
221 | when removing (and deleting) elements in the collection, clearing the collection, or - the most prominent case - |
9fecb2769d32
add documentation for collection.h
Mike Becker <universe@uap-core.de>
parents:
729
diff
changeset
|
222 | destroying the collection. |
9fecb2769d32
add documentation for collection.h
Mike Becker <universe@uap-core.de>
parents:
729
diff
changeset
|
223 | |
9fecb2769d32
add documentation for collection.h
Mike Becker <universe@uap-core.de>
parents:
729
diff
changeset
|
224 | You can always look at the UCX list and map implementations if you need some inspiration. |
9fecb2769d32
add documentation for collection.h
Mike Becker <universe@uap-core.de>
parents:
729
diff
changeset
|
225 | |
720
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
226 | ## List |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
227 | |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
228 | *Header file:* [list.h](api/list_8h.html) |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
229 | |
731
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
230 | This header defines a common interface for all list implementations, which is basically as simple as the following |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
231 | structure. |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
232 | ```c |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
233 | struct cx_list_s { |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
234 | CX_COLLECTION_MEMBERS // size, capacity, etc. |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
235 | cx_list_class const *cl; // The list class definition |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
236 | }; |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
237 | ``` |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
238 | The actual structure contains one more class pointer that is used when wrapping a list into a pointer aware list |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
239 | with `cxListStorePointers()`. What this means, is that - if you want to implement your own list structure - you |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
240 | only need to cover the case where the list is storing copies of your objects. |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
241 | |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
242 | UCX comes with two common list implementations (linked list and array list) that should cover most use cases. |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
243 | But if you feel the need to implement an own list, the only thing you need to do is to define a struct where |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
244 | `struct cx_list_s`, and set an appropriate list class that implements the functionality. |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
245 | It is strongly recommended that this class is shared among all instances of the same list type, because otherwise |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
246 | the `cxListCompare` function cannot use the optimized implementation of your class and will instead fall back to |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
247 | using iterators to compare the contents element-wise. |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
248 | |
720
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
249 | ### Linked List |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
250 | |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
251 | *Header file:* [linked_list.h](api/linked__list_8h.html) |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
252 | |
731
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
253 | On top of implementing the list interface, this header also defines several low-level functions that |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
254 | work with arbitrary structures. |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
255 | Low-level functions, in contrast to the high-level list interface, can easily be recognized by their snake-casing. |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
256 | The function `cx_linked_list_at`, for example, implements a similar functionality like `cxListAt`, but operates |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
257 | on arbitrary structures. |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
258 | The following snippet shows how it is used. |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
259 | All other low-level functions work similarly. |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
260 | ```c |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
261 | struct node { |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
262 | node *next; |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
263 | node *prev; |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
264 | int data; |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
265 | }; |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
266 | |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
267 | const ptrdiff_t loc_prev = offsetof(struct node, prev); |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
268 | const ptrdiff_t loc_next = offsetof(struct node, next); |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
269 | const ptrdiff_t loc_data = offsetof(struct node, data); |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
270 | |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
271 | struct node a = {0}, b = {0}, c = {0}, d = {0}; |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
272 | cx_linked_list_link(&a, &b, loc_prev, loc_next); |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
273 | cx_linked_list_link(&b, &c, loc_prev, loc_next); |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
274 | cx_linked_list_link(&c, &d, loc_prev, loc_next); |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
275 | |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
276 | cx_linked_list_at(&a, 0, loc_next, 2); // returns pointer to c |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
277 | ``` |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
278 | |
720
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
279 | ### Array List |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
280 | |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
281 | *Header file:* [array_list.h](api/array__list_8h.html) |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
282 | |
731
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
283 | Since low-level array lists are just plain arrays, there is no need for such many low-level functions as for linked |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
284 | lists. |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
285 | However, there is one extremely powerful function that can be used for several complex tasks: `cx_array_copy`. |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
286 | The full signature is shown below: |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
287 | ```c |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
288 | enum cx_array_copy_result cx_array_copy( |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
289 | void **target, |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
290 | size_t *size, |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
291 | size_t *capacity, // optional |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
292 | size_t index, |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
293 | void const *src, |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
294 | size_t elem_size, |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
295 | size_t elem_count, |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
296 | struct cx_array_reallocator_s *reallocator // optional |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
297 | ); |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
298 | ``` |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
299 | The `target` argument is a pointer to the target array pointer. |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
300 | The reason for this additional indirection is that - given that you provide a `reallocator` - this function writes |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
301 | back the pointer to the possibly reallocated array. |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
302 | THe next two arguments are pointers to the `size` and `capacity` of the target array. |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
303 | Tracking the capacity is optional. |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
304 | If you do not specify a pointer for the capacity, automatic reallocation of the array is entirely disabled (i.e. it |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
305 | does not make sense to specify a `reallocator` then). |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
306 | In this case, the function cannot copy more than `size-index` elements and if you try, it will return |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
307 | `CX_ARRAY_COPY_REALLOC_NOT_SUPPORTED` and do nothing. |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
308 | |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
309 | On a successful invocation, the function copies `elem_count` number of elements, each of size `elem_size` from |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
310 | `src` to `*target` and uses the `reallocator` to extend the array when necessary. |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
311 | Finally, the size, capacity, and the pointer to the array are all updated and the function returns |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
312 | `CX_ARRAY_COPY_SUCCESS`. |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
313 | |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
314 | The third, but extremely rare, return code is `CX_ARRAY_COPY_REALLOC_FAILED` and speaks for itself. |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
315 | |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
316 | A few things to note: |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
317 | * `*target` and `src` can point to the same memory region, effectively copying elements within the array with `memmove` |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
318 | * `*target` does not need to point to the start of the array, but `size` and `capacity` always start counting from the |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
319 | position, `*target` points to - in this scenario, specifying a `reallocator` is forbidden for obvious reasons |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
320 | * `index` does not need to be within size of the current array, if `capacity` is specified |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
321 | * `index` does not even need to be within the capacity of the array, if `reallocator` is specified |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
322 | |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
323 | |
720
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
324 | ## Map |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
325 | |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
326 | *Header file:* [map.h](api/map_8h.html) |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
327 | |
732 | 328 | Similar to the list interface, the map interface provides a common API for implementing maps. |
329 | There are some minor subtle differences, though. | |
330 | ||
331 | First, the `remove` method is not always a destructive removal. | |
332 | Instead, the last argument is a Boolean that indicates whether the element shall be destroyed or returned. | |
333 | ```c | |
334 | void *(*remove)(CxMap *map, CxHashKey key, bool destroy); | |
335 | ``` | |
336 | When you implement this method, you are either supposed to invoke the destructors and return `NULL`, | |
337 | or just remove the element from the map and return it. | |
338 | ||
339 | Secondly, the iterator method is a bit more complete. The signature is as follows: | |
340 | ```c | |
341 | CxIterator (*iterator)(CxMap const *map, enum cx_map_iterator_type type); | |
342 | ``` | |
343 | There are three map iterator types: for values, for keys, for pairs. | |
344 | Depending on the iterator type requested, you need to create an iterator with the correct methods that | |
345 | return the requested thing. | |
346 | There are no automatic checks to enforce this - it's completely up to you. | |
347 | If you need inspiration on how to do that, check the hash map implementation that comes with UCX. | |
348 | ||
720
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
349 | ### Hash Map |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
350 | |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
351 | *Header file:* [hash_map.h](api/hash__map_8h.html) |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
352 | |
732 | 353 | UCX provides a basic hash map implementation with a configurable amount of buckets. |
354 | If you do not specify the number of buckets, a default of 16 buckets will be used. | |
355 | You can always rehash the map with `cxMapRehash()` to change the number of buckets to something more efficient, | |
356 | but you need to be careful, because when you use this function you are effectively locking into using this | |
357 | specific hash map implementation, and you would need to remove all calls to this function when you want to | |
358 | exchange the concrete map implementation with something different. | |
359 | ||
720
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
360 | ## Utilities |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
361 | |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
362 | *Header file:* [utils.h](api/utils_8h.html) |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
363 | |
724
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
364 | UCX provides some utilities for routine tasks. Most of them are simple macros, like e.g. the `cx_for_n()` macro, |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
365 | creating a `for` loop counting from zero to (n-1) which is extremely useful to traverse the indices of |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
366 | an array. |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
367 | |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
368 | But the most useful utilities are the *stream copy* functions, which provide a simple way to copy all - or a |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
369 | bounded amount of - data from one stream to another. Since the read/write functions of a UCX buffer are |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
370 | fully compatible with stream read/write functions, you can easily transfer data from file or network streams to |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
371 | a UCX buffer or vice-versa. |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
372 | |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
373 | The following example shows, how easy it is to read the contents of a file into a buffer: |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
374 | ```c |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
375 | FILE *inputfile = fopen(infilename, "r"); |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
376 | if (inputfile) { |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
377 | CxBuffer fbuf; |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
378 | cxBufferInit(&fbuf, NULL, 4096, NULL, CX_BUFFER_AUTO_EXTEND); |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
379 | cx_stream_copy(inputfile, &fbuf, |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
380 | (cx_read_func) fread, |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
381 | (cx_write_func) cxBufferWrite); |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
382 | fclose(inputfile); |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
383 | |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
384 | // ... do something meaningful with the contents ... |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
385 | |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
386 | cxBufferDestroy(&fbuf); |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
387 | } else { |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
388 | perror("Error opening input file"); |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
389 | if (fout != stdout) { |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
390 | fclose(fout); |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
391 | } |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
392 | } |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
393 | ``` |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
394 | |
720
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
395 | ### Printf Functions |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
396 | |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
397 | *Header file:* [printf.h](api/printf_8h.html) |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
398 | |
725
c9b882bef838
add docs for the compare.h and printf.h utilities
Mike Becker <universe@uap-core.de>
parents:
724
diff
changeset
|
399 | In this utility header you can find `printf()`-like functions that can write the formatted output to an arbitrary |
c9b882bef838
add docs for the compare.h and printf.h utilities
Mike Becker <universe@uap-core.de>
parents:
724
diff
changeset
|
400 | stream (or UCX buffer, resp.), or to memory allocated by an allocator within a single function call. |
c9b882bef838
add docs for the compare.h and printf.h utilities
Mike Becker <universe@uap-core.de>
parents:
724
diff
changeset
|
401 | With the help of these convenience functions, you do not need to `snprintf` your string to a temporary buffer anymore, |
c9b882bef838
add docs for the compare.h and printf.h utilities
Mike Becker <universe@uap-core.de>
parents:
724
diff
changeset
|
402 | plus you do not need to worry about too small buffer sizes, because the functions will automatically allocate enough |
c9b882bef838
add docs for the compare.h and printf.h utilities
Mike Becker <universe@uap-core.de>
parents:
724
diff
changeset
|
403 | memory to contain the entire formatted string. |
c9b882bef838
add docs for the compare.h and printf.h utilities
Mike Becker <universe@uap-core.de>
parents:
724
diff
changeset
|
404 | |
720
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
405 | ### Compare Functions |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
406 | |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
407 | *Header file:* [compare.h](api/compare_8h.html) |
725
c9b882bef838
add docs for the compare.h and printf.h utilities
Mike Becker <universe@uap-core.de>
parents:
724
diff
changeset
|
408 | |
c9b882bef838
add docs for the compare.h and printf.h utilities
Mike Becker <universe@uap-core.de>
parents:
724
diff
changeset
|
409 | This header file contains a collection of compare functions for various data types. |
c9b882bef838
add docs for the compare.h and printf.h utilities
Mike Becker <universe@uap-core.de>
parents:
724
diff
changeset
|
410 | Their signatures are designed to be compatible with the `cx_compare_func` function pointer type. |