Skip site navigation (1)Skip section navigation (2)

  
 
  

home | help
ZLISTX(3)			   CZMQ Manual			       ZLISTX(3)

NAME
     zlistx - Class for extended generic list container

SYNOPSIS
     //  This is a stable class, and may not change except for emergencies. It
     //  is provided in stable builds.
     //  This class has draft methods, which may change over time. They are not
     //  in stable releases, by default. Use --enable-drafts to enable.
     // Destroy an item
     typedef void (zlistx_destructor_fn) (
	 void **item);

     // Duplicate an item
     typedef void * (zlistx_duplicator_fn) (
	 const void *item);

     // Compare two items, for sorting
     typedef int (zlistx_comparator_fn) (
	 const void *item1, const void *item2);

     //  Create a new, empty list.
     CZMQ_EXPORT zlistx_t *
	 zlistx_new (void);

     //  Destroy a list. If an item destructor was specified, all items in the
     //  list are automatically destroyed as well.
     CZMQ_EXPORT void
	 zlistx_destroy (zlistx_t **self_p);

     //  Add an item to the head of the list. Calls the item duplicator, if any,
     //  on the item. Resets cursor to list head. Returns an item handle on
     //  success, NULL if memory was exhausted.
     CZMQ_EXPORT void *
	 zlistx_add_start (zlistx_t *self, void *item);

     //  Add an item to the tail of the list. Calls the item duplicator, if any,
     //  on the item. Resets cursor to list head. Returns an item handle on
     //  success, NULL if memory was exhausted.
     CZMQ_EXPORT void *
	 zlistx_add_end (zlistx_t *self, void *item);

     //  Return the number of items in the list
     CZMQ_EXPORT size_t
	 zlistx_size (zlistx_t *self);

     //  Return first item in the list, or null, leaves the cursor
     CZMQ_EXPORT void *
	 zlistx_head (zlistx_t *self);

     //  Return last item in the list, or null, leaves the cursor
     CZMQ_EXPORT void *
	 zlistx_tail (zlistx_t *self);

     //  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 *
	 zlistx_first (zlistx_t *self);

     //  Return the next item. At the end of the list (or in an empty list),
     //  returns NULL. Use repeated zlistx_next () calls to work through the list
     //  from zlistx_first (). First time, acts as zlistx_first().
     CZMQ_EXPORT void *
	 zlistx_next (zlistx_t *self);

     //  Return the previous item. At the start of the list (or in an empty list),
     //  returns NULL. Use repeated zlistx_prev () calls to work through the list
     //  backwards from zlistx_last (). First time, acts as zlistx_last().
     CZMQ_EXPORT void *
	 zlistx_prev (zlistx_t *self);

     //  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 *
	 zlistx_last (zlistx_t *self);

     //  Returns the value of the item at the cursor, or NULL if the cursor is
     //  not pointing to an item.
     CZMQ_EXPORT void *
	 zlistx_item (zlistx_t *self);

     //  Returns the handle of the item at the cursor, or NULL if the cursor is
     //  not pointing to an item.
     CZMQ_EXPORT void *
	 zlistx_cursor (zlistx_t *self);

     //  Returns the item associated with the given list handle, or NULL if passed
     //  in handle is NULL. Asserts that the passed in handle points to a list element.
     CZMQ_EXPORT void *
	 zlistx_handle_item (void *handle);

     //  Find an item in the list, searching from the start. Uses the item
     //  comparator, if any, else compares item values directly. Returns the
     //  item handle found, or NULL. Sets the cursor to the found item, if any.
     CZMQ_EXPORT void *
	 zlistx_find (zlistx_t *self, void *item);

     //  Detach an item from the list, using its handle. The item is not modified,
     //  and the caller is responsible for destroying it if necessary. If handle is
     //  null, detaches the first item on the list. Returns item that was detached,
     //  or null if none was. If cursor was at item, moves cursor to previous item,
     //  so you can detach items while iterating forwards through a list.
     CZMQ_EXPORT void *
	 zlistx_detach (zlistx_t *self, void *handle);

     //  Detach item at the cursor, if any, from the list. The item is not modified,
     //  and the caller is responsible for destroying it as necessary. Returns item
     //  that was detached, or null if none was. Moves cursor to previous item, so
     //  you can detach items while iterating forwards through a list.
     CZMQ_EXPORT void *
	 zlistx_detach_cur (zlistx_t *self);

     //  Delete an item, using its handle. Calls the item destructor if any is
     //  set. If handle is null, deletes the first item on the list. Returns 0
     //  if an item was deleted, -1 if not. If cursor was at item, moves cursor
     //  to previous item, so you can delete items while iterating forwards
     //  through a list.
     CZMQ_EXPORT int
	 zlistx_delete (zlistx_t *self, void *handle);

     //  Move an item to the start of the list, via its handle.
     CZMQ_EXPORT void
	 zlistx_move_start (zlistx_t *self, void *handle);

     //  Move an item to the end of the list, via its handle.
     CZMQ_EXPORT void
	 zlistx_move_end (zlistx_t *self, void *handle);

     //  Remove all items from the list, and destroy them if the item destructor
     //  is set.
     CZMQ_EXPORT void
	 zlistx_purge (zlistx_t *self);

     //  Sort the list. If an item comparator was set, calls that to compare
     //  items, otherwise compares on item value. The sort is not stable, so may
     //  reorder equal items.
     CZMQ_EXPORT void
	 zlistx_sort (zlistx_t *self);

     //  Create a new node and insert it into a sorted list. Calls the item
     //  duplicator, if any, on the item. If low_value is true, starts searching
     //  from the start of the list, otherwise searches from the end. Use the item
     //  comparator, if any, to find where to place the new node. Returns a handle
     //  to the new node, or NULL if memory was exhausted. Resets the cursor to the
     //  list head.
     CZMQ_EXPORT void *
	 zlistx_insert (zlistx_t *self, void *item, bool low_value);

     //  Move an item, specified by handle, into position in a sorted list. Uses
     //  the item comparator, if any, to determine the new location. If low_value
     //  is true, starts searching from the start of the list, otherwise searches
     //  from the end.
     CZMQ_EXPORT void
	 zlistx_reorder (zlistx_t *self, void *handle, bool low_value);

     //  Make a copy of the list; items are duplicated if you set a duplicator
     //  for the list, otherwise not. Copying a null reference returns a null
     //  reference.
     CZMQ_EXPORT zlistx_t *
	 zlistx_dup (zlistx_t *self);

     //  Set a user-defined deallocator for list items; by default items are not
     //  freed when the list is destroyed.
     CZMQ_EXPORT void
	 zlistx_set_destructor (zlistx_t *self, zlistx_destructor_fn destructor);

     //  Set a user-defined duplicator for list items; by default items are not
     //  copied when the list is duplicated.
     CZMQ_EXPORT void
	 zlistx_set_duplicator (zlistx_t *self, zlistx_duplicator_fn duplicator);

     //  Set a user-defined comparator for zlistx_find and zlistx_sort; the method
     //  must return -1, 0, or 1 depending on whether item1 is less than, equal to,
     //  or greater than, item2.
     CZMQ_EXPORT void
	 zlistx_set_comparator (zlistx_t *self, zlistx_comparator_fn comparator);

     //  Self test of this class.
     CZMQ_EXPORT void
	 zlistx_test (bool verbose);

     #ifdef CZMQ_BUILD_DRAFT_API
     //  *** Draft method, for development use, may change without warning ***
     //  Unpack binary frame into a new list. Packed data must follow format
     //  defined by zlistx_pack. List is set to autofree. An empty frame
     //  unpacks to an empty list.
     CZMQ_EXPORT zlistx_t *
	 zlistx_unpack (zframe_t *frame);

     //  *** Draft method, for development use, may change without warning ***
     //  Serialize list to a binary frame that can be sent in a message.
     //  The packed format is compatible with the 'strings' type implemented by zproto:
     //
     //     ; A list of strings
     //     list	    = list-count *longstr
     //     list-count	    = number-4
     //
     //     ; Strings are always length + text contents
     //     longstr	    = number-4 *VCHAR
     //
     //     ; Numbers are unsigned integers in network byte order
     //     number-4	    = 4OCTET
     //  Caller owns return value and must destroy it when done.
     CZMQ_EXPORT zframe_t *
	 zlistx_pack (zlistx_t *self);

     #endif // CZMQ_BUILD_DRAFT_API
     Please add '@interface' section in './../src/zlistx.c'.

DESCRIPTION
     Provides  a  generic  doubly-linked list container. This container provides
     hooks for duplicator, comparator, and destructor functions. These tie  into
     CZMQ and standard C semantics, so e.g. for string items you can use strdup,
     strcmp,  and zstr_free. To store custom objects, define your own duplicator
     and comparator, and use the standard object destructor.

     This is a reworking of the simpler zlist container. It is faster to  insert
     and delete items anywhere in the list, and to keep ordered lists.

EXAMPLE
     From zlistx_test method.

	 zlistx_t *list = zlistx_new ();
	 assert (list);
	 assert (zlistx_size (list) == 0);

	 //  Test operations on an empty list
	 assert (zlistx_head (list) == NULL);
	 assert (zlistx_first (list) == NULL);
	 assert (zlistx_last (list) == NULL);
	 assert (zlistx_next (list) == NULL);
	 assert (zlistx_prev (list) == NULL);
	 assert (zlistx_find (list, "hello") == NULL);
	 assert (zlistx_delete (list, NULL) == -1);
	 assert (zlistx_detach (list, NULL) == NULL);
	 assert (zlistx_delete (list, NULL) == -1);
	 assert (zlistx_detach (list, NULL) == NULL);
	 zlistx_purge (list);
	 zlistx_sort (list);

	 //  Use item handlers
	 zlistx_set_destructor (list, (zlistx_destructor_fn *) zstr_free);
	 zlistx_set_duplicator (list, (zlistx_duplicator_fn *) strdup);
	 zlistx_set_comparator (list, (zlistx_comparator_fn *) strcmp);

	 //  Try simple insert/sort/delete/next
	 assert (zlistx_next (list) == NULL);
	 zlistx_add_end (list, "world");
	 assert (streq ((char *) zlistx_next (list), "world"));
	 assert (streq ((char *) zlistx_head (list), "world"));
	 zlistx_add_end (list, "hello");
	 assert (streq ((char *) zlistx_prev (list), "hello"));
	 zlistx_sort (list);
	 assert (zlistx_size (list) == 2);
	 void *handle = zlistx_find (list, "hello");
	 char *item1 = (char *) zlistx_item (list);
	 char *item2 = (char *) zlistx_handle_item (handle);
	 assert (item1 == item2);
	 assert (streq (item1, "hello"));
	 zlistx_delete (list, handle);
	 assert (zlistx_size (list) == 1);
	 char *string = (char *) zlistx_detach (list, NULL);
	 assert (streq (string, "world"));
	 freen (string);
	 assert (zlistx_size (list) == 0);

	 //  Check next/back work
	 //  Now populate the list with items
	 zlistx_add_start (list, "five");
	 zlistx_add_end   (list, "six");
	 zlistx_add_start (list, "four");
	 zlistx_add_end   (list, "seven");
	 zlistx_add_start (list, "three");
	 zlistx_add_end   (list, "eight");
	 zlistx_add_start (list, "two");
	 zlistx_add_end   (list, "nine");
	 zlistx_add_start (list, "one");
	 zlistx_add_end   (list, "ten");

	 //  Test our navigation skills
	 assert (zlistx_size (list) == 10);
	 assert (streq ((char *) zlistx_last (list), "ten"));
	 assert (streq ((char *) zlistx_prev (list), "nine"));
	 assert (streq ((char *) zlistx_prev (list), "eight"));
	 assert (streq ((char *) zlistx_prev (list), "seven"));
	 assert (streq ((char *) zlistx_prev (list), "six"));
	 assert (streq ((char *) zlistx_prev (list), "five"));
	 assert (streq ((char *) zlistx_first (list), "one"));
	 assert (streq ((char *) zlistx_next (list), "two"));
	 assert (streq ((char *) zlistx_next (list), "three"));
	 assert (streq ((char *) zlistx_next (list), "four"));

	 //  Sort by alphabetical order
	 zlistx_sort (list);
	 assert (streq ((char *) zlistx_first (list), "eight"));
	 assert (streq ((char *) zlistx_last (list), "two"));

	 //  Moving items around
	 handle = zlistx_find (list, "six");
	 zlistx_move_start (list, handle);
	 assert (streq ((char *) zlistx_first (list), "six"));
	 zlistx_move_end (list, handle);
	 assert (streq ((char *) zlistx_last (list), "six"));
	 zlistx_sort (list);
	 assert (streq ((char *) zlistx_last (list), "two"));

	 //  Copying a list
	 zlistx_t *copy = zlistx_dup (list);
	 assert (copy);
	 assert (zlistx_size (copy) == 10);
	 assert (streq ((char *) zlistx_first (copy), "eight"));
	 assert (streq ((char *) zlistx_last (copy), "two"));
	 zlistx_destroy (&copy);

	 //  Delete items while iterating
	 string = (char *) zlistx_first (list);
	 assert (streq (string, "eight"));
	 string = (char *) zlistx_next (list);
	 assert (streq (string, "five"));
	 zlistx_delete (list, zlistx_cursor (list));
	 string = (char *) zlistx_next (list);
	 assert (streq (string, "four"));

	 //  Test pack/unpack methods
	 zframe_t *frame = zlistx_pack (list);
	 copy = zlistx_unpack (frame);
	 assert (copy);
	 zframe_destroy (&frame);
	 assert (zlistx_size (copy) == zlistx_size (list));

	 char *item_orig = (char *) zlistx_first (list);
	 char *item_copy = (char *) zlistx_first (copy);
	 while (item_orig) {
	     assert (strcmp(item_orig, item_copy) == 0);
	     item_orig = (char *) zlistx_next (list);
	     item_copy = (char *) zlistx_next (copy);
	 }

	 zlistx_destroy (&copy);

	 zlistx_purge (list);
	 zlistx_destroy (&list);

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

AUTHORS
     The czmq manual was written by the authors in the AUTHORS file.

RESOURCES
     Main web site:

     Report bugs to the email <zeromq-dev@lists.zeromq.org[1]>

COPYRIGHT
     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 Li-
     cense, 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.

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

CZMQ 4.2.1			   08/27/2026			       ZLISTX(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=zlistx&sektion=3&manpath=FreeBSD+Ports+15.1.quarterly>

home | help