1ZLISTX(3) CZMQ Manual ZLISTX(3)
2
3
4
6 zlistx - Class for extended generic list container
7
9 // This is a stable class, and may not change except for emergencies. It
10 // is provided in stable builds.
11 // Destroy an item
12 typedef void (zlistx_destructor_fn) (
13 void **item);
14
15 // Duplicate an item
16 typedef void * (zlistx_duplicator_fn) (
17 const void *item);
18
19 // Compare two items, for sorting
20 typedef int (zlistx_comparator_fn) (
21 const void *item1, const void *item2);
22
23 // Create a new, empty list.
24 CZMQ_EXPORT zlistx_t *
25 zlistx_new (void);
26
27 // Destroy a list. If an item destructor was specified, all items in the
28 // list are automatically destroyed as well.
29 CZMQ_EXPORT void
30 zlistx_destroy (zlistx_t **self_p);
31
32 // Add an item to the head of the list. Calls the item duplicator, if any,
33 // on the item. Resets cursor to list head. Returns an item handle on
34 // success, NULL if memory was exhausted.
35 CZMQ_EXPORT void *
36 zlistx_add_start (zlistx_t *self, void *item);
37
38 // Add an item to the tail of the list. Calls the item duplicator, if any,
39 // on the item. Resets cursor to list head. Returns an item handle on
40 // success, NULL if memory was exhausted.
41 CZMQ_EXPORT void *
42 zlistx_add_end (zlistx_t *self, void *item);
43
44 // Return the number of items in the list
45 CZMQ_EXPORT size_t
46 zlistx_size (zlistx_t *self);
47
48 // Return first item in the list, or null, leaves the cursor
49 CZMQ_EXPORT void *
50 zlistx_head (zlistx_t *self);
51
52 // Return last item in the list, or null, leaves the cursor
53 CZMQ_EXPORT void *
54 zlistx_tail (zlistx_t *self);
55
56 // Return the item at the head of list. If the list is empty, returns NULL.
57 // Leaves cursor pointing at the head item, or NULL if the list is empty.
58 CZMQ_EXPORT void *
59 zlistx_first (zlistx_t *self);
60
61 // Return the next item. At the end of the list (or in an empty list),
62 // returns NULL. Use repeated zlistx_next () calls to work through the list
63 // from zlistx_first (). First time, acts as zlistx_first().
64 CZMQ_EXPORT void *
65 zlistx_next (zlistx_t *self);
66
67 // Return the previous item. At the start of the list (or in an empty list),
68 // returns NULL. Use repeated zlistx_prev () calls to work through the list
69 // backwards from zlistx_last (). First time, acts as zlistx_last().
70 CZMQ_EXPORT void *
71 zlistx_prev (zlistx_t *self);
72
73 // Return the item at the tail of list. If the list is empty, returns NULL.
74 // Leaves cursor pointing at the tail item, or NULL if the list is empty.
75 CZMQ_EXPORT void *
76 zlistx_last (zlistx_t *self);
77
78 // Returns the value of the item at the cursor, or NULL if the cursor is
79 // not pointing to an item.
80 CZMQ_EXPORT void *
81 zlistx_item (zlistx_t *self);
82
83 // Returns the handle of the item at the cursor, or NULL if the cursor is
84 // not pointing to an item.
85 CZMQ_EXPORT void *
86 zlistx_cursor (zlistx_t *self);
87
88 // Returns the item associated with the given list handle, or NULL if passed
89 // in handle is NULL. Asserts that the passed in handle points to a list element.
90 CZMQ_EXPORT void *
91 zlistx_handle_item (void *handle);
92
93 // Find an item in the list, searching from the start. Uses the item
94 // comparator, if any, else compares item values directly. Returns the
95 // item handle found, or NULL. Sets the cursor to the found item, if any.
96 CZMQ_EXPORT void *
97 zlistx_find (zlistx_t *self, void *item);
98
99 // Detach an item from the list, using its handle. The item is not modified,
100 // and the caller is responsible for destroying it if necessary. If handle is
101 // null, detaches the first item on the list. Returns item that was detached,
102 // or null if none was. If cursor was at item, moves cursor to previous item,
103 // so you can detach items while iterating forwards through a list.
104 CZMQ_EXPORT void *
105 zlistx_detach (zlistx_t *self, void *handle);
106
107 // Detach item at the cursor, if any, from the list. The item is not modified,
108 // and the caller is responsible for destroying it as necessary. Returns item
109 // that was detached, or null if none was. Moves cursor to previous item, so
110 // you can detach items while iterating forwards through a list.
111 CZMQ_EXPORT void *
112 zlistx_detach_cur (zlistx_t *self);
113
114 // Delete an item, using its handle. Calls the item destructor is any is
115 // set. If handle is null, deletes the first item on the list. Returns 0
116 // if an item was deleted, -1 if not. If cursor was at item, moves cursor
117 // to previous item, so you can delete items while iterating forwards
118 // through a list.
119 CZMQ_EXPORT int
120 zlistx_delete (zlistx_t *self, void *handle);
121
122 // Move an item to the start of the list, via its handle.
123 CZMQ_EXPORT void
124 zlistx_move_start (zlistx_t *self, void *handle);
125
126 // Move an item to the end of the list, via its handle.
127 CZMQ_EXPORT void
128 zlistx_move_end (zlistx_t *self, void *handle);
129
130 // Remove all items from the list, and destroy them if the item destructor
131 // is set.
132 CZMQ_EXPORT void
133 zlistx_purge (zlistx_t *self);
134
135 // Sort the list. If an item comparator was set, calls that to compare
136 // items, otherwise compares on item value. The sort is not stable, so may
137 // reorder equal items.
138 CZMQ_EXPORT void
139 zlistx_sort (zlistx_t *self);
140
141 // Create a new node and insert it into a sorted list. Calls the item
142 // duplicator, if any, on the item. If low_value is true, starts searching
143 // from the start of the list, otherwise searches from the end. Use the item
144 // comparator, if any, to find where to place the new node. Returns a handle
145 // to the new node, or NULL if memory was exhausted. Resets the cursor to the
146 // list head.
147 CZMQ_EXPORT void *
148 zlistx_insert (zlistx_t *self, void *item, bool low_value);
149
150 // Move an item, specified by handle, into position in a sorted list. Uses
151 // the item comparator, if any, to determine the new location. If low_value
152 // is true, starts searching from the start of the list, otherwise searches
153 // from the end.
154 CZMQ_EXPORT void
155 zlistx_reorder (zlistx_t *self, void *handle, bool low_value);
156
157 // Make a copy of the list; items are duplicated if you set a duplicator
158 // for the list, otherwise not. Copying a null reference returns a null
159 // reference.
160 CZMQ_EXPORT zlistx_t *
161 zlistx_dup (zlistx_t *self);
162
163 // Set a user-defined deallocator for list items; by default items are not
164 // freed when the list is destroyed.
165 CZMQ_EXPORT void
166 zlistx_set_destructor (zlistx_t *self, zlistx_destructor_fn destructor);
167
168 // Set a user-defined duplicator for list items; by default items are not
169 // copied when the list is duplicated.
170 CZMQ_EXPORT void
171 zlistx_set_duplicator (zlistx_t *self, zlistx_duplicator_fn duplicator);
172
173 // Set a user-defined comparator for zlistx_find and zlistx_sort; the method
174 // must return -1, 0, or 1 depending on whether item1 is less than, equal to,
175 // or greater than, item2.
176 CZMQ_EXPORT void
177 zlistx_set_comparator (zlistx_t *self, zlistx_comparator_fn comparator);
178
179 // Self test of this class.
180 CZMQ_EXPORT void
181 zlistx_test (bool verbose);
182
183 Please add '@interface' section in './../src/zlistx.c'.
184
186 Provides a generic doubly-linked list container. This container
187 provides hooks for duplicator, comparator, and destructor functions.
188 These tie into CZMQ and standard C semantics, so e.g. for string items
189 you can use strdup, strcmp, and zstr_free. To store custom objects,
190 define your own duplicator and comparator, and use the standard object
191 destructor.
192
193 This is a reworking of the simpler zlist container. It is faster to
194 insert and delete items anywhere in the list, and to keep ordered
195 lists.
196
198 From zlistx_test method.
199
200 zlistx_t *list = zlistx_new ();
201 assert (list);
202 assert (zlistx_size (list) == 0);
203
204 // Test operations on an empty list
205 assert (zlistx_first (list) == NULL);
206 assert (zlistx_last (list) == NULL);
207 assert (zlistx_next (list) == NULL);
208 assert (zlistx_prev (list) == NULL);
209 assert (zlistx_find (list, "hello") == NULL);
210 assert (zlistx_delete (list, NULL) == -1);
211 assert (zlistx_detach (list, NULL) == NULL);
212 assert (zlistx_delete (list, NULL) == -1);
213 assert (zlistx_detach (list, NULL) == NULL);
214 zlistx_purge (list);
215 zlistx_sort (list);
216
217 // Use item handlers
218 zlistx_set_destructor (list, (zlistx_destructor_fn *) zstr_free);
219 zlistx_set_duplicator (list, (zlistx_duplicator_fn *) strdup);
220 zlistx_set_comparator (list, (zlistx_comparator_fn *) strcmp);
221
222 // Try simple insert/sort/delete/next
223 assert (zlistx_next (list) == NULL);
224 zlistx_add_end (list, "world");
225 assert (streq ((char *) zlistx_next (list), "world"));
226 zlistx_add_end (list, "hello");
227 assert (streq ((char *) zlistx_prev (list), "hello"));
228 zlistx_sort (list);
229 assert (zlistx_size (list) == 2);
230 void *handle = zlistx_find (list, "hello");
231 char *item1 = (char *) zlistx_item (list);
232 char *item2 = (char *) zlistx_handle_item (handle);
233 assert (item1 == item2);
234 assert (streq (item1, "hello"));
235 zlistx_delete (list, handle);
236 assert (zlistx_size (list) == 1);
237 char *string = (char *) zlistx_detach (list, NULL);
238 assert (streq (string, "world"));
239 freen (string);
240 assert (zlistx_size (list) == 0);
241
242 // Check next/back work
243 // Now populate the list with items
244 zlistx_add_start (list, "five");
245 zlistx_add_end (list, "six");
246 zlistx_add_start (list, "four");
247 zlistx_add_end (list, "seven");
248 zlistx_add_start (list, "three");
249 zlistx_add_end (list, "eight");
250 zlistx_add_start (list, "two");
251 zlistx_add_end (list, "nine");
252 zlistx_add_start (list, "one");
253 zlistx_add_end (list, "ten");
254
255 // Test our navigation skills
256 assert (zlistx_size (list) == 10);
257 assert (streq ((char *) zlistx_last (list), "ten"));
258 assert (streq ((char *) zlistx_prev (list), "nine"));
259 assert (streq ((char *) zlistx_prev (list), "eight"));
260 assert (streq ((char *) zlistx_prev (list), "seven"));
261 assert (streq ((char *) zlistx_prev (list), "six"));
262 assert (streq ((char *) zlistx_prev (list), "five"));
263 assert (streq ((char *) zlistx_first (list), "one"));
264 assert (streq ((char *) zlistx_next (list), "two"));
265 assert (streq ((char *) zlistx_next (list), "three"));
266 assert (streq ((char *) zlistx_next (list), "four"));
267
268 // Sort by alphabetical order
269 zlistx_sort (list);
270 assert (streq ((char *) zlistx_first (list), "eight"));
271 assert (streq ((char *) zlistx_last (list), "two"));
272
273 // Moving items around
274 handle = zlistx_find (list, "six");
275 zlistx_move_start (list, handle);
276 assert (streq ((char *) zlistx_first (list), "six"));
277 zlistx_move_end (list, handle);
278 assert (streq ((char *) zlistx_last (list), "six"));
279 zlistx_sort (list);
280 assert (streq ((char *) zlistx_last (list), "two"));
281
282 // Copying a list
283 zlistx_t *copy = zlistx_dup (list);
284 assert (copy);
285 assert (zlistx_size (copy) == 10);
286 assert (streq ((char *) zlistx_first (copy), "eight"));
287 assert (streq ((char *) zlistx_last (copy), "two"));
288 zlistx_destroy (©);
289
290 // Delete items while iterating
291 string = (char *) zlistx_first (list);
292 assert (streq (string, "eight"));
293 string = (char *) zlistx_next (list);
294 assert (streq (string, "five"));
295 zlistx_delete (list, zlistx_cursor (list));
296 string = (char *) zlistx_next (list);
297 assert (streq (string, "four"));
298
299 zlistx_purge (list);
300 zlistx_destroy (&list);
301
302 #if defined (__WINDOWS__)
303 zsys_shutdown();
304 #endif
305
306
308 The czmq manual was written by the authors in the AUTHORS file.
309
311 Main web site:
312
313 Report bugs to the email <zeromq-dev@lists.zeromq.org[1]>
314
316 Copyright (c) the Contributors as noted in the AUTHORS file. This file
317 is part of CZMQ, the high-level C binding for 0MQ:
318 http://czmq.zeromq.org. This Source Code Form is subject to the terms
319 of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
320 distributed with this file, You can obtain one at
321 http://mozilla.org/MPL/2.0/. LICENSE included with the czmq
322 distribution.
323
325 1. zeromq-dev@lists.zeromq.org
326 mailto:zeromq-dev@lists.zeromq.org
327
328
329
330CZMQ 4.1.1 07/24/2019 ZLISTX(3)