ZLIST(3)

✨ ZLIST(3) ✨ β€” it's giving generic list container, bestie πŸ’…

okay so this is a page from the CZMQ Manual and it's literally about zlist, a class for a simple generic list container. she's stable, she's iconic, she holds your void *s, let's GO πŸ¦‹


🌸 NAME 🌸

zlist β€” class for simple generic list container. no cap, that's the whole vibe. πŸ‘‘


πŸŽ€ SYNOPSIS πŸŽ€

heads up bestie: this is a stable class, and may not change except for emergencies. it's provided in stable builds. periodt.

first, the function-pointer typedefs, because we're fancy like that:

// Comparison function e.g. for sorting and removing.
typedef int (zlist_compare_fn) (
    void *item1, void *item2);

// Callback function for zlist_freefn method
typedef void (zlist_free_fn) (
    void *data);

πŸ’– creating and destroying πŸ’–

  • zlist_new β€” make a brand new list container, fresh out the box ✨
//  Create a new list container
CZMQ_EXPORT zlist_t *
    zlist_new (void);
  • zlist_destroy β€” bye bye list container, destroy her 🫢
//  Destroy a list container
CZMQ_EXPORT void
    zlist_destroy (zlist_t **self_p);

πŸ¦‹ walking through the list πŸ¦‹

  • zlist_first β€” hands you the item at the head of the list. if the list is empty you get NULL. the cursor is left pointing at the head item, or NULL if the list is empty πŸ‘€
//  Return the item at the head of list. If the list is empty, returns NULL.
//  Leaves cursor pointing at the head item, or NULL if the list is empty.
CZMQ_EXPORT void *
    zlist_first (zlist_t *self);
  • zlist_next β€” gives you the next item. empty list = NULL. wanna jump back to the start? call zlist_first (). this advances the cursor, lowkey important πŸƒβ€β™€οΈ
//  Return the next item. If the list is empty, returns NULL. To move to
//  the start of the list call zlist_first (). Advances the cursor.
CZMQ_EXPORT void *
    zlist_next (zlist_t *self);
  • zlist_last β€” item at the tail of the list, NULL if she's empty. cursor ends up on the tail item, or NULL if the list is empty πŸ’œ
//  Return the item at the tail of list. If the list is empty, returns NULL.
//  Leaves cursor pointing at the tail item, or NULL if the list is empty.
CZMQ_EXPORT void *
    zlist_last (zlist_t *self);
  • zlist_head β€” first item in the list, or null. and this one leaves the cursor alone, she's respectful like that πŸ™ˆ
//  Return first item in the list, or null, leaves the cursor
CZMQ_EXPORT void *
    zlist_head (zlist_t *self);
  • zlist_tail β€” last item in the list, or null, also leaves the cursor untouched πŸŽ€
//  Return last item in the list, or null, leaves the cursor
CZMQ_EXPORT void *
    zlist_tail (zlist_t *self);
  • zlist_item β€” whatever the cursor is currently on. empty list? NULL. cursor stays on the current item, or NULL if the list is empty πŸ‘‘
//  Return the current item of list. If the list is empty, returns NULL.
//  Leaves cursor pointing at the current item, or NULL if the list is empty.
CZMQ_EXPORT void *
    zlist_item (zlist_t *self);

🌈 adding and removing stuff 🌈

  • zlist_append β€” shove an item onto the end of the list. returns 0 if it went fine, or -1 if it failed for some reason (out of memory 😭). note: if a duplicator has been set, this method will also duplicate the item πŸ“
//  Append an item to the end of the list, return 0 if OK or -1 if this
//  failed for some reason (out of memory). Note that if a duplicator has
//  been set, this method will also duplicate the item.
CZMQ_EXPORT int
    zlist_append (zlist_t *self, void *item);
  • zlist_push β€” push an item to the start of the list. 0 if OK, -1 if it failed for some reason (out of memory 😭). same deal: if a duplicator has been set, this method will also duplicate the item πŸ’…
//  Push an item to the start of the list, return 0 if OK or -1 if this
//  failed for some reason (out of memory). Note that if a duplicator has
//  been set, this method will also duplicate the item.
CZMQ_EXPORT int
    zlist_push (zlist_t *self, void *item);
  • zlist_pop β€” pop the item off the start of the list, if there is one ✨
//  Pop the item off the start of the list, if any
CZMQ_EXPORT void *
    zlist_pop (zlist_t *self);
  • zlist_exists β€” is this item already in here? she uses the compare method to figure out if items are equal. if the compare method is NULL, the check will only compare pointers. returns true if the item is present, else false πŸ”₯
//  Checks if an item already is present. Uses compare method to determine if
//  items are equal. If the compare method is NULL the check will only compare
//  pointers. Returns true if item is present else false.
CZMQ_EXPORT bool
    zlist_exists (zlist_t *self, void *item);
  • zlist_remove β€” remove that specific item from the list if she's in there 🧚
//  Remove the specified item from the list if present
CZMQ_EXPORT void
    zlist_remove (zlist_t *self, void *item);
  • zlist_dup β€” make a copy of the list. if the list has autofree set, the copied list will duplicate all items, which must be strings. otherwise, the list will hold pointers back to the items in the original list. if the list is null, returns NULL.
πŸ‘‘ the caller owns the return value and must destroy it when done. don't forget bestie, that's a leak otherwise.
//  Make a copy of list. If the list has autofree set, the copied list will
//  duplicate all items, which must be strings. Otherwise, the list will hold
//  pointers back to the items in the original list. If list is null, returns
//  NULL.
//  Caller owns return value and must destroy it when done.
CZMQ_EXPORT zlist_t *
    zlist_dup (zlist_t *self);
  • zlist_purge β€” purge all items from the list. every last one πŸ’€
//  Purge all items from list
CZMQ_EXPORT void
    zlist_purge (zlist_t *self);
  • zlist_size β€” how many items are in the list? she'll tell you πŸŽ€
//  Return number of items in the list
CZMQ_EXPORT size_t
    zlist_size (zlist_t *self);

⭐ sorting & configuring ⭐

  • zlist_sort β€” sort the list. if the compare function is null, she sorts by ascending key value using a straight ASCII comparison. if you specify a compare function, that decides how items get sorted. the sort is not stable, so it may reorder items with the same keys 😭. the algorithm used is combsort, a compromise between performance and simplicity.
//  Sort the list. If the compare function is null, sorts the list by
//  ascending key value using a straight ASCII comparison. If you specify
//  a compare function, this decides how items are sorted. The sort is not
//  stable, so may reorder items with the same keys. The algorithm used is
//  combsort, a compromise between performance and simplicity.
CZMQ_EXPORT void
    zlist_sort (zlist_t *self, zlist_compare_fn compare);
  • zlist_autofree β€” set the list up for automatic item destruction. item values MUST be strings. by default a list item refers to a value held elsewhere. when you set this, each time you append or push a list item, zlist will take a copy of the string value. then, when you destroy the list, it will free all item values automatically. if you use any other technique to allocate list values, you must free them explicitly before destroying the list. the usual technique is to pop list items and destroy them, until the list is empty 🫢
//  Set list for automatic item destruction; item values MUST be strings.
//  By default a list item refers to a value held elsewhere. When you set
//  this, each time you append or push a list item, zlist will take a copy
//  of the string value. Then, when you destroy the list, it will free all
//  item values automatically. If you use any other technique to allocate
//  list values, you must free them explicitly before destroying the list.
//  The usual technique is to pop list items and destroy them, until the
//  list is empty.
CZMQ_EXPORT void
    zlist_autofree (zlist_t *self);
  • zlist_comparefn β€” sets a compare function for this list. the function compares two items. it returns an integer less than, equal to, or greater than zero if the first item is found, respectively, to be less than, to match, or be greater than the second item.

this function is used for sorting, removal and exists checking πŸ”₯

//  Sets a compare function for this list. The function compares two items.
//  It returns an integer less than, equal to, or greater than zero if the
//  first item is found, respectively, to be less than, to match, or be
//  greater than the second item.
//  This function is used for sorting, removal and exists checking.
CZMQ_EXPORT void
    zlist_comparefn (zlist_t *self, zlist_compare_fn fn);
  • zlist_freefn β€” set a free function for the specified list item. when the item is destroyed, the free function, if any, is called on that item. use this when list items are dynamically allocated, to ensure that you don't have memory leaks. you can pass free or NULL as a free_fn. returns the item, or NULL if there is no such item πŸ’œ
//  Set a free function for the specified list item. When the item is
//  destroyed, the free function, if any, is called on that item.
//  Use this when list items are dynamically allocated, to ensure that
//  you don't have memory leaks. You can pass 'free' or NULL as a free_fn.
//  Returns the item, or NULL if there is no such item.
CZMQ_EXPORT void *
    zlist_freefn (zlist_t *self, void *item, zlist_free_fn fn, bool at_tail);

πŸ’… the self test πŸ’…

  • zlist_test β€” self test of this class. run it, she checks herself πŸ’–
//  Self test of this class.
CZMQ_EXPORT void
    zlist_test (bool verbose);
πŸ“ tiny note that was in the original: Please add '@interface' section in './../src/zlist.c'.

πŸ’– DESCRIPTION πŸ’–

she provides a generic container implementing a fast singly-linked list. you can use this to construct multi-dimensional lists, and other structures together with other generic containers like zhash. this is a simple class. for demanding applications we recommend using zlistx β€” no shade, she's just built different πŸ”₯

to iterate through a list, use zlist_first to get the first item, then loop while not null, and do zlist_next at the end of each iteration. that's the whole dance, bestie 🧚


🌈 EXAMPLE 🌈

from the zlist_test method. yes it's long. no we're not skipping any of it. sit down, hydrate, enjoy πŸ“

zlist_t *list = zlist_new ();
assert (list);
assert (zlist_size (list) == 0);

//  Three items we'll use as test data
//  List items are void *, not particularly strings
char *cheese = "boursin";
char *bread = "baguette";
char *wine = "bordeaux";

zlist_append (list, cheese);
assert (zlist_size (list) == 1);
assert ( zlist_exists (list, cheese));
assert (!zlist_exists (list, bread));
assert (!zlist_exists (list, wine));
zlist_append (list, bread);
assert (zlist_size (list) == 2);
assert ( zlist_exists (list, cheese));
assert ( zlist_exists (list, bread));
assert (!zlist_exists (list, wine));
zlist_append (list, wine);
assert (zlist_size (list) == 3);
assert ( zlist_exists (list, cheese));
assert ( zlist_exists (list, bread));
assert ( zlist_exists (list, wine));

assert (zlist_head (list) == cheese);
assert (zlist_next (list) == cheese);

assert (zlist_first (list) == cheese);
assert (zlist_tail (list) == wine);
assert (zlist_next (list) == bread);

assert (zlist_first (list) == cheese);
assert (zlist_next (list) == bread);
assert (zlist_next (list) == wine);
assert (zlist_next (list) == NULL);
//  After we reach end of list, next wraps around
assert (zlist_next (list) == cheese);
assert (zlist_size (list) == 3);

zlist_remove (list, wine);
assert (zlist_size (list) == 2);

assert (zlist_first (list) == cheese);
zlist_remove (list, cheese);
assert (zlist_size (list) == 1);
assert (zlist_first (list) == bread);

zlist_remove (list, bread);
assert (zlist_size (list) == 0);

zlist_append (list, cheese);
zlist_append (list, bread);
assert (zlist_last (list) == bread);
zlist_remove (list, bread);
assert (zlist_last (list) == cheese);
zlist_remove (list, cheese);
assert (zlist_last (list) == NULL);

zlist_push (list, cheese);
assert (zlist_size (list) == 1);
assert (zlist_first (list) == cheese);

zlist_push (list, bread);
assert (zlist_size (list) == 2);
assert (zlist_first (list) == bread);
assert (zlist_item (list) == bread);

zlist_append (list, wine);
assert (zlist_size (list) == 3);
assert (zlist_first (list) == bread);

zlist_t *sub_list = zlist_dup (list);
assert (sub_list);
assert (zlist_size (sub_list) == 3);

zlist_sort (list, NULL);
char *item;
item = (char *) zlist_pop (list);
assert (item == bread);
item = (char *) zlist_pop (list);
assert (item == wine);
item = (char *) zlist_pop (list);
assert (item == cheese);
assert (zlist_size (list) == 0);

assert (zlist_size (sub_list) == 3);
zlist_push (list, sub_list);
zlist_t *sub_list_2 = zlist_dup (sub_list);
zlist_append (list, sub_list_2);
assert (zlist_freefn (list, sub_list, &s_zlist_free, false) == sub_list);
assert (zlist_freefn (list, sub_list_2, &s_zlist_free, true) == sub_list_2);
zlist_destroy (&list);

//  Test autofree functionality
list = zlist_new ();
assert (list);
zlist_autofree (list);
//  Set equals function otherwise equals will not work as autofree copies strings
zlist_comparefn (list, (zlist_compare_fn *) strcmp);
zlist_push (list, bread);
zlist_append (list, cheese);
assert (zlist_size (list) == 2);
zlist_append (list, wine);
assert (zlist_exists (list, wine));
zlist_remove (list, wine);
assert (!zlist_exists (list, wine));
assert (streq ((const char *) zlist_first (list), bread));
item = (char *) zlist_pop (list);
assert (streq (item, bread));
freen (item);
item = (char *) zlist_pop (list);
assert (streq (item, cheese));
freen (item);

zlist_destroy (&list);
assert (list == NULL);

#if defined (__WINDOWS__)
zsys_shutdown();
#endif

🫢 AUTHORS 🫢

the czmq manual was written by the authors in the AUTHORS file. give them their flowers, they earned them πŸ‘‘


🌐 RESOURCES 🌐

main web site:

report bugs to the email <zeromq-dev@lists.zeromq.org[1]> πŸ“¬


copyright (c) the Contributors as noted in the AUTHORS file. this file is part of CZMQ, the high-level C binding for 0MQ: http://czmq.zeromq.org. this Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. if a copy of the MPL was not distributed with this file, you can obtain one at http://mozilla.org/MPL/2.0/. LICENSE included with the czmq distribution. legal queen behavior, periodt πŸ’…


πŸ—’οΈ NOTES πŸ—’οΈ

  1. zeromq-dev@lists.zeromq.org mailto:zeromq-dev@lists.zeromq.org

okay bestie that's the whole page πŸŽ€ this one's from CZMQ 4.2.1, dated 01/16/2026, and it's literally giving ZLIST(3) energy. go build a linked list, you main character βœ¨πŸ¦‹πŸ’–

πŸ“¦ where this page comes from