/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef CRAS_ARRAY_H_
#define CRAS_ARRAY_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <string.h>
/*
Sample usage:
DECLARE_ARRAY_TYPE(double, double_array);
void f()
{
int i;
double *p;
double_array a = ARRAY_INIT;
ARRAY_APPEND(&a, 1.0);
*ARRAY_APPEND_ZERO(&a) = 2.0;
FOR_ARRAY_ELEMENT(&a, i, p) {
printf("%f\n", *p); // prints 1.0 2.0
}
ARRAY_FREE(&a);
}
*/
/* Define a type for the array given the element type */
#define DECLARE_ARRAY_TYPE(element_type, array_type) \
typedef struct { \
int count; \
int size; \
element_type *element; \
} array_type;
/* The initializer for an empty array is the zero value. */
#define ARRAY_INIT {}
#define _ARRAY_EXTEND(a) \
({ \
if ((a)->count >= (a)->size) { \
if ((a)->size == 0) \
(a)->size = 4; \
else \
(a)->size *= 2; \
(a)->element = (__typeof((a)->element)) \
realloc((a)->element, \
(a)->size * \
sizeof((a)->element[0])); \
} \
&(a)->element[((a)->count)++]; \
})
/* Append an element with the given value to the array a */
#define ARRAY_APPEND(a, value) \
do { \
*_ARRAY_EXTEND(a) = (value); \
} while (0)
/* Append a zero element to the array a and return the pointer to the element */
#define ARRAY_APPEND_ZERO(a) \
({ \
typeof((a)->element) _tmp_ptr = _ARRAY_EXTEND(a); \
memset(_tmp_ptr, 0, sizeof(*_tmp_ptr)); \
_tmp_ptr; \
})
/* Return the number of elements in the array a */
#define ARRAY_COUNT(a) ((a)->count)
/* Return a pointer to the i-th element in the array a */
#define ARRAY_ELEMENT(a, i) ((a)->element + (i))
/* Return the index of the element pointed by p in the array a */
#define ARRAY_INDEX(a, p) ((p) - (a)->element)
/* Go through each element in the array a and assign index and pointer
to the element to the variable i and ptr */
#define FOR_ARRAY_ELEMENT(a, i, ptr) \
for ((i) = 0, (ptr) = (a)->element; (i) < (a)->count; \
(i)++, (ptr)++)
/* Free the memory used by the array a. The array becomes an empty array. */
#define ARRAY_FREE(a) \
do { \
free((a)->element); \
(a)->element = NULL; \
(a)->size = 0; \
(a)->count = 0; \
} while (0)
/* Return the index of the element with the value x. -1 if not found */
#define ARRAY_FIND(a, x) \
({ \
typeof((a)->element) _bptr = (a)->element; \
typeof((a)->element) _eptr = (a)->element + (a)->count; \
for (; _bptr != _eptr && *_bptr != x; _bptr++) \
; \
(_bptr == _eptr) ? -1 : (_bptr - (a)->element); \
})
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* CRAS_ARRAY_H_ */