#ifndef INCLUDED_FLEXARR_H
#define INCLUDED_FLEXARR_H

/*-
 * SPDX-FileCopyrightText: Peter Pentchev
 * SPDX-License-Identifier: BSD-2-Clause
 *
 * flexarr - a trivial implementation of a "flexible array" that may be
 * reallocated as new elements are added
 */

#define FLEXARR_INIT(arr, nelem, nalloc)	do { \
	(arr) = NULL; \
	(nelem) = (nalloc) = 0; \
} while (0)

#define FLEXARR_ALLOC(arr, count, nelem, nalloc)	do { \
	size_t flexarr_ncount = (nelem) + (count); \
	if (flexarr_ncount > (nalloc)) { \
		size_t flexarr_nsize; \
		void *flexarr_p; \
		flexarr_nsize = (nalloc) * 2 + 1; \
		if (flexarr_nsize < flexarr_ncount) \
			flexarr_nsize = flexarr_ncount; \
		flexarr_p = realloc((arr), flexarr_nsize * sizeof(*(arr))); \
		if (flexarr_p == NULL) \
			errx(1, "Out of memory"); \
		(arr) = flexarr_p; \
		(nalloc) = flexarr_nsize; \
	} \
	(nelem) = flexarr_ncount; \
} while (0)

#define FLEXARR_FREE(arr, nalloc)	do { \
	free(arr); \
} while (0)

#endif
