| /* 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; |
| |
| ARRAY_ELEMENT_FOREACH(&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 ARRAY_ELEMENT_FOREACH(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_ */ |