Simple data structures / objects in plain C Snapshot
Classes | Defines | Typedefs | Functions
ARRAY

Dynamic array, all elements contained in this structure are of the same size. More...

Classes

struct  ARRAY

Defines

#define ARRAY_init_stack(arr, elmsize, numofelem)
 Macro: Allocate dynamic array on stack.

Typedefs

typedef int(* ARRAY_VISITOR )(int index, void *elm, size_t elmsize, void *context)

Functions

M_INLINE int ARRAY_init (ARRAY *arr, size_t elmsize, size_t numofelem)
M_INLINE int ARRAY_init_fixed (ARRAY *arr, size_t elmsize, void *ptr, size_t bufsize)
 Allocates a dynamic array from already allocated memory area;.
M_INLINE void ARRAY_free (ARRAY *arr)
 free all memory held by dynamic array (destructor).
M_INLINE void ARRAY_reset (ARRAY *arr)
M_INLINE size_t ARRAY_size (ARRAY *arr)
 returns number of objects that are currently held by this collection.
M_INLINE size_t ARRAY_maxsize (ARRAY *arr)
 returns maximum number of elements that can currently be held by this collection.
M_INLINE int ARRAY_resize (ARRAY *arr, size_t num_elem)
 change size of dynamic array (i.e. change size of memory allocated for array) If requested size is smaller then the current size, then all skipping elements are discarded.
M_INLINE uint8_t * ARRAY_at (ARRAY *arr, size_t index)
M_INLINE int ARRAY_copy_at (ARRAY *arr, size_t index, void *elm, size_t elmsize)
int ARRAY_insert_at (ARRAY *arr, size_t index, void *elm, size_t elmsize)
int ARRAY_set_at (ARRAY *arr, size_t index, void *elm, size_t elmsize)
M_INLINE int ARRAY_delete_at (ARRAY *arr, size_t index)
M_INLINE int ARRAY_push_back (ARRAY *arr, void *elm, size_t elmsize)
M_INLINE int ARRAY_pop_back (ARRAY *arr, void *ptr, size_t elmsize)
M_INLINE int ARRAY_stack_top (ARRAY *arr, void *ptr, size_t elmsize)
M_INLINE void ARRAY_foreach (ARRAY *arr, ARRAY_VISITOR eval, void *context)
M_INLINE int ARRAY_foreach_range (ARRAY *arr, ARRAY_VISITOR eval, void *context, int from_idx, int to_idx)
M_INLINE void ARRAY_foreach_reverse (ARRAY *arr, ARRAY_VISITOR eval, void *context)
M_INLINE int ARRAY_foreach_reverse_range (ARRAY *arr, ARRAY_VISITOR eval, void *context, int from_idx, int to_idx)
M_INLINE int ARRAY_findif (ARRAY *arr, ARRAY_VISITOR eval, void *context, uint32_t *retval)
M_INLINE int ARRAY_findif_range (ARRAY *arr, ARRAY_VISITOR eval, void *context, int from_idx, int to_idx, uint32_t *retval)
M_INLINE int ARRAY_findif_reverse (ARRAY *arr, ARRAY_VISITOR eval, void *context, uint32_t *retval)
M_INLINE int ARRAY_findif_reverse_range (ARRAY *arr, ARRAY_VISITOR eval, void *context, int from_idx, int to_idx, uint32_t *retval)

Detailed Description

Dynamic array, all elements contained in this structure are of the same size.

A dynamic array, growable array, resizable array, dynamic table, or array list is a data structure, an array which is automatically expanded to accommodate new objects if filled beyond its current size. In most ways the dynamic array has performance similar to an array, with the addition of new operations to add and remove elements from the end:

From http://en.wikipedia.org/wiki/Dynamic_array


Define Documentation

#define ARRAY_init_stack (   arr,
  elmsize,
  numofelem 
)
Value:
do { \
        (arr)->ctx = 0; \
        (arr)->elmcount = 0; \
        (arr)->elmsize = (elmsize); \
        (arr)->elmmaxcount = (elmsize) * (numofelem); \
        (arr)->buffer = (char *) alloca( (str)->elmmaxcount ); \
} while(0);

Macro: Allocate dynamic array on stack.

Warning! this macro uses alloca standard library function - this is not always portable, and it bombs out when it causes stack overflow.

Parameters:
arr(out) (type ARRAY *) the object.
elmsize(in) (type size_t) size of one element
numofelem(in) (type size_t) maximum number of elements.

Definition at line 100 of file array.h.


Typedef Documentation

typedef int(* ARRAY_VISITOR)(int index, void *elm, size_t elmsize, void *context)

Definition at line 281 of file array.h.


Function Documentation

M_INLINE uint8_t* ARRAY_at ( ARRAY arr,
size_t  index 
)

Definition at line 174 of file array.h.

{
        if (index >= arr->elmcount) {
                return 0;
        }

        return arr->buffer + (index * arr->elmsize);
}
M_INLINE int ARRAY_copy_at ( ARRAY arr,
size_t  index,
void *  elm,
size_t  elmsize 
)

Definition at line 183 of file array.h.

{
        if (index >= arr->elmcount) {
                return -1;
        }
        
        if (elmsize != arr->elmsize) {
                return -1;
        }

        memcpy( elm, arr->buffer + (index * arr->elmsize), elmsize );
        return 0;
}
M_INLINE int ARRAY_delete_at ( ARRAY arr,
size_t  index 
)

Definition at line 202 of file array.h.

{
        if (index >= arr->elmcount) {
                return -1;
        }
        
        if (index < (arr->elmcount - 1)) {
                size_t elmsize = arr->elmsize;

                memmove( arr->buffer + index * elmsize,
                                 arr->buffer + (index + 1) * elmsize, 
                                 (arr->elmcount - index - 1) * elmsize);
                
        } 
        --arr->elmcount;
        return 0;
}
M_INLINE int ARRAY_findif ( ARRAY arr,
ARRAY_VISITOR  eval,
void *  context,
uint32_t *  retval 
)

Definition at line 353 of file array.h.

{
        size_t i;
        size_t sz = arr->elmcount;
        size_t elmsz = arr->elmsize;
        uint32_t ret;
        uint8_t *pos;

        if (!retval) {
          *retval = 0;
        }

        for(i = 0, pos = arr->buffer; i < sz; i++, pos += elmsz) {
                if ( (ret = eval( i, pos, elmsz, context )) != 0) {
                        if (retval) {
                                *retval = ret;
                        }
                        return i;
                }
        }
        return -1;
}
M_INLINE int ARRAY_findif_range ( ARRAY arr,
ARRAY_VISITOR  eval,
void *  context,
int  from_idx,
int  to_idx,
uint32_t *  retval 
)

Definition at line 376 of file array.h.

{
        int  i;
        size_t sz = arr->elmcount;
        size_t elmsz = arr->elmsize;
        uint32_t ret;
        uint8_t *pos;

        if (!retval) {
          *retval = 0;
        }

        if (!(from_idx > 0 && from_idx < to_idx && (size_t) to_idx < sz)) {
                return -1;
        }

        for(i = from_idx, pos = arr->buffer + (from_idx * elmsz); i < to_idx; i++, pos += elmsz) {
                if ((ret = eval( i, pos, elmsz, context )) != 0) {
                        if (retval) {
                                *retval = ret;
                        }                       
                        return i;
                }
        }

        return -1;
}
M_INLINE int ARRAY_findif_reverse ( ARRAY arr,
ARRAY_VISITOR  eval,
void *  context,
uint32_t *  retval 
)

Definition at line 407 of file array.h.

{
        size_t i;
        size_t sz = arr->elmcount;
        size_t elmsz = arr->elmsize;
        uint32_t ret;
        uint8_t *pos;

        if (!retval) {
          *retval = 0;
        }

        for(i = sz-1, pos = arr->buffer + (elmsz * (sz-1)); ; i--, pos -= elmsz) {
                if ((ret = eval( i, pos, elmsz, context )) != 0) {
                        if (retval) {
                                *retval = ret;
                        }                       
                        return i;
                }
                if (i == 0) {
                        break;
                }
        }
        return -1;
}
M_INLINE int ARRAY_findif_reverse_range ( ARRAY arr,
ARRAY_VISITOR  eval,
void *  context,
int  from_idx,
int  to_idx,
uint32_t *  retval 
)

Definition at line 434 of file array.h.

{
        int i;
        size_t sz = arr->elmcount;
        size_t elmsz = arr->elmsize;
        uint32_t ret;
        uint8_t *pos;

        if (!retval) {
          *retval = 0;
        }

        if (!(from_idx > 0 && from_idx < to_idx && (size_t) to_idx < sz)) {
                return -1;
        }

        for(i = to_idx - 1, pos = arr->buffer + (elmsz * i); ; i--, pos -= elmsz) {
                if ((ret = eval( i, pos, elmsz, context )) != 0) {
                        if (retval) {
                                *retval = ret;
                        }                       
                        return i;
                }
                if (i == from_idx) {
                        break;
                }
        }

        return -1;
}
M_INLINE void ARRAY_foreach ( ARRAY arr,
ARRAY_VISITOR  eval,
void *  context 
)

Definition at line 283 of file array.h.

{
        size_t i;
        size_t sz = arr->elmcount;
        size_t elmsz = arr->elmsize;
        uint8_t *pos;

        for(pos = arr->buffer, i = 0; i < sz; i++, pos += elmsz) {
                eval( i, pos, elmsz, context ); 
        }
}
M_INLINE int ARRAY_foreach_range ( ARRAY arr,
ARRAY_VISITOR  eval,
void *  context,
int  from_idx,
int  to_idx 
)

Definition at line 295 of file array.h.

{
        size_t i;
        size_t sz = arr->elmcount;
        size_t elmsz = arr->elmsize;
        uint8_t *pos;

        if (!(from_idx > 0 && from_idx < to_idx && (size_t) to_idx <  sz)) {
                return -1;
        }

        for(pos = arr->buffer + (from_idx * elmsz), i = from_idx; i < (size_t) to_idx; i++, pos += elmsz) {
                eval( i, pos, elmsz, context ); 
        }

        return 0;
}
M_INLINE void ARRAY_foreach_reverse ( ARRAY arr,
ARRAY_VISITOR  eval,
void *  context 
)

Definition at line 315 of file array.h.

{
        size_t i;
        size_t sz = arr->elmcount;
        size_t elmsz = arr->elmsize;
        uint8_t *pos;

        for(pos = arr->buffer + (elmsz * (sz-1)), i = sz-1; ; i--, pos -= elmsz) {
                eval( i, pos, elmsz, context ); 
                if (i == 0) {
                        break;
                }
        }
}
M_INLINE int ARRAY_foreach_reverse_range ( ARRAY arr,
ARRAY_VISITOR  eval,
void *  context,
int  from_idx,
int  to_idx 
)

Definition at line 331 of file array.h.

{
        int i;
        size_t sz = arr->elmcount;
        size_t elmsz = arr->elmsize;
        uint8_t *pos;

        if (!(from_idx > 0 && from_idx < to_idx && (size_t) to_idx < sz)) {
                return -1;
        }

        for(i = (to_idx - 1), pos = arr->buffer + (elmsz * i); ; i--, pos -= elmsz) {
                eval( i, pos, elmsz, context ); 
                if (i == from_idx) {
                        break;
                }
        }

        return 0;
}
M_INLINE void ARRAY_free ( ARRAY arr)

free all memory held by dynamic array (destructor).

Parameters:
buf(in out) the object

Definition at line 114 of file array.h.

{
        if (arr->buffer) {
                free( arr->buffer );
                arr->buffer = 0;
        }
}
M_INLINE int ARRAY_init ( ARRAY arr,
size_t  elmsize,
size_t  numofelem 
)

Definition at line 45 of file array.h.

{
        
        arr->elmsize    = elmsize;
        arr->elmcount   = 0;
        arr->elmmaxcount= numofelem;
        arr->buffer     = 0;


        if (numofelem) {
                if ((arr->buffer = (uint8_t *) malloc( elmsize * numofelem)) == 0) {
                        return -1;
                }
        }
        return 0;
}
M_INLINE int ARRAY_init_fixed ( ARRAY arr,
size_t  elmsize,
void *  ptr,
size_t  bufsize 
)

Allocates a dynamic array from already allocated memory area;.

The memory is not owned by this object, meaning that this dynamic array cannot be resized (does not grow as maximum size is exceed); data are is not freed in object destructor.

Parameters:
arr(out) the object
elmsize(in) size of one element
ptr(in) memory area that will contain
busize(in) size of memory area pointed to by ptr (size of Data area passed has to be greater or equal to the size of one element elmsize).
Returns:
0 if ok -1 on failure.

Definition at line 75 of file array.h.

{
        if (bufsize < elmsize) {
                return -1;
        }

        arr->elmsize = elmsize;

        arr->elmcount = 0;
        arr->elmmaxcount = bufsize / elmsize;
        arr->buffer = ptr;

        return 0;
}
int ARRAY_insert_at ( ARRAY arr,
size_t  index,
void *  elm,
size_t  elmsize 
)

Definition at line 29 of file array.c.

{       
        if (elmsize != arr->elmsize) {
                return -1;
        }

 
        if (index >= arr->elmmaxcount) {
                if (ARRAY_grow_default(arr,index+1)) {
                        return -1;
                }
        }


        if (arr->elmcount == arr->elmmaxcount) {
                if (ARRAY_grow_default(arr,arr->elmmaxcount+1)) {
                        return -1;
                }
        }


        if (index < arr->elmcount) {
                memmove( arr->buffer + (index + 1) * elmsize, 
                                 arr->buffer + index * elmsize, (arr->elmcount - index) * elmsize);

        } 

        if (index <= arr->elmcount) {
                arr->elmcount++;
        } else {
                memset( arr->buffer + arr->elmcount * arr->elmsize, 
                                0, 
                                arr->elmsize * (index - arr->elmcount) );               
                arr->elmcount = index + 1;
        }

        memcpy(arr->buffer + (index * elmsize), elm, elmsize);


        return 0;
}
M_INLINE size_t ARRAY_maxsize ( ARRAY arr)

returns maximum number of elements that can currently be held by this collection.

Parameters:
arr(in) the object
Returns:

Definition at line 142 of file array.h.

{
        return arr->elmmaxcount;
}
M_INLINE int ARRAY_pop_back ( ARRAY arr,
void *  ptr,
size_t  elmsize 
)

Definition at line 227 of file array.h.

{
        if (arr->elmcount <=0) {
                return -1;
        }

        if (ptr) {
                if (elmsize != arr->elmsize) {
                        return -1;
                }

                memcpy( ptr, arr->buffer + (--arr->elmcount) * arr->elmsize, elmsize);
        }
        return 0;
}
M_INLINE int ARRAY_push_back ( ARRAY arr,
void *  elm,
size_t  elmsize 
)

Definition at line 221 of file array.h.

{       
        return ARRAY_insert_at(arr,arr->elmcount,elm, elmsize);         
}
M_INLINE void ARRAY_reset ( ARRAY arr)

Definition at line 122 of file array.h.

{
        arr->elmcount = 0;
}
M_INLINE int ARRAY_resize ( ARRAY arr,
size_t  num_elem 
)

change size of dynamic array (i.e. change size of memory allocated for array) If requested size is smaller then the current size, then all skipping elements are discarded.

Parameters:
arr(in out) the object
num_elem(in) change maximum number of element to this number.

Definition at line 154 of file array.h.

{
        uint8_t * ptr;

        if (num_elem > arr->elmmaxcount) {
                ptr = realloc( arr->buffer, num_elem * arr->elmsize);
                if (!ptr) {
                        return -1;
                }
                arr->buffer = ptr;
                arr->elmmaxcount = num_elem;
                if (num_elem < arr->elmcount) {
                        arr->elmcount = num_elem;
                }
        } else {
                arr->elmcount = num_elem;
        }
        return 0;
}
int ARRAY_set_at ( ARRAY arr,
size_t  index,
void *  elm,
size_t  elmsize 
)

Definition at line 71 of file array.c.

{       
        if (elmsize != arr->elmsize) {
                return -1;
        }

 
        if (index >= arr->elmmaxcount) {
                if (ARRAY_grow_default(arr,index+1)) {
                        return -1;
                }
        }


        memcpy(arr->buffer + (index * elmsize), elm, elmsize);
        if (index >= arr->elmcount) {
                memset( arr->buffer + arr->elmcount * arr->elmsize, 
                                0, 
                                arr->elmsize * (index - arr->elmcount) );       
                arr->elmcount = index + 1;

        }

        return 0;
}
M_INLINE size_t ARRAY_size ( ARRAY arr)

returns number of objects that are currently held by this collection.

Parameters:
arr(in) the object
Returns:

Definition at line 132 of file array.h.

{
        return arr->elmcount;
}
M_INLINE int ARRAY_stack_top ( ARRAY arr,
void *  ptr,
size_t  elmsize 
)

Definition at line 243 of file array.h.

{
        if (arr->elmcount <=0) {
                return -1;
        }

        if (ptr) {
                if (elmsize != arr->elmsize) {
                        return -1;
                }

                memcpy( ptr, arr->buffer + arr->elmcount * arr->elmsize, elmsize);
        }
        return 0;
}