summaryrefslogtreecommitdiffstats
path: root/array.h
blob: fde200ed9e83f48c3a876a072cc31f80dc67eb4d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/* $Id: array.h,v 1.2 2007-08-27 08:08:19 nicm Exp $ */

/*
 * Copyright (c) 2006 Nicholas Marriott <nicm@users.sourceforge.net>
 *
 * Permission to use, copy, modify, and 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 MIND, 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_DECL(n, c)						\
	struct n {							\
		c	*list;						\
		u_int	 num;						\
		size_t	 space;						\
	}

#define ARRAY_ITEM(a, i) ((a)->list[i])
#define ARRAY_ITEMSIZE(a) (sizeof *(a)->list)

#define ARRAY_EMPTY(a) ((a) == NULL || (a)->num == 0)
#define ARRAY_LENGTH(a) ((a)->num)
#define ARRAY_DATA(a) ((a)->list)

#define ARRAY_FIRST(a) ARRAY_ITEM(a, 0)
#define ARRAY_LAST(a) ARRAY_ITEM(a, (a)->num - 1)

#define ARRAY_INIT(a) do {						\
	(a)->num = 0;							\
	(a)->list = NULL;		 				\
	(a)->space = 0;							\
} while (0)
#define ARRAY_CLEAR(a) do {						\
	(a)->num = 0;							\
} while (0)

#define ARRAY_SET(a, i, s) do {						\
	if (((u_int) (i)) >= (a)->num)					\
		abort();						\
	(a)->list[i] = s;						\
} while (0)

#define ARRAY_ADD(a, s) do {						\
	ENSURE_SIZE2((a)->list, (a)->space, (a)->num + 1, ARRAY_ITEMSIZE(a)); \
	(a)->list[(a)->num] = s;					\
	(a)->num++;							\
} while (0)
#define ARRAY_REMOVE(a, i) do {						\
	if (((u_int) (i)) >= (a)->num)					\
		abort();						\
	if (i < (a)->num - 1) {						\
		memmove((a)->list + (i), (a)->list + (i) + 1, 		\
		    ARRAY_ITEMSIZE(a) * ((a)->num - (i) - 1)); 		\
	}								\
	(a)->num--;							\
        if ((a)->num == 0)						\
		ARRAY_FREE(a);						\
} while (0)

#define ARRAY_EXPAND(a, n) do {						\
	ENSURE_SIZE2((a)->list, (a)->space, (a)->num + n, ARRAY_ITEMSIZE(a)); \
	(a)->num += n;							\
} while (0)
#define ARRAY_TRUNC(a, n) do {						\
	if ((a)->num > n)						\
		(a)->num -= n;				       		\
	else								\
		ARRAY_FREE(a);						\
} while (0)

#define ARRAY_CONCAT(a, b) do {						\
	ENSURE_SIZE2((a)->list, (a)->space, (a)->num + (b)->num, 	\
	    ARRAY_ITEMSIZE(a)); 					\
	memcpy((a)->list + (a)->num, (b)->list, (b)->num * ARRAY_ITEMSIZE(a)) \
	(a)->num += (b)->num;						\
} while (0)

#define ARRAY_FREE(a) do {						\
	if ((a)->list != NULL)						\
		xfree((a)->list);					\
	ARRAY_INIT(a);							\
} while (0)
#define ARRAY_FREEALL(a) do {						\
	ARRAY_FREE(a);							\
	xfree(a);							\
} while (0)

#endif