modified: diffout.py
[GalaxyCodeBases.git] / c_cpp / lib / uthash / doc / utlist.txt
blob9318ea090850a22f244607ba5fa2800b4c3f5103
1 utlist: linked list macros for C structures
2 ===========================================
3 Troy D. Hanson <tdh@tkhanson.net>
4 v2.0.2, March 2017
6 Here's a link back to the https://github.com/troydhanson/uthash[GitHub project page].
8 Introduction
9 ------------
10 A set of general-purpose 'linked list' macros for C structures are included with
11 uthash in `utlist.h`.  To use these macros in your own C program, just
12 copy `utlist.h` into your source directory and use it in your programs.
14   #include "utlist.h"
16 These macros support the basic linked list operations: adding and deleting
17 elements, sorting them and iterating over them.
19 Download
20 ~~~~~~~~
21 To download the `utlist.h` header file,
22 follow the links on https://github.com/troydhanson/uthash to clone uthash or get a zip file,
23 then look in the src/ sub-directory.
25 BSD licensed
26 ~~~~~~~~~~~~
27 This software is made available under the
28 link:license.html[revised BSD license].
29 It is free and open source.
31 Platforms
32 ~~~~~~~~~
33 The 'utlist' macros have been tested on:
35  * Linux,
36  * Mac OS X, and
37  * Windows, using Visual Studio 2008, Visual Studio 2010, or Cygwin/MinGW.
39 Using utlist
40 ------------
42 Types of lists
43 ~~~~~~~~~~~~~~
44 Three types of linked lists are supported:
46 - *singly-linked* lists,
47 - *doubly-linked* lists, and
48 - *circular, doubly-linked* lists
50 Efficiency
51 ^^^^^^^^^^
52 Prepending elements::
53  Constant-time on all list types.
54 Appending::
55  'O(n)' on singly-linked lists; constant-time on doubly-linked list.
56  (The utlist implementation of the doubly-linked list keeps a tail pointer in
57  `head->prev` so that append can be done in constant time).
58 Deleting elements::
59  'O(n)' on singly-linked lists; constant-time on doubly-linked list.
60 Sorting::
61  'O(n log(n))' for all list types.
62 Iteration, counting and searching::
63  'O(n)' for all list types.
65 List elements
66 ~~~~~~~~~~~~~
67 You can use any structure with these macros, as long as the structure
68 contains a `next` pointer. If you want to make a doubly-linked list,
69 the element also needs to have a `prev` pointer.
71   typedef struct element {
72       char *name;
73       struct element *prev; /* needed for a doubly-linked list only */
74       struct element *next; /* needed for singly- or doubly-linked lists */
75   } element;
77 You can name your structure anything. In the example above it is called `element`.
78 Within a particular list, all elements must be of the same type.
80 Flexible prev/next naming
81 ^^^^^^^^^^^^^^^^^^^^^^^^^
82 You can name your `prev` and `next` pointers something else. If you do, there is
83 a <<flex_names,family of macros>> that work identically but take these names as
84 extra arguments.
86 List head
87 ~~~~~~~~~
88 The list head is simply a pointer to your element structure. You can name it
89 anything. *It must be initialized to `NULL`*.
91   element *head = NULL;
93 List operations
94 ~~~~~~~~~~~~~~~
95 The lists support inserting or deleting elements, sorting the elements and
96 iterating over them.
98 [width="100%",cols="10<m,10<m,10<m",grid="cols",options="header"]
99 |===============================================================================
100 |Singly-linked             | Doubly-linked              | Circular, doubly-linked
101 |LL_PREPEND(head,add);     | DL_PREPEND(head,add);      | CDL_PREPEND(head,add);
102 |LL_PREPEND_ELEM(head,ref,add); | DL_PREPEND_ELEM(head,ref,add); | CDL_PREPEND_ELEM(head,ref,add);
103 |LL_APPEND_ELEM(head,ref,add); | DL_APPEND_ELEM(head,ref,add); | CDL_APPEND_ELEM(head,ref,add);
104 |LL_REPLACE_ELEM(head,del,add); | DL_REPLACE_ELEM(head,del,add); | CDL_REPLACE_ELEM(head,del,add);
105 |LL_APPEND(head,add);      | DL_APPEND(head,add);       | CDL_APPEND(head,add);
106 |LL_CONCAT(head1,head2);   | DL_CONCAT(head1,head2);    |
107 |LL_DELETE(head,del);      | DL_DELETE(head,del);       | CDL_DELETE(head,del);
108 |LL_SORT(head,cmp);        | DL_SORT(head,cmp);         | CDL_SORT(head,cmp);
109 |LL_FOREACH(head,elt) {...}| DL_FOREACH(head,elt) {...} | CDL_FOREACH(head,elt) {...}
110 |LL_FOREACH_SAFE(head,elt,tmp) {...}| DL_FOREACH_SAFE(head,elt,tmp) {...} | CDL_FOREACH_SAFE(head,elt,tmp1,tmp2) {...}
111 |LL_SEARCH_SCALAR(head,elt,mbr,val);| DL_SEARCH_SCALAR(head,elt,mbr,val); | CDL_SEARCH_SCALAR(head,elt,mbr,val);
112 |LL_SEARCH(head,elt,like,cmp);| DL_SEARCH(head,elt,like,cmp); | CDL_SEARCH(head,elt,like,cmp);
113 |LL_COUNT(head,elt,count); | DL_COUNT(head,elt,count);  | CDL_COUNT(head,elt,count);
114 |===============================================================================
116 'Prepend' means to insert an element in front of the existing list head (if any),
117 changing the list head to the new element. 'Append' means to add an element at the
118 end of the list, so it becomes the new tail element. 'Concatenate' takes two
119 properly constructed lists and appends the second list to the first.  (Visual
120 Studio 2008 does not support `LL_CONCAT` and `DL_CONCAT`, but VS2010 is ok.)
121 To prepend before an arbitrary element instead of the list head, use the
122 `_PREPEND_ELEM` macro family.
123 To append after an arbitrary element element instead of the list head, use the
124 `_APPEND_ELEM` macro family.
125 To 'replace' an arbitrary list element with another element use the `_REPLACE_ELEM`
126 family of macros.
128 The 'sort' operation never moves the elements in memory; rather it only adjusts
129 the list order by altering the `prev` and `next` pointers in each element. Also
130 the sort operation can change the list head to point to a new element.
132 The 'foreach' operation is for easy iteration over the list from the head to the
133 tail. A usage example is shown below. You can of course just use the `prev` and
134 `next` pointers directly instead of using the 'foreach' macros.
135 The 'foreach_safe' operation should be used if you plan to delete any of the list
136 elements while iterating.
138 The 'search' operation is a shortcut for iteration in search of a particular
139 element. It is not any faster than manually iterating and testing each element.
140 There are two forms: the "scalar" version searches for an element using a
141 simple equality test on a given structure member, while the general version takes an
142 element to which all others in the list will be compared using a `cmp` function.
144 The 'count' operation iterates over the list and increments a supplied counter.
146 The parameters shown in the table above are explained here:
148 head::
149   The list head (a pointer to your list element structure).
150 add::
151   A pointer to the list element structure you are adding to the list.
152 del::
153   A pointer to the list element structure you are replacing or
154   deleting from the list.
155 elt::
156   A pointer that will be assigned to each list element in succession (see
157   example) in the case of iteration macros; or, the output pointer from
158   the search macros.
159 ref::
160   Reference element for prepend and append operations that will be
161   prepended before or appended after.
162   If `ref` is a pointer with value NULL, the new element will be appended to the
163   list for _PREPEND_ELEM() operations and prepended for _APPEND_ELEM() operations.
164   `ref` must be the name of a pointer variable and cannot be literally NULL,
165   use _PREPEND() and _APPEND() macro family instead.
166 like::
167   An element pointer, having the same type as `elt`, for which the search macro
168   seeks a match (if found, the match is stored in `elt`). A match is determined
169   by the given `cmp` function.
170 cmp::
171   pointer to comparison function which accepts two arguments-- these are
172   pointers to two element structures to be compared. The comparison function
173   must return an `int` that is negative, zero, or positive, which specifies
174   whether the first item should sort before, equal to, or after the second item,
175   respectively. (In other words, the same convention that is used by `strcmp`).
176   Note that under Visual Studio 2008 you may need to declare the two arguments
177   as `void *` and then cast them back to their actual types.
178 tmp::
179   A pointer of the same type as `elt`. Used internally. Need not be initialized.
180 mbr::
181   In the scalar search macro, the name of a member within the `elt` structure which
182   will be tested (using `==`) for equality with the value `val`.
183 val::
184   In the scalar search macro, specifies the value of (of structure member
185   `field`) of the element being sought.
186 count::
187   integer which will be set to the length of the list
189 Example
190 ~~~~~~~
191 This example program reads names from a text file (one name per line), and
192 appends each name to a doubly-linked list. Then it sorts and prints them.
194 .A doubly-linked list
195 --------------------------------------------------------------------------------
196 #include <stdio.h>
197 #include <stdlib.h>
198 #include <string.h>
199 #include "utlist.h"
201 #define BUFLEN 20
203 typedef struct el {
204     char bname[BUFLEN];
205     struct el *next, *prev;
206 } el;
208 int namecmp(el *a, el *b) {
209     return strcmp(a->bname,b->bname);
212 el *head = NULL; /* important- initialize to NULL! */
214 int main(int argc, char *argv[]) {
215     el *name, *elt, *tmp, etmp;
217     char linebuf[BUFLEN];
218     int count;
219     FILE *file;
221     if ( (file = fopen( "test11.dat", "r" )) == NULL ) {
222         perror("can't open: ");
223         exit(-1);
224     }
226     while (fgets(linebuf,BUFLEN,file) != NULL) {
227         if ( (name = (el*)malloc(sizeof(el))) == NULL) exit(-1);
228         strncpy(name->bname,linebuf,BUFLEN);
229         DL_APPEND(head, name);
230     }
231     DL_SORT(head, namecmp);
232     DL_FOREACH(head,elt) printf("%s", elt->bname);
233     DL_COUNT(head, elt, count);
234     printf("%d number of elements in list\n", count);
236     memcpy(&etmp.bname, "WES\n", 5);
237     DL_SEARCH(head,elt,&etmp,namecmp);
238     if (elt) printf("found %s\n", elt->bname);
240     /* now delete each element, use the safe iterator */
241     DL_FOREACH_SAFE(head,elt,tmp) {
242       DL_DELETE(head,elt);
243       free(elt);
244     }
246     fclose(file);
248     return 0;
250 --------------------------------------------------------------------------------
252 [[flex_names]]
253 Other names for prev and next
254 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
255 If the `prev` and `next` fields are named something else, a separate group of
256 macros must be used. These work the same as the regular macros, but take the
257 field names as extra parameters.
259 These "flexible field name" macros are shown below. They all end with "2". Each
260 operates the same as its counterpart without the 2, but they take the name of
261 the `prev` and `next` fields (as applicable) as trailing arguments.
263 .Flexible field name macros
264  LL_SORT2(list, cmp, next);
265  DL_SORT2(list, cmp, prev, next);
266  CDL_SORT2(list, cmp, prev, next);
267  LL_PREPEND2(head, add, next);
268  LL_PREPEND_ELEM2(head, ref, add, next);
269  LL_APPEND_ELEM2(head, ref, add, next);
270  LL_REPLACE_ELEM(head, del, add, next);
271  LL_CONCAT2(head1, head2, next);
272  LL_APPEND2(head, add, next);
273  LL_DELETE2(head, del, next);
274  LL_FOREACH2(head, elt, next) {...}
275  LL_FOREACH_SAFE2(head, elt, tmp, next) {...}
276  LL_SEARCH_SCALAR2(head, out, field, val, next);
277  LL_SEARCH2(head, out, elt, cmp, next);
278  LL_COUNT2(head, elt, count, next);
279  DL_PREPEND2(head, add, prev, next);
280  DL_PREPEND_ELEM2(head, ref, add, prev, next);
281  DL_APPEND_ELEM2(head, ref, add, prev, next);
282  DL_REPLACE_ELEM2(head, del, add, prev, next);
283  DL_CONCAT2(head1, head2, prev, next);
284  DL_APPEND2(head, add, prev, next);
285  DL_DELETE2(head, del, prev, next);
286  DL_FOREACH2(head, elt, next) {...}
287  DL_FOREACH_SAFE2(head, elt, tmp, next) {...}
288  DL_SEARCH_SCALAR2(head, out, field, val, next);
289  DL_COUNT2(head, elt, count, next);
290  CDL_PREPEND2(head, add, prev, next);
291  CDL_PREPEND_ELEM2(head, ref, add, prev, next);
292  CDL_APPEND_ELEM2(head, ref, add, prev, next);
293  CDL_REPLACE_ELEM2(head, del, add, prev, next);
294  CDL_APPEND2(head, add, prev, next);
295  CDL_DELETE2(head, del, prev, next);
296  CDL_FOREACH2(head, elt, next) {...}
297  CDL_FOREACH_SAFE2(head, elt, tmp1, tmp2, prev, next) {...}
298  CDL_SEARCH_SCALAR2(head, out, field, val, next);
299  CDL_SEARCH2(head, out, elt, cmp, next);
300  CDL_COUNT2(head, elt, count, next);
302 // vim: set tw=80 wm=2 syntax=asciidoc: