---
name: "im_list_append"
section: "3"
platform: "linux"
package: "libvips10-dev"
version: "7.10.21-1"
release: "Debian 4.0 (Etch)"
platforms: ["linux"]
url: "https://new.carta.tech/im_list_add"
---

# im\_list\_append(3)

linked list functions

Part of [im\_list\_add(3)](/im_list_add/3.md).

## 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

## SYNOPSIS

\#include \<vips/vips.h\>\
 \#include \<vips/list.h\>

typedef struct list\_type {\
\
 	struct list\_type \*next;\
\
 	void \*this;\
 } List;

\#define hd(L) ((L)-\>this)\
 \#define tl(L) ((L)-\>next)

typedef void \*(\*im\_list\_map\_fn)( void \*, void \*, void \* );\
 typedef void (\*im\_list\_free\_fn)( void \*, void \*, void \* );\
 typedef void \*(\*im\_list\_fold\_fn)( void \*, void \*, \
\
 	void \*, void \* );

int im\_list\_len( List \*l );\
 int im\_list\_pos( List \*l, void \*t );\
 int im\_list\_member( List \*l, void \*t );\
 void \*im\_list\_index( List \*l, int n );\
 int im\_list\_add( List \*\*base, void \*new );\
 int im\_list\_insert( List \*\*base, void \*new, void \*old );\
 int im\_list\_append( List \*\*base, void \*new );\
 int im\_list\_remove( List \*\*base, void \*t );

void \*im\_list\_eq( void \*a, void \*b );\
 void \*im\_list\_map( List \*l, \
\
 	im\_list\_map\_fn fn, void \*a, void \*b );\
 void \*im\_list\_map\_rev( List \*l, \
\
 	im\_list\_map\_fn fn, void \*a, void \*b );\
 void \*im\_list\_fold( List \*l, \
\
 	void \*start, im\_list\_fold\_fn fn, void \*a, void \*b );\
 void im\_list\_fix( List \*\*base, \
\
 	im\_list\_map\_fn fn, void \*a, void \*b );\
 void im\_list\_free( List \*\*base, \
\
 	im\_list\_free\_fn fn, void \*a, void \*b );

## 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)](/im_list_len/3.md) returns the number of elements in list l. [im\_list\_pos(3)](/im_list_pos/3.md) searches list l for stored object t, returning an index. The first list element has index zero. [im\_list\_pos(3)](/im_list_pos/3.md) returns -1 for not present. [im\_list\_index(3)](/im_list_index/3.md) returns the item at position n in the list, or NULL for index out of range. [im\_list\_member(3)](/im_list_member/3.md) returns non-zero if the list contains the element.

[im\_list\_map(3)](/im_list_map/3.md) 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)](/im_list_map/3.md) abandons the map and returns immediately, returning the value the user function returned. If the list is empty, [im\_list\_map(3)](/im_list_map/3.md) 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)](/im_list_eq/3.md) 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, \
\
          (im\_list\_map\_fn) im\_list\_eq, object, NULL );

This could also be written as

    List \*p;

    for( p = list; p; p = tl( p ) )\
\
         if( object == hd( p ) )\
\
             break;

I prefer the first.

[im\_list\_map\_rev(3)](/im_list_map_rev/3.md) behaves exactly as [im\_list\_map(3)](/im_list_map/3.md), but applies the function running from te end to the beginning of the list. It is much slower than [im\_list\_map(3)](/im_list_map/3.md) and should be used only in emergencies.

[im\_list\_fold(3)](/im_list_fold/3.md) 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 )\
\
     {\
\
         if( !old \|\| \*new \> \*old )\
\
             return( new );\
\
         else\
\
             return( old );\
\
     }

    largest = im\_list\_fold( list, \
\
         NULL, (im\_list\_map\_fn) max\_pair, NULL, NULL );

[im\_list\_add(3)](/im_list_add/3.md) 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;\
\
     List \*nlist = NULL;

    for( i = 0; i \< 10; i++ )\
\
         im\_list\_add( &nlist, (void \*) i );

[im\_list\_insert(3)](/im_list_insert/3.md) 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)](/im_list_insert/3.md) returns an error.

[im\_list\_append(3)](/im_list_append/3.md) appends a new element to the end of a list. This is much slower than [im\_list\_add(3)](/im_list_add/3.md), and should be avoided if possible.

[im\_list\_remove(3)](/im_list_remove/3.md) 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)](/im_list_fix/3.md) 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 \*\
\
     test\_ele( int \*n, List \*\*base, int x )\
\
     {\
\
         if( \*n \< x ) {\
\
             im\_list\_remove( base, n );\
\
             return( base );\
\
         }\
\
         else\
\
             return( NULL );\
\
     }

    im\_list\_fix( &nlist, \
\
         (im\_list\_map\_fn) test\_ele, &nlist, x );

[im\_list\_free(3)](/im_list_free/3.md) 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)](/im_list_free/3.md) 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.

## RETURN VALUE

The functions returns a 0 or a pointer on sucess, and non-zero or NULL on  failure.

## SEE ALSO

[im\_rect\_intersectrect(3)](/im_rect_intersectrect/3.md), etc.

## COPYRIGHT

National Gallery, 1992

## AUTHOR

J. Cupitt
