xref: /minix3/external/bsd/tmux/dist/array.h (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc /* Id */
2eda6f593SDavid van Moolenbroek 
3eda6f593SDavid van Moolenbroek /*
4eda6f593SDavid van Moolenbroek  * Copyright (c) 2006 Nicholas Marriott <nicm@users.sourceforge.net>
5eda6f593SDavid van Moolenbroek  *
6eda6f593SDavid van Moolenbroek  * Permission to use, copy, modify, and distribute this software for any
7eda6f593SDavid van Moolenbroek  * purpose with or without fee is hereby granted, provided that the above
8eda6f593SDavid van Moolenbroek  * copyright notice and this permission notice appear in all copies.
9eda6f593SDavid van Moolenbroek  *
10eda6f593SDavid van Moolenbroek  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11eda6f593SDavid van Moolenbroek  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12eda6f593SDavid van Moolenbroek  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13eda6f593SDavid van Moolenbroek  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14eda6f593SDavid van Moolenbroek  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15eda6f593SDavid van Moolenbroek  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16eda6f593SDavid van Moolenbroek  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17eda6f593SDavid van Moolenbroek  */
18eda6f593SDavid van Moolenbroek 
19eda6f593SDavid van Moolenbroek #ifndef ARRAY_H
20eda6f593SDavid van Moolenbroek #define ARRAY_H
21eda6f593SDavid van Moolenbroek 
22eda6f593SDavid van Moolenbroek #define ARRAY_INITIALIZER { NULL, 0, 0 }
23eda6f593SDavid van Moolenbroek 
24eda6f593SDavid van Moolenbroek #define ARRAY_DECL(n, c)						\
25eda6f593SDavid van Moolenbroek 	struct n {							\
26eda6f593SDavid van Moolenbroek 		c	*list;						\
27eda6f593SDavid van Moolenbroek 		u_int	 num;						\
28eda6f593SDavid van Moolenbroek 		size_t	 space;						\
29eda6f593SDavid van Moolenbroek 	}
30eda6f593SDavid van Moolenbroek 
31eda6f593SDavid van Moolenbroek #define ARRAY_ITEM(a, i) ((a)->list[i])
32eda6f593SDavid van Moolenbroek #define ARRAY_ITEMSIZE(a) (sizeof *(a)->list)
33eda6f593SDavid van Moolenbroek #define ARRAY_INITIALSPACE(a) (10 * ARRAY_ITEMSIZE(a))
34eda6f593SDavid van Moolenbroek 
35eda6f593SDavid van Moolenbroek #define ARRAY_ENSURE(a, n) do {						\
36eda6f593SDavid van Moolenbroek 	if (UINT_MAX - (n) < (a)->num)					\
37eda6f593SDavid van Moolenbroek 		fatalx("number too big");				\
38eda6f593SDavid van Moolenbroek 	if (SIZE_MAX / ((a)->num + (n)) < ARRAY_ITEMSIZE(a))		\
39eda6f593SDavid van Moolenbroek 		fatalx("size too big");					\
40eda6f593SDavid van Moolenbroek 	if ((a)->space == 0) {						\
41eda6f593SDavid van Moolenbroek 	       	(a)->space = ARRAY_INITIALSPACE(a);			\
42eda6f593SDavid van Moolenbroek 		(a)->list = xrealloc((a)->list, 1, (a)->space);		\
43eda6f593SDavid van Moolenbroek 	}								\
44eda6f593SDavid van Moolenbroek 	while ((a)->space <= ((a)->num + (n)) * ARRAY_ITEMSIZE(a)) {	\
45eda6f593SDavid van Moolenbroek 		(a)->list = xrealloc((a)->list, 2, (a)->space);		\
46eda6f593SDavid van Moolenbroek 		(a)->space *= 2;					\
47eda6f593SDavid van Moolenbroek 	}								\
48eda6f593SDavid van Moolenbroek } while (0)
49eda6f593SDavid van Moolenbroek 
50eda6f593SDavid van Moolenbroek #define ARRAY_EMPTY(a) (((void *) (a)) == NULL || (a)->num == 0)
51eda6f593SDavid van Moolenbroek #define ARRAY_LENGTH(a) ((a)->num)
52eda6f593SDavid van Moolenbroek #define ARRAY_DATA(a) ((a)->list)
53eda6f593SDavid van Moolenbroek 
54eda6f593SDavid van Moolenbroek #define ARRAY_FIRST(a) ARRAY_ITEM(a, 0)
55eda6f593SDavid van Moolenbroek #define ARRAY_LAST(a) ARRAY_ITEM(a, (a)->num - 1)
56eda6f593SDavid van Moolenbroek 
57eda6f593SDavid van Moolenbroek #define ARRAY_INIT(a) do {						\
58eda6f593SDavid van Moolenbroek 	(a)->num = 0;							\
59eda6f593SDavid van Moolenbroek 	(a)->list = NULL;		 				\
60eda6f593SDavid van Moolenbroek 	(a)->space = 0;							\
61eda6f593SDavid van Moolenbroek } while (0)
62eda6f593SDavid van Moolenbroek #define ARRAY_CLEAR(a) do {						\
63eda6f593SDavid van Moolenbroek 	(a)->num = 0;							\
64eda6f593SDavid van Moolenbroek } while (0)
65eda6f593SDavid van Moolenbroek 
66eda6f593SDavid van Moolenbroek #define ARRAY_SET(a, i, s) do {						\
67eda6f593SDavid van Moolenbroek 	(a)->list[i] = s;						\
68eda6f593SDavid van Moolenbroek } while (0)
69eda6f593SDavid van Moolenbroek 
70eda6f593SDavid van Moolenbroek #define ARRAY_ADD(a, s) do {						\
71eda6f593SDavid van Moolenbroek 	ARRAY_ENSURE(a, 1);						\
72eda6f593SDavid van Moolenbroek 	(a)->list[(a)->num] = s;					\
73eda6f593SDavid van Moolenbroek 	(a)->num++;							\
74eda6f593SDavid van Moolenbroek } while (0)
75eda6f593SDavid van Moolenbroek #define ARRAY_INSERT(a, i, s) do {					\
76eda6f593SDavid van Moolenbroek 	ARRAY_ENSURE(a, 1);						\
77eda6f593SDavid van Moolenbroek 	if ((i) < (a)->num) {						\
78eda6f593SDavid van Moolenbroek 		memmove((a)->list + (i) + 1, (a)->list + (i), 		\
79eda6f593SDavid van Moolenbroek 		    ARRAY_ITEMSIZE(a) * ((a)->num - (i)));		\
80eda6f593SDavid van Moolenbroek 	}								\
81eda6f593SDavid van Moolenbroek 	(a)->list[i] = s;						\
82eda6f593SDavid van Moolenbroek 	(a)->num++;							\
83eda6f593SDavid van Moolenbroek } while (0)
84eda6f593SDavid van Moolenbroek #define ARRAY_REMOVE(a, i) do {						\
85eda6f593SDavid van Moolenbroek 	if ((i) < (a)->num - 1) {					\
86eda6f593SDavid van Moolenbroek 		memmove((a)->list + (i), (a)->list + (i) + 1, 		\
87eda6f593SDavid van Moolenbroek 		    ARRAY_ITEMSIZE(a) * ((a)->num - (i) - 1));		\
88eda6f593SDavid van Moolenbroek 	}								\
89eda6f593SDavid van Moolenbroek 	(a)->num--;							\
90eda6f593SDavid van Moolenbroek 	if ((a)->num == 0)						\
91eda6f593SDavid van Moolenbroek 		ARRAY_FREE(a);						\
92eda6f593SDavid van Moolenbroek } while (0)
93eda6f593SDavid van Moolenbroek 
94eda6f593SDavid van Moolenbroek #define ARRAY_EXPAND(a, n) do {						\
95eda6f593SDavid van Moolenbroek 	ARRAY_ENSURE(a, n);						\
96eda6f593SDavid van Moolenbroek 	(a)->num += n;							\
97eda6f593SDavid van Moolenbroek } while (0)
98eda6f593SDavid van Moolenbroek #define ARRAY_TRUNC(a, n) do {						\
99eda6f593SDavid van Moolenbroek 	if ((a)->num > n)						\
100eda6f593SDavid van Moolenbroek 		(a)->num -= n;				       		\
101eda6f593SDavid van Moolenbroek 	else								\
102eda6f593SDavid van Moolenbroek 		ARRAY_FREE(a);						\
103eda6f593SDavid van Moolenbroek } while (0)
104eda6f593SDavid van Moolenbroek 
105eda6f593SDavid van Moolenbroek #define ARRAY_CONCAT(a, b) do {						\
106eda6f593SDavid van Moolenbroek 	ARRAY_ENSURE(a, (b)->num);					\
107eda6f593SDavid van Moolenbroek 	memcpy((a)->list + (a)->num, (b)->list, (b)->num * ARRAY_ITEMSIZE(a)); \
108eda6f593SDavid van Moolenbroek 	(a)->num += (b)->num;						\
109eda6f593SDavid van Moolenbroek } while (0)
110eda6f593SDavid van Moolenbroek 
111eda6f593SDavid van Moolenbroek #define ARRAY_FREE(a) do {						\
112*0a6a1f1dSLionel Sambuc 	free((a)->list);						\
113eda6f593SDavid van Moolenbroek 	ARRAY_INIT(a);							\
114eda6f593SDavid van Moolenbroek } while (0)
115eda6f593SDavid van Moolenbroek #define ARRAY_FREEALL(a) do {						\
116eda6f593SDavid van Moolenbroek 	ARRAY_FREE(a);							\
117*0a6a1f1dSLionel Sambuc 	free(a);							\
118eda6f593SDavid van Moolenbroek } while (0)
119eda6f593SDavid van Moolenbroek 
120eda6f593SDavid van Moolenbroek #endif
121