modified: diffout.py
[GalaxyCodeBases.git] / c_cpp / lib / uthash / doc / utarray.txt
blob546f42420d4261faf06b6f5ca1a495c873def561
1 utarray: dynamic array macros for C
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 dynamic array macros for C structures are included with
11 uthash in `utarray.h`.  To use these macros in your own C program, just
12 copy `utarray.h` into your source directory and use it in your programs.
14   #include "utarray.h"
16 The dynamic array supports basic operations such as push, pop, and erase on the
17 array elements. These array elements can be any simple datatype or structure.
18 The array <<operations,operations>> are based loosely on the C++ STL vector methods.
20 Internally the dynamic array contains a contiguous memory region into which
21 the elements are copied. This buffer is grown as needed using `realloc` to
22 accommodate all the data that is pushed into it.
24 Download
25 ~~~~~~~~
26 To download the `utarray.h` header file,
27 follow the links on https://github.com/troydhanson/uthash to clone uthash or get a zip file,
28 then look in the src/ sub-directory.
30 BSD licensed
31 ~~~~~~~~~~~~
32 This software is made available under the
33 link:license.html[revised BSD license].
34 It is free and open source.
36 Platforms
37 ~~~~~~~~~
38 The 'utarray' macros have been tested on:
40  * Linux,
41  * Mac OS X,
42  * Windows, using Visual Studio 2008 and Visual Studio 2010
44 Usage
45 -----
47 Declaration
48 ~~~~~~~~~~~
50 The array itself has the data type `UT_array`, regardless of the type of
51 elements to be stored in it. It is declared like,
53   UT_array *nums;
55 New and free
56 ~~~~~~~~~~~~
57 The next step is to create the array using `utarray_new`. Later when you're
58 done with the array, `utarray_free` will free it and all its elements.
60 Push, pop, etc
61 ~~~~~~~~~~~~~~
62 The central features of the utarray involve putting elements into it, taking
63 them out, and iterating over them. There are several <<operations,operations>>
64 to pick from that deal with either single elements or ranges of elements at a
65 time. In the examples below we will use only the push operation to insert
66 elements.
68 Elements
69 --------
71 Support for dynamic arrays of integers or strings is especially easy. These are
72 best shown by example:
74 Integers
75 ~~~~~~~~
76 This example makes a utarray of integers, pushes 0-9 into it, then prints it.
77 Lastly it frees it.
79 .Integer elements
80 -------------------------------------------------------------------------------
81 #include <stdio.h>
82 #include "utarray.h"
84 int main() {
85   UT_array *nums;
86   int i, *p;
88   utarray_new(nums,&ut_int_icd);
89   for(i=0; i < 10; i++) utarray_push_back(nums,&i);
91   for(p=(int*)utarray_front(nums);
92       p!=NULL;
93       p=(int*)utarray_next(nums,p)) {
94     printf("%d\n",*p);
95   }
97   utarray_free(nums);
99   return 0;
101 -------------------------------------------------------------------------------
103 The second argument to `utarray_push_back` is always a 'pointer' to the type
104 (so a literal cannot be used). So for integers, it is an `int*`.
106 Strings
107 ~~~~~~~
108 In this example we make a utarray of strings, push two strings into it, print
109 it and free it.
111 .String elements
112 -------------------------------------------------------------------------------
113 #include <stdio.h>
114 #include "utarray.h"
116 int main() {
117   UT_array *strs;
118   char *s, **p;
120   utarray_new(strs,&ut_str_icd);
122   s = "hello"; utarray_push_back(strs, &s);
123   s = "world"; utarray_push_back(strs, &s);
124   p = NULL;
125   while ( (p=(char**)utarray_next(strs,p))) {
126     printf("%s\n",*p);
127   }
129   utarray_free(strs);
131   return 0;
133 -------------------------------------------------------------------------------
135 In this example, since the element is a `char*`, we pass a pointer to it
136 (`char**`) as the second argument to `utarray_push_back`. Note that "push" makes
137 a copy of the source string and pushes that copy into the array.
139 About UT_icd
140 ~~~~~~~~~~~~
142 Arrays be made of any type of element, not just integers and strings.  The
143 elements can be basic types or structures. Unless you're dealing with integers
144 and strings (which use pre-defined `ut_int_icd` and `ut_str_icd`), you'll need
145 to define a `UT_icd` helper structure. This structure contains everything that
146 utarray needs to initialize, copy or destruct elements.
148   typedef struct {
149       size_t sz;
150       init_f *init;
151       ctor_f *copy;
152       dtor_f *dtor;
153   } UT_icd;
155 The three function pointers `init`, `copy`, and `dtor` have these prototypes:
157   typedef void (ctor_f)(void *dst, const void *src);
158   typedef void (dtor_f)(void *elt);
159   typedef void (init_f)(void *elt);
161 The `sz` is just the size of the element being stored in the array.
163 The `init` function will be invoked whenever utarray needs to initialize an
164 empty element. This only happens as a byproduct of `utarray_resize` or
165 `utarray_extend_back`. If `init` is `NULL`, it defaults to zero filling the
166 new element using memset.
168 The `copy` function is used whenever an element is copied into the array.
169 It is invoked during `utarray_push_back`, `utarray_insert`, `utarray_inserta`,
170 or `utarray_concat`. If `copy` is `NULL`, it defaults to a bitwise copy using
171 memcpy.
173 The `dtor` function is used to clean up an element that is being removed from
174 the array. It may be invoked due to `utarray_resize`, `utarray_pop_back`,
175 `utarray_erase`, `utarray_clear`, `utarray_done` or `utarray_free`. If the
176 elements need no cleanup upon destruction, `dtor` may be `NULL`.
178 Scalar types
179 ~~~~~~~~~~~~
181 The next example uses `UT_icd` with all its defaults to make a utarray of
182 `long` elements. This example pushes two longs, prints them, and frees the
183 array.
185 .long elements
186 -------------------------------------------------------------------------------
187 #include <stdio.h>
188 #include "utarray.h"
190 UT_icd long_icd = {sizeof(long), NULL, NULL, NULL };
192 int main() {
193   UT_array *nums;
194   long l, *p;
195   utarray_new(nums, &long_icd);
197   l=1; utarray_push_back(nums, &l);
198   l=2; utarray_push_back(nums, &l);
200   p=NULL;
201   while( (p=(long*)utarray_next(nums,p))) printf("%ld\n", *p);
203   utarray_free(nums);
204   return 0;
206 -------------------------------------------------------------------------------
208 Structures
209 ~~~~~~~~~~
211 Structures can be used as utarray elements. If the structure requires no
212 special effort to initialize, copy or destruct, we can use `UT_icd` with all
213 its defaults. This example shows a structure that consists of two integers. Here
214 we push two values, print them and free the array.
216 .Structure (simple)
217 -------------------------------------------------------------------------------
218 #include <stdio.h>
219 #include "utarray.h"
221 typedef struct {
222     int a;
223     int b;
224 } intpair_t;
226 UT_icd intpair_icd = {sizeof(intpair_t), NULL, NULL, NULL};
228 int main() {
230   UT_array *pairs;
231   intpair_t ip, *p;
232   utarray_new(pairs,&intpair_icd);
234   ip.a=1;  ip.b=2;  utarray_push_back(pairs, &ip);
235   ip.a=10; ip.b=20; utarray_push_back(pairs, &ip);
237   for(p=(intpair_t*)utarray_front(pairs);
238       p!=NULL;
239       p=(intpair_t*)utarray_next(pairs,p)) {
240     printf("%d %d\n", p->a, p->b);
241   }
243   utarray_free(pairs);
244   return 0;
246 -------------------------------------------------------------------------------
248 The real utility of `UT_icd` is apparent when the elements of the utarray are
249 structures that require special work to initialize, copy or destruct.
251 For example, when a structure contains pointers to related memory areas that
252 need to be copied when the structure is copied (and freed when the structure is
253 freed), we can use custom `init`, `copy`, and `dtor` members in the `UT_icd`.
255 Here we take an example of a structure that contains an integer and a string.
256 When this element is copied (such as when an element is pushed into the array),
257 we want to "deep copy" the `s` pointer (so the original element and the new
258 element point to their own copies of `s`). When an element is destructed, we
259 want to "deep free" its copy of `s`. Lastly, this example is written to work
260 even if `s` has the value `NULL`.
262 .Structure (complex)
263 -------------------------------------------------------------------------------
264 #include <stdio.h>
265 #include <stdlib.h>
266 #include "utarray.h"
268 typedef struct {
269     int a;
270     char *s;
271 } intchar_t;
273 void intchar_copy(void *_dst, const void *_src) {
274   intchar_t *dst = (intchar_t*)_dst, *src = (intchar_t*)_src;
275   dst->a = src->a;
276   dst->s = src->s ? strdup(src->s) : NULL;
279 void intchar_dtor(void *_elt) {
280   intchar_t *elt = (intchar_t*)_elt;
281   if (elt->s) free(elt->s);
284 UT_icd intchar_icd = {sizeof(intchar_t), NULL, intchar_copy, intchar_dtor};
286 int main() {
287   UT_array *intchars;
288   intchar_t ic, *p;
289   utarray_new(intchars, &intchar_icd);
291   ic.a=1; ic.s="hello"; utarray_push_back(intchars, &ic);
292   ic.a=2; ic.s="world"; utarray_push_back(intchars, &ic);
294   p=NULL;
295   while( (p=(intchar_t*)utarray_next(intchars,p))) {
296     printf("%d %s\n", p->a, (p->s ? p->s : "null"));
297   }
299   utarray_free(intchars);
300   return 0;
303 -------------------------------------------------------------------------------
305 [[operations]]
306 Reference
307 ---------
308 This table lists all the utarray operations. These are loosely based on the C++
309 vector class.
311 Operations
312 ~~~~~~~~~~
314 [width="100%",cols="50<m,40<",grid="none",options="none"]
315 |===============================================================================
316 | utarray_new(UT_array *a, UT_icd *icd)| allocate a new array
317 | utarray_free(UT_array *a)            | free an allocated array
318 | utarray_init(UT_array *a,UT_icd *icd)| init an array (non-alloc)
319 | utarray_done(UT_array *a)            | dispose of an array (non-allocd)
320 | utarray_reserve(UT_array *a,int n)  | ensure space available for 'n' more elements
321 | utarray_push_back(UT_array *a,void *p) | push element p onto a
322 | utarray_pop_back(UT_array *a)        | pop last element from a
323 | utarray_extend_back(UT_array *a)     | push empty element onto a
324 | utarray_len(UT_array *a)             | get length of a
325 | utarray_eltptr(UT_array *a,int j)    | get pointer of element from index
326 | utarray_eltidx(UT_array *a,void *e)  | get index of element from pointer
327 | utarray_insert(UT_array *a,void *p, int j) | insert element p to index j
328 | utarray_inserta(UT_array *a,UT_array *w, int j) | insert array w into array a at index j
329 | utarray_resize(UT_array *dst,int num)  | extend or shrink array to num elements
330 | utarray_concat(UT_array *dst,UT_array *src) | copy src to end of dst array
331 | utarray_erase(UT_array *a,int pos,int len) | remove len elements from a[pos]..a[pos+len-1]
332 | utarray_clear(UT_array *a) | clear all elements from a, setting its length to zero
333 | utarray_sort(UT_array *a,cmpfcn *cmp) | sort elements of a using comparison function
334 | utarray_find(UT_array *a,void *v, cmpfcn *cmp) | find element v in utarray (must be sorted)
335 | utarray_front(UT_array *a) | get first element of a
336 | utarray_next(UT_array *a,void *e) | get element of a following e (front if e is NULL)
337 | utarray_prev(UT_array *a,void *e) | get element of a before e (back if e is NULL)
338 | utarray_back(UT_array *a) | get last element of a
339 |===============================================================================
341 Notes
342 ~~~~~
344 1. `utarray_new` and `utarray_free` are used to allocate a new array and free it,
345    while `utarray_init` and `utarray_done` can be used if the UT_array is already
346    allocated and just needs to be initialized or have its internal resources
347    freed.
348 2. `utarray_reserve` takes the "delta" of elements to reserve (not the total
349    desired capacity of the array-- this differs from the C++ STL "reserve" notion)
350 3. `utarray_sort` expects a comparison function having the usual `strcmp` -like
351    convention where it accepts two elements (a and b) and returns a negative
352    value if a precedes b, 0 if a and b sort equally, and positive if b precedes a.
353    This is an example of a comparison function:
355   int intsort(const void *a, const void *b) {
356       int _a = *(const int *)a;
357       int _b = *(const int *)b;
358       return (_a < _b) ? -1 : (_a > _b);
359   }
361 4. `utarray_find` uses a binary search to locate an element having a certain value
362    according to the given comparison function. The utarray must be first sorted
363    using the same comparison function. An example of using `utarray_find` with
364    a utarray of strings is included in `tests/test61.c`.
366 5. A 'pointer' to a particular element (obtained using `utarray_eltptr` or
367    `utarray_front`, `utarray_next`, `utarray_prev`, `utarray_back`) becomes invalid whenever
368    another element is inserted into the utarray. This is because the internal
369    memory management may need to `realloc` the element storage to a new address.
370    For this reason, it's usually better to refer to an element by its integer
371    'index' in code whose duration may include element insertion.
373 // vim: set nowrap syntax=asciidoc: