view array.h @ 55:cda80ba48029

Add beautiful gcc attribute to buffer
author David Demelier <markand@malikania.fr>
date Fri, 04 Nov 2011 16:11:31 +0100
parents 82bbd3b869e3
children 669f2734557d
line wrap: on
line source

/*
 * array.h -- manipulate dynamic arrays
 *
 * Copyright (c) 2011, David Demelier <markand@malikania.fr>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifndef _ARRAY_H_
#define _ARRAY_H_

#define ARRAY_DEFAULT_BSIZE	128

enum array_type {
	ARRAY_FIXED	= 0,
	ARRAY_AUTO	= 1
};

struct array {
	enum array_type	type;	/* array's type (default FIXED) */
	void		*data;	/* array of data */
	int		length;	/* number of element inside */
	size_t		size;	/* current buffer size (allocated memory) */
	size_t		unit;	/* unit size (sizeof the object) */
	int		bsize;	/* block size (used when growing array) */
	int		i;	/* only for ARRAY_FOREACH(_R) */
};

typedef void (*array_map_fn)(void *, void *);
typedef int (*array_cmp_fn)(void *, void *);

struct array	*array_new(enum array_type, size_t, int);
int		array_push(struct array *, const void *);
int		array_insert(struct array *, const void *, int);
int		array_append(struct array *, const void *);
void		array_pop(struct array *);
void		array_unqueue(struct array *);
void		array_remove(struct array *, int);
void		array_unref(struct array *, const void *);
int		array_iswap(struct array *, int, int);
int		array_pswap(struct array *, const void *, const void *);
void		array_map(const struct array *, array_map_fn, void *);
void		*array_find(const struct array *, array_cmp_fn, int *, void *);
void		array_clear(struct array *);
void		array_free(struct array *);

#define ARRAY_HEAD(a)								\
	(a->data)
#define ARRAY_TAIL(a)								\
	((void *) ((char *) (a)->data +						\
	    ((a)->unit * (((a)->length == 0) ? 0 : ((a)->length - 1)))))
#define ARRAY_INDEX(a, i)							\
	(((i) < 0 || (a)->length == 0) ? (ARRAY_HEAD((a)))	/* < 0 head */	\
	    : ((i) >= (a)->length) ? (ARRAY_TAIL((a)))		/* > l tail */	\
	    : ((void *) ((char *) (a)->data + ((a)->unit * (i))))) /* correct */

#define ARRAY_FOREACH_R(a, var)							\
	for ((a)->i = 0, var = ARRAY_TAIL((a));					\
	    (a)->i < (a)->length; ++(a)->i, --var)

#define ARRAY_FOREACH(a, var)							\
	for ((a)->i = 0, var = (a)->data; (a)->i < (a)->length; ++(a)->i, ++var)


#endif /* _ARRAY_H_ */