1IM_LIST_ADD(3) Library Functions Manual IM_LIST_ADD(3)
2
3
4
6 im_list_add, im_list_len, im_list_pos, im_list_member, im_list_append,
7 im_list_remove, im_list_eq, im_list_map, im_list_map_rev, im_list_fold,
8 im_list_fix, im_list_free, im_list_insert - linked list functions
9
11 #include <vips/vips.h>
12 #include <vips/list.h>
13
14 typedef struct list_type {
15 struct list_type *next;
16 void *this;
17 } List;
18
19 #define hd(L) ((L)->this)
20 #define tl(L) ((L)->next)
21
22 typedef void *(*im_list_map_fn)( void *, void *, void * );
23 typedef void (*im_list_free_fn)( void *, void *, void * );
24 typedef void *(*im_list_fold_fn)( void *, void *,
25 void *, void * );
26
27 int im_list_len( List *l );
28 int im_list_pos( List *l, void *t );
29 int im_list_member( List *l, void *t );
30 void *im_list_index( List *l, int n );
31 int im_list_add( List **base, void *new );
32 int im_list_insert( List **base, void *new, void *old );
33 int im_list_append( List **base, void *new );
34 int im_list_remove( List **base, void *t );
35
36 void *im_list_eq( void *a, void *b );
37 void *im_list_map( List *l,
38 im_list_map_fn fn, void *a, void *b );
39 void *im_list_map_rev( List *l,
40 im_list_map_fn fn, void *a, void *b );
41 void *im_list_fold( List *l,
42 void *start, im_list_fold_fn fn, void *a, void *b );
43 void im_list_fix( List **base,
44 im_list_map_fn fn, void *a, void *b );
45 void im_list_free( List **base,
46 im_list_free_fn fn, void *a, void *b );
47
48
50 Manipulate linked lists in various ways. These functions are heavily
51 used by the VIPS IO system; use them yourself if you like. VIPS lists
52 store lists of void * pointers - use casts if you want to store some
53 other type. Note that if sizeof( your object ) != sizeof( void * ), you
54 will be in trouble!
55
56 All are based on the List type (see above). An empty list is a NULL
57 pointer, a one element list is a pointer to a List struct, whose this
58 field contains a pointer to the object in the list and whose next field
59 is NULL. Macros hd(3) and tl(3) (head and tail) return this and next
60 respectively.
61
62 im_list_len(3) returns the number of elements in list l. im_list_pos(3)
63 searches list l for stored object t, returning an index. The first list
64 element has index zero. im_list_pos(3) returns -1 for not present.
65 im_list_index(3) returns the item at position n in the list, or NULL
66 for index out of range. im_list_member(3) returns non-zero if the list
67 contains the element.
68
69 im_list_map(3) applies a void * valued function to every element in a
70 list, running from beginning to end. If the function returns NULL,
71 im_list_map continues with the next element. If the function returns
72 non-NULL, im_list_map(3) abandons the map and returns immediately,
73 returning the value the user function returned. If the list is empty,
74 im_list_map(3) returns NULL.
75
76 The two extra arguments a and b are carried around for you by VIPS and
77 fed into each call of the function. They are useful for communicating
78 context information.
79
80 You can use im_list_map to implement many kinds of list search/apply
81 operation. VIPS supplies the function im_list_eq(3) which tests two
82 void * pointers for equality, returning the pointer if they match, and
83 returning NULL otherwise.
84
85 Example: search a list for an object
86
87 im_list_map( list,
88 (im_list_map_fn) im_list_eq, object, NULL );
89
90 This could also be written as
91
92 List *p;
93
94 for( p = list; p; p = tl( p ) )
95 if( object == hd( p ) )
96 break;
97
98 I prefer the first.
99
100 im_list_map_rev(3) behaves exactly as im_list_map(3), but applies the
101 function running from te end to the beginning of the list. It is much
102 slower than im_list_map(3) and should be used only in emergencies.
103
104 im_list_fold(3) folds up a list with a dyadic function. If a list con‐
105 tains [1,2], return fn( 2, fn( 1, start, a, b ), a, b ). If the list is
106 empty, return start.
107
108 The two extra arguments a and b are carried around for you by VIPS and
109 fed into each call of the function. They are useful for communicating
110 context information.
111
112 Example: find a pointer to the largest element in a list of ints
113 (assume sizeof(int) <= sizeof(void *))
114
115 max_pair( int *new, int *old )
116 {
117 if( !old || *new > *old )
118 return( new );
119 else
120 return( old );
121 }
122
123 largest = im_list_fold( list,
124 NULL, (im_list_map_fn) max_pair, NULL, NULL );
125
126 im_list_add(3) adds a new element to the head of a list. Since the head
127 of the list will move, you must pass in a *pointer* to your pointer to
128 your old head.
129
130 Example: make a list of the numbers 9-0 (assume sizeof(int) <=
131 sizeof(void *))
132
133 int i;
134 List *nlist = NULL;
135
136 for( i = 0; i < 10; i++ )
137 im_list_add( &nlist, (void *) i );
138
139 im_list_insert(3) adds a new element to a list, placing it just before
140 the indicated old element. If the old element is not found,
141 im_list_insert(3) returns an error.
142
143 im_list_append(3) appends a new element to the end of a list. This is
144 much slower than im_list_add(3), and should be avoided if possible.
145
146 im_list_remove(3) removes the specified element from the list. Since
147 the head of the list may move, you must pass in a *pointer* to your
148 pointer to your old head.
149
150 im_list_fix(3) finds the fixed-point of a list-altering function. It
151 repeatedly maps a function over the list until the function returns
152 NULL. Note that, since the list may be changing, you must pass in a
153 *pointer* to the pointer you store the list in.
154
155 The two extra arguments a and b are carried around for you by VIPS and
156 fed into each call of the function. They are useful for communicating
157 context information.
158
159 Example: remove all elements less than x from a list of numbers (assume
160 sizeof(int) <= sizeof(void *))
161
162 int *
163 test_ele( int *n, List **base, int x )
164 {
165 if( *n < x ) {
166 im_list_remove( base, n );
167 return( base );
168 }
169 else
170 return( NULL );
171 }
172
173 im_list_fix( &nlist,
174 (im_list_map_fn) test_ele, &nlist, x );
175
176 im_list_free(3) frees the list, applying a user free function to every
177 element as it is freed. You may pass NULL instead of a pointer to a
178 function, in which case im_list_free(3) will just free the memory used
179 by the list nodes.
180
181 The two extra arguments a and b are carried around for you by VIPS and
182 fed into each call of the function. They are useful for communicating
183 context information.
184
185
187 The functions returns a 0 or a pointer on sucess, and non-zero or NULL
188 on failure.
189
191 im_rect_intersectrect(3), etc.
192
194 National Gallery, 1992
195
197 J. Cupitt
198
199
200
201 2 May 1991 IM_LIST_ADD(3)