1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
|
/*******************************************************************************
*
* HEADER: list
*
********************************************************************************
*
* DESCRIPTION: Generic routines for a doubly linked ring list
*
********************************************************************************
*
* Copyright (c) 2002-2024 Marcus Holland-Moritz. All rights reserved.
* This program is free software; you can redistribute it and/or modify
* it under the same terms as Perl itself.
*
*******************************************************************************/
/**
* \file list.h
* \brief Generic implementation of Linked Lists
*
* The interface is laid out to make the linked lists look
* as they were arrays that can be manipulated in multiple
* ways. Internally, each array is represented by a doubly
* linked ring list, which is quite efficient for most cases.
* The following piece of code provides some examples of how
* the linked list functions can be used.
*
* \include LinkedList.c
*
* If you're familiar with Perl, you may notice a certain
* similarity between these routines and the functions
* Perl uses for manipulating arrays. This is absolutely
* intended.
*/
#ifndef _UTIL_LIST_H
#define _UTIL_LIST_H
/**
* Linked List Handle
*/
typedef struct _linkedList * LinkedList;
typedef const struct _linkedList * ConstLinkedList;
/**
* Linked List Iterator
*/
typedef struct _listIterator {
ConstLinkedList list;
const struct _link *cur;
#ifdef DEBUG_UTIL_LIST
unsigned orig_state;
#endif
} ListIterator;
/**
* Destructor Function Pointer
*/
typedef void (* LLDestroyFunc)(void *);
/**
* Cloning Function Pointer
*/
typedef void * (* LLCloneFunc)(const void *);
/**
* Comparison Function Pointer
*/
typedef int (* LLCompareFunc)(const void *, const void *);
LinkedList LL_new( void );
void LL_delete( LinkedList list );
void LL_flush( LinkedList list, LLDestroyFunc destroy );
void LL_destroy( LinkedList list, LLDestroyFunc destroy );
LinkedList LL_clone( ConstLinkedList list, LLCloneFunc func );
int LL_count( ConstLinkedList list );
void LL_push( LinkedList list, void *pObj );
void * LL_pop( LinkedList list );
void LL_unshift( LinkedList list, void *pObj );
void * LL_shift( LinkedList list );
void LL_insert( LinkedList list, int item, void *pObj );
void * LL_extract( LinkedList list, int item );
void * LL_get( ConstLinkedList list, int item );
LinkedList LL_splice( LinkedList list, int offset, int length, LinkedList rlist );
void LL_sort( LinkedList list, LLCompareFunc cmp );
void LI_init(ListIterator *it, ConstLinkedList list);
int LI_next(ListIterator *it);
int LI_prev(ListIterator *it);
void * LI_curr(const ListIterator *it);
/**
* Loop over all list elements.
*
* The LL_foreach() macro is actually only a shortcut for the
* following loop:
*
* \code
* for (LI_reset(&iter, list); LI_next(&iter) && ((pObj) = LL_curr(&iter)) != NULL;) {
* // do something with pObj
* }
* \endcode
*
* It is safe to use LL_foreach() even if \a list is NULL.
* In that case, the loop won't be executed.
*
* \param pObj Variable that will receive a pointer
* to the current object.
*
* \param iter Iterator state object.
*
* \param list Handle to an existing linked list.
*
* \see LL_reset() and LL_next()
* \hideinitializer
*/
#define LL_foreach(pObj, iter, list) \
for (LI_init(&iter, list); ((pObj) = LI_next(&iter) ? LI_curr(&iter) : NULL) != NULL;)
#endif
|