230 lines
6.5 KiB
Groff
230 lines
6.5 KiB
Groff
.TH IM_LIST_ADD 3 "2 May 1991"
|
|
.SH NAME
|
|
im_list_add, im_list_len, im_list_pos, im_list_member, im_list_append,
|
|
im_list_remove,
|
|
im_list_eq, im_list_map, im_list_map_rev, im_list_fold, im_list_fix,
|
|
im_list_free, im_list_insert \- linked list functions
|
|
.SH SYNOPSIS
|
|
#include <vips/vips.h>
|
|
.br
|
|
#include <vips/list.h>
|
|
|
|
typedef struct list_type {
|
|
.br
|
|
struct list_type *next;
|
|
.br
|
|
void *this;
|
|
.br
|
|
} List;
|
|
|
|
#define hd(L) ((L)->this)
|
|
.br
|
|
#define tl(L) ((L)->next)
|
|
|
|
typedef void *(*im_list_map_fn)( void *, void *, void * );
|
|
.br
|
|
typedef void (*im_list_free_fn)( void *, void *, void * );
|
|
.br
|
|
typedef void *(*im_list_fold_fn)( void *, void *,
|
|
.br
|
|
void *, void * );
|
|
|
|
int im_list_len( List *l );
|
|
.br
|
|
int im_list_pos( List *l, void *t );
|
|
.br
|
|
int im_list_member( List *l, void *t );
|
|
.br
|
|
void *im_list_index( List *l, int n );
|
|
.br
|
|
int im_list_add( List **base, void *new );
|
|
.br
|
|
int im_list_insert( List **base, void *new, void *old );
|
|
.br
|
|
int im_list_append( List **base, void *new );
|
|
.br
|
|
int im_list_remove( List **base, void *t );
|
|
|
|
void *im_list_eq( void *a, void *b );
|
|
.br
|
|
void *im_list_map( List *l,
|
|
.br
|
|
im_list_map_fn fn, void *a, void *b );
|
|
.br
|
|
void *im_list_map_rev( List *l,
|
|
.br
|
|
im_list_map_fn fn, void *a, void *b );
|
|
.br
|
|
void *im_list_fold( List *l,
|
|
.br
|
|
void *start, im_list_fold_fn fn, void *a, void *b );
|
|
.br
|
|
void im_list_fix( List **base,
|
|
.br
|
|
im_list_map_fn fn, void *a, void *b );
|
|
.br
|
|
void im_list_free( List **base,
|
|
.br
|
|
im_list_free_fn fn, void *a, void *b );
|
|
|
|
.SH DESCRIPTION
|
|
Manipulate linked lists in various ways. These functions are heavily used by
|
|
the VIPS IO system; use them yourself if you like. VIPS lists store lists of
|
|
void * pointers - use casts if you want to store some other type. Note that
|
|
if sizeof( your object ) != sizeof( void * ), you will be in trouble!
|
|
|
|
All are based on the List type (see above). An empty list is a NULL pointer, a
|
|
one element list is a pointer to a List struct, whose this field contains a
|
|
pointer to the object in the list and whose next field is NULL. Macros hd(3)
|
|
and tl(3) (head and tail) return this and next respectively.
|
|
|
|
im_list_len(3) returns the number of elements in list l. im_list_pos(3) searches
|
|
list l for stored object t, returning an index. The first list element has
|
|
index zero. im_list_pos(3) returns -1 for not present. im_list_index(3) returns
|
|
the item at position n in the list, or NULL for index out of range.
|
|
im_list_member(3) returns non-zero if the list contains the element.
|
|
|
|
im_list_map(3) applies a void * valued function to every element in a list,
|
|
running from beginning to end. If the function returns NULL, im_list_map
|
|
continues with the next element. If the function returns non-NULL,
|
|
im_list_map(3) abandons the map and returns immediately, returning the value
|
|
the user function returned. If the list is empty, im_list_map(3) returns NULL.
|
|
|
|
The two extra arguments a and b are carried around for you by VIPS and fed
|
|
into each call of the function. They are useful for communicating context
|
|
information.
|
|
|
|
You can use im_list_map to implement many kinds of list search/apply operation.
|
|
VIPS supplies the function im_list_eq(3) which tests two void * pointers for
|
|
equality, returning the pointer if they match, and returning NULL otherwise.
|
|
|
|
Example: search a list for an object
|
|
|
|
im_list_map( list,
|
|
.br
|
|
(im_list_map_fn) im_list_eq, object, NULL );
|
|
|
|
This could also be written as
|
|
|
|
List *p;
|
|
|
|
for( p = list; p; p = tl( p ) )
|
|
.br
|
|
if( object == hd( p ) )
|
|
.br
|
|
break;
|
|
|
|
I prefer the first.
|
|
|
|
im_list_map_rev(3) behaves exactly as im_list_map(3), but applies the function
|
|
running from te end to the beginning of the list. It is much slower than
|
|
im_list_map(3) and should be used only in emergencies.
|
|
|
|
im_list_fold(3) folds up a list with a dyadic function. If a list contains
|
|
[1,2], return fn( 2, fn( 1, start, a, b ), a, b ). If the list is empty,
|
|
return start.
|
|
|
|
The two extra arguments a and b are carried around for you by VIPS and fed
|
|
into each call of the function. They are useful for communicating context
|
|
information.
|
|
|
|
Example: find a pointer to the largest element in a list of ints (assume
|
|
sizeof(int) <= sizeof(void *))
|
|
|
|
max_pair( int *new, int *old )
|
|
.br
|
|
{
|
|
.br
|
|
if( !old || *new > *old )
|
|
.br
|
|
return( new );
|
|
.br
|
|
else
|
|
.br
|
|
return( old );
|
|
.br
|
|
}
|
|
|
|
largest = im_list_fold( list,
|
|
.br
|
|
NULL, (im_list_map_fn) max_pair, NULL, NULL );
|
|
|
|
im_list_add(3) adds a new element to the head of a list. Since the head of the
|
|
list will move, you must pass in a *pointer* to your pointer to your old head.
|
|
|
|
Example: make a list of the numbers 9-0 (assume sizeof(int) <= sizeof(void *))
|
|
|
|
int i;
|
|
.br
|
|
List *nlist = NULL;
|
|
|
|
for( i = 0; i < 10; i++ )
|
|
.br
|
|
im_list_add( &nlist, (void *) i );
|
|
|
|
im_list_insert(3) adds a new element to a list, placing it just before the
|
|
indicated old element. If the old element is not found, im_list_insert(3)
|
|
returns an error.
|
|
|
|
im_list_append(3) appends a new element to the end of a list. This is much
|
|
slower than im_list_add(3), and should be avoided if possible.
|
|
|
|
im_list_remove(3) removes the specified element from the list. Since the head
|
|
of the list may move, you must pass in a *pointer* to your pointer to your
|
|
old head.
|
|
|
|
im_list_fix(3) finds the fixed-point of a list-altering function. It repeatedly
|
|
maps a function over the list until the function returns NULL. Note that,
|
|
since the list may be changing, you must pass in a *pointer* to the pointer
|
|
you store the list in.
|
|
|
|
The two extra arguments a and b are carried around for you by VIPS and fed
|
|
into each call of the function. They are useful for communicating context
|
|
information.
|
|
|
|
Example: remove all elements less than x from a list of numbers (assume
|
|
sizeof(int) <= sizeof(void *))
|
|
|
|
int *
|
|
.br
|
|
test_ele( int *n, List **base, int x )
|
|
.br
|
|
{
|
|
.br
|
|
if( *n < x ) {
|
|
.br
|
|
im_list_remove( base, n );
|
|
.br
|
|
return( base );
|
|
.br
|
|
}
|
|
.br
|
|
else
|
|
.br
|
|
return( NULL );
|
|
.br
|
|
}
|
|
|
|
im_list_fix( &nlist,
|
|
.br
|
|
(im_list_map_fn) test_ele, &nlist, x );
|
|
|
|
im_list_free(3) frees the list, applying a user free function to every element
|
|
as it is freed. You may pass NULL instead of a pointer to a function, in which
|
|
case im_list_free(3) will just free the memory used by the list nodes.
|
|
|
|
The two extra arguments a and b are carried around for you by VIPS and fed
|
|
into each call of the function. They are useful for communicating context
|
|
information.
|
|
|
|
.SH RETURN VALUE
|
|
The functions returns a 0 or a pointer on sucess, and non-zero or NULL on
|
|
failure.
|
|
.SH SEE\ ALSO
|
|
im_rect_intersectrect(3), etc.
|
|
.SH COPYRIGHT
|
|
.br
|
|
National Gallery, 1992
|
|
.SH AUTHOR
|
|
J. Cupitt
|