Sat, 17 Feb 2024 20:51:27 +0100
remove unnecessary flag_removal function
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 | ||
720
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
51 | ## String |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
52 | |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
53 | *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
|
54 | |
723
c33e0ac069dd
add web documentation for strings
Mike Becker <universe@uap-core.de>
parents:
722
diff
changeset
|
55 | 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
|
56 | 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
|
57 | 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
|
58 | 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
|
59 | |
c33e0ac069dd
add web documentation for strings
Mike Becker <universe@uap-core.de>
parents:
722
diff
changeset
|
60 | 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
|
61 | 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
|
62 | 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
|
63 | 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
|
64 | |
c33e0ac069dd
add web documentation for strings
Mike Becker <universe@uap-core.de>
parents:
722
diff
changeset
|
65 | 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
|
66 | 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
|
67 | 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
|
68 | ensuring that the string is zero-terminated. |
c33e0ac069dd
add web documentation for strings
Mike Becker <universe@uap-core.de>
parents:
722
diff
changeset
|
69 | |
720
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
70 | ## Buffer |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
71 | |
724
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
72 | *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
|
73 | |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
74 | 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
|
75 | 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
|
76 | 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
|
77 | |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
78 | 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
|
79 | resizing of the buffer space. |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
80 | |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
81 | 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
|
82 | 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
|
83 | 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
|
84 | |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
85 | ## Memory Pool |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
86 | |
725
c9b882bef838
add docs for the compare.h and printf.h utilities
Mike Becker <universe@uap-core.de>
parents:
724
diff
changeset
|
87 | *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
|
88 | |
729 | 89 | A memory pool is providing an allocator implementation that automatically deallocates the memory upon its destruction. |
90 | It also allows you to register destructor functions for the allocated memory, which are automatically called before | |
91 | the memory is deallocated. | |
92 | Additionally, you may also register _independent_ destructor functions within a pool in case some external library | |
93 | allocated memory for you, which should be destroyed together with this pool. | |
94 | ||
95 | Many UCX features support the use of an allocator. | |
96 | The [strings](#string), for instance, provide several functions suffixed with `_a` that allow specifying an allocator. | |
97 | You can use this to keep track of the memory occupied by dynamically allocated strings and cleanup everything with | |
98 | just a single call to `cxMempoolDestroy()`. | |
99 | ||
100 | The following code illustrates this on the example of reading a CSV file into memory. | |
101 | ```C | |
102 | #include <stdio.h> | |
103 | #include <cx/mempool.h> | |
104 | #include <cx/linked_list.h> | |
105 | #include <cx/string.h> | |
106 | #include <cx/buffer.h> | |
107 | #include <cx/utils.h> | |
108 | ||
109 | typedef struct { | |
110 | cxstring column_a; | |
111 | cxstring column_b; | |
112 | cxstring column_c; | |
113 | } CSVData; | |
114 | ||
115 | int main(void) { | |
116 | CxMempool* pool = cxBasicMempoolCreate(128); | |
117 | ||
118 | FILE *f = fopen("test.csv", "r"); | |
119 | if (!f) { | |
120 | perror("Cannot open file"); | |
121 | return 1; | |
122 | } | |
123 | // close the file automatically at pool destruction | |
124 | cxMempoolRegister(pool, f, (cx_destructor_func) fclose); | |
125 | ||
126 | // create a buffer using the memory pool for destruction | |
127 | CxBuffer *content = cxBufferCreate(NULL, 256, pool->allocator, CX_BUFFER_AUTO_EXTEND); | |
128 | ||
129 | // read the file into the buffer and turn it into a string | |
130 | cx_stream_copy(f, content, (cx_read_func) fread, (cx_write_func) cxBufferWrite); | |
745
c99abca90d21
some fixes in example code
Mike Becker <universe@uap-core.de>
parents:
733
diff
changeset
|
131 | fclose(f); |
729 | 132 | cxstring contentstr = cx_strn(content->space, content->size); |
133 | ||
134 | // split the string into lines - use the mempool for allocating the target array | |
135 | cxstring* lines; | |
136 | size_t lc = cx_strsplit_a(pool->allocator, contentstr, | |
137 | CX_STR("\n"), SIZE_MAX, &lines); | |
138 | ||
139 | // skip the header and parse the remaining data into a linked list | |
140 | // the nodes of the linked list shall also be allocated by the mempool | |
141 | CxList* datalist = cxLinkedListCreate(pool->allocator, NULL, sizeof(CSVData)); | |
142 | for (size_t i = 1 ; i < lc ; i++) { | |
143 | if (lines[i].length == 0) continue; | |
144 | cxstring fields[3]; | |
145 | size_t fc = cx_strsplit(lines[i], CX_STR(";"), 3, fields); | |
146 | if (fc != 3) { | |
147 | fprintf(stderr, "Syntax error in line %zu.\n", i); | |
148 | cxMempoolDestroy(pool); | |
149 | return 1; | |
150 | } | |
746 | 151 | CSVData data; |
152 | data.column_a = fields[0]; | |
153 | data.column_b = fields[1]; | |
154 | data.column_c = fields[2]; | |
155 | cxListAdd(datalist, &data); | |
729 | 156 | } |
157 | ||
158 | // iterate through the list and output the data | |
159 | CxIterator iter = cxListIterator(datalist); | |
160 | cx_foreach(CSVData*, data, iter) { | |
161 | printf("Column A: %.*s | " | |
162 | "Column B: %.*s | " | |
163 | "Column C: %.*s\n", | |
164 | (int)data->column_a.length, data->column_a.ptr, | |
165 | (int)data->column_b.length, data->column_b.ptr, | |
166 | (int)data->column_c.length, data->column_c.ptr | |
167 | ); | |
168 | } | |
169 | ||
170 | // cleanup everything, no manual free() needed | |
171 | cxMempoolDestroy(pool); | |
172 | ||
173 | return 0; | |
174 | } | |
175 | ``` | |
176 | ||
720
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
177 | ## Iterator |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
178 | |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
179 | *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
|
180 | |
733
2ed01495f838
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
732
diff
changeset
|
181 | 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
|
182 | 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
|
183 | 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
|
184 | |
2ed01495f838
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
732
diff
changeset
|
185 | 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
|
186 | 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
|
187 | `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
|
188 | |
2ed01495f838
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
732
diff
changeset
|
189 | 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
|
190 | 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
|
191 | 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
|
192 | This is, what the `CxMutIterator` is for. |
2ed01495f838
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
732
diff
changeset
|
193 | 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
|
194 | 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
|
195 | 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
|
196 | 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
|
197 | 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
|
198 | |
720
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
199 | ## Collection |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
200 | |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
201 | *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
|
202 | |
730
9fecb2769d32
add documentation for collection.h
Mike Becker <universe@uap-core.de>
parents:
729
diff
changeset
|
203 | Collections in UCX 3 have several common features. |
9fecb2769d32
add documentation for collection.h
Mike Becker <universe@uap-core.de>
parents:
729
diff
changeset
|
204 | 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
|
205 | `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
|
206 | ```c |
9fecb2769d32
add documentation for collection.h
Mike Becker <universe@uap-core.de>
parents:
729
diff
changeset
|
207 | struct my_fancy_collection_s { |
9fecb2769d32
add documentation for collection.h
Mike Becker <universe@uap-core.de>
parents:
729
diff
changeset
|
208 | CX_COLLECTION_MEMBERS |
9fecb2769d32
add documentation for collection.h
Mike Becker <universe@uap-core.de>
parents:
729
diff
changeset
|
209 | struct my_collection_data_s *data; |
9fecb2769d32
add documentation for collection.h
Mike Becker <universe@uap-core.de>
parents:
729
diff
changeset
|
210 | }; |
9fecb2769d32
add documentation for collection.h
Mike Becker <universe@uap-core.de>
parents:
729
diff
changeset
|
211 | ``` |
9fecb2769d32
add documentation for collection.h
Mike Becker <universe@uap-core.de>
parents:
729
diff
changeset
|
212 | 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
|
213 | that are part of the basic collection members. |
9fecb2769d32
add documentation for collection.h
Mike Becker <universe@uap-core.de>
parents:
729
diff
changeset
|
214 | 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
|
215 | contents with one single function call. |
9fecb2769d32
add documentation for collection.h
Mike Becker <universe@uap-core.de>
parents:
729
diff
changeset
|
216 | 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
|
217 | 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
|
218 | destroying the collection. |
9fecb2769d32
add documentation for collection.h
Mike Becker <universe@uap-core.de>
parents:
729
diff
changeset
|
219 | |
9fecb2769d32
add documentation for collection.h
Mike Becker <universe@uap-core.de>
parents:
729
diff
changeset
|
220 | 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
|
221 | |
720
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
222 | ## List |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
223 | |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
224 | *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
|
225 | |
731
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
226 | 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
|
227 | structure. |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
228 | ```c |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
229 | struct cx_list_s { |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
230 | CX_COLLECTION_MEMBERS // size, capacity, etc. |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
231 | 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
|
232 | }; |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
233 | ``` |
745
c99abca90d21
some fixes in example code
Mike Becker <universe@uap-core.de>
parents:
733
diff
changeset
|
234 | The actual structure contains one more class pointer that is used when wrapping a list into a pointer-aware list |
731
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
235 | 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
|
236 | 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
|
237 | |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
238 | 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
|
239 | 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
|
240 | `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
|
241 | 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
|
242 | 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
|
243 | using iterators to compare the contents element-wise. |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
244 | |
720
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
245 | ### Linked List |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
246 | |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
247 | *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
|
248 | |
731
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
249 | 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
|
250 | work with arbitrary structures. |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
251 | 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
|
252 | 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
|
253 | on arbitrary structures. |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
254 | The following snippet shows how it is used. |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
255 | All other low-level functions work similarly. |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
256 | ```c |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
257 | struct node { |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
258 | node *next; |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
259 | node *prev; |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
260 | int data; |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
261 | }; |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
262 | |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
263 | 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
|
264 | 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
|
265 | 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
|
266 | |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
267 | 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
|
268 | 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
|
269 | 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
|
270 | 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
|
271 | |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
272 | 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
|
273 | ``` |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
274 | |
720
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
275 | ### Array List |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
276 | |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
277 | *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
|
278 | |
731
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
279 | 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
|
280 | lists. |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
281 | 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
|
282 | The full signature is shown below: |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
283 | ```c |
819
5da2ead43077
rename cx_array_copy_result to just cx_array_result
Mike Becker <universe@uap-core.de>
parents:
746
diff
changeset
|
284 | enum cx_array_result cx_array_copy( |
731
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
285 | void **target, |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
286 | size_t *size, |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
287 | size_t *capacity, // optional |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
288 | size_t index, |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
289 | void const *src, |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
290 | size_t elem_size, |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
291 | size_t elem_count, |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
292 | struct cx_array_reallocator_s *reallocator // optional |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
293 | ); |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
294 | ``` |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
295 | 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
|
296 | 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
|
297 | back the pointer to the possibly reallocated array. |
819
5da2ead43077
rename cx_array_copy_result to just cx_array_result
Mike Becker <universe@uap-core.de>
parents:
746
diff
changeset
|
298 | The next two arguments are pointers to the `size` and `capacity` of the target array. |
731
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
299 | Tracking the capacity is optional. |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
300 | 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
|
301 | 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
|
302 | In this case, the function cannot copy more than `size-index` elements and if you try, it will return |
819
5da2ead43077
rename cx_array_copy_result to just cx_array_result
Mike Becker <universe@uap-core.de>
parents:
746
diff
changeset
|
303 | `CX_ARRAY_REALLOC_NOT_SUPPORTED` and do nothing. |
731
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
304 | |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
305 | 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
|
306 | `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
|
307 | Finally, the size, capacity, and the pointer to the array are all updated and the function returns |
819
5da2ead43077
rename cx_array_copy_result to just cx_array_result
Mike Becker <universe@uap-core.de>
parents:
746
diff
changeset
|
308 | `CX_ARRAY_SUCCESS`. |
731
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
309 | |
819
5da2ead43077
rename cx_array_copy_result to just cx_array_result
Mike Becker <universe@uap-core.de>
parents:
746
diff
changeset
|
310 | The third, but extremely rare, return code is `CX_ARRAY_REALLOC_FAILED` and speaks for itself. |
731
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
311 | |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
312 | A few things to note: |
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
313 | * `*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
|
314 | * `*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
|
315 | 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
|
316 | * `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
|
317 | * `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
|
318 | |
819
5da2ead43077
rename cx_array_copy_result to just cx_array_result
Mike Becker <universe@uap-core.de>
parents:
746
diff
changeset
|
319 | If you just want to add one single element to an existing array, you can use the macro `cx_array_add()`. |
5da2ead43077
rename cx_array_copy_result to just cx_array_result
Mike Becker <universe@uap-core.de>
parents:
746
diff
changeset
|
320 | In that case, since the element is added to the end of the array, the `capacity` argument is mandatory. |
731
9c097dabba2c
add documentation for the lists
Mike Becker <universe@uap-core.de>
parents:
730
diff
changeset
|
321 | |
720
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
322 | ## Map |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
323 | |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
324 | *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
|
325 | |
732 | 326 | Similar to the list interface, the map interface provides a common API for implementing maps. |
327 | There are some minor subtle differences, though. | |
328 | ||
329 | First, the `remove` method is not always a destructive removal. | |
330 | Instead, the last argument is a Boolean that indicates whether the element shall be destroyed or returned. | |
331 | ```c | |
332 | void *(*remove)(CxMap *map, CxHashKey key, bool destroy); | |
333 | ``` | |
334 | When you implement this method, you are either supposed to invoke the destructors and return `NULL`, | |
335 | or just remove the element from the map and return it. | |
336 | ||
337 | Secondly, the iterator method is a bit more complete. The signature is as follows: | |
338 | ```c | |
339 | CxIterator (*iterator)(CxMap const *map, enum cx_map_iterator_type type); | |
340 | ``` | |
341 | There are three map iterator types: for values, for keys, for pairs. | |
342 | Depending on the iterator type requested, you need to create an iterator with the correct methods that | |
343 | return the requested thing. | |
344 | There are no automatic checks to enforce this - it's completely up to you. | |
345 | If you need inspiration on how to do that, check the hash map implementation that comes with UCX. | |
346 | ||
720
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
347 | ### Hash Map |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
348 | |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
349 | *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
|
350 | |
732 | 351 | UCX provides a basic hash map implementation with a configurable amount of buckets. |
352 | If you do not specify the number of buckets, a default of 16 buckets will be used. | |
353 | You can always rehash the map with `cxMapRehash()` to change the number of buckets to something more efficient, | |
354 | but you need to be careful, because when you use this function you are effectively locking into using this | |
355 | specific hash map implementation, and you would need to remove all calls to this function when you want to | |
356 | exchange the concrete map implementation with something different. | |
357 | ||
720
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
358 | ## Utilities |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
359 | |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
360 | *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
|
361 | |
724
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
362 | 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
|
363 | 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
|
364 | an array. |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
365 | |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
366 | 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
|
367 | 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
|
368 | 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
|
369 | 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
|
370 | |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
371 | 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
|
372 | ```c |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
373 | FILE *inputfile = fopen(infilename, "r"); |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
374 | if (inputfile) { |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
375 | CxBuffer fbuf; |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
376 | 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
|
377 | cx_stream_copy(inputfile, &fbuf, |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
378 | (cx_read_func) fread, |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
379 | (cx_write_func) cxBufferWrite); |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
380 | fclose(inputfile); |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
381 | |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
382 | // ... 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
|
383 | |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
384 | cxBufferDestroy(&fbuf); |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
385 | } else { |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
386 | perror("Error opening input file"); |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
387 | if (fout != stdout) { |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
388 | fclose(fout); |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
389 | } |
5e7b1951dc80
add web docs for buffer and stream copy
Mike Becker <universe@uap-core.de>
parents:
723
diff
changeset
|
390 | } |
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 | |
720
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
393 | ### Printf Functions |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
394 | |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
395 | *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
|
396 | |
725
c9b882bef838
add docs for the compare.h and printf.h utilities
Mike Becker <universe@uap-core.de>
parents:
724
diff
changeset
|
397 | 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
|
398 | 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
|
399 | 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
|
400 | 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
|
401 | 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
|
402 | |
720
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
403 | ### Compare Functions |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
404 | |
f73adc75e50a
add empty sections to features.md
Mike Becker <universe@uap-core.de>
parents:
716
diff
changeset
|
405 | *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
|
406 | |
c9b882bef838
add docs for the compare.h and printf.h utilities
Mike Becker <universe@uap-core.de>
parents:
724
diff
changeset
|
407 | 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
|
408 | Their signatures are designed to be compatible with the `cx_compare_func` function pointer type. |