1/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. 2 * Use of this source code is governed by a BSD-style license that can be 3 * found in the LICENSE file. 4 */ 5 6#ifndef CRAS_ARRAY_H_ 7#define CRAS_ARRAY_H_ 8 9#ifdef __cplusplus 10extern "C" { 11#endif 12 13#include <string.h> 14 15/* 16 17Sample usage: 18 19DECLARE_ARRAY_TYPE(double, double_array); 20 21void f() 22{ 23 int i; 24 double *p; 25 double_array a = ARRAY_INIT; 26 27 ARRAY_APPEND(&a, 1.0); 28 *ARRAY_APPEND_ZERO(&a) = 2.0; 29 30 FOR_ARRAY_ELEMENT(&a, i, p) { 31 printf("%f\n", *p); // prints 1.0 2.0 32 } 33 34 ARRAY_FREE(&a); 35} 36 37*/ 38 39/* Define a type for the array given the element type */ 40#define DECLARE_ARRAY_TYPE(element_type, array_type) \ 41 typedef struct { \ 42 int count; \ 43 int size; \ 44 element_type *element; \ 45 } array_type; 46 47/* The initializer for an empty array is the zero value. */ 48#define ARRAY_INIT {} 49 50#define _ARRAY_EXTEND(a) \ 51 ({ \ 52 if ((a)->count >= (a)->size) { \ 53 if ((a)->size == 0) \ 54 (a)->size = 4; \ 55 else \ 56 (a)->size *= 2; \ 57 (a)->element = (__typeof((a)->element)) \ 58 realloc((a)->element, \ 59 (a)->size * \ 60 sizeof((a)->element[0])); \ 61 } \ 62 &(a)->element[((a)->count)++]; \ 63 }) 64 65/* Append an element with the given value to the array a */ 66#define ARRAY_APPEND(a, value) \ 67 do { \ 68 *_ARRAY_EXTEND(a) = (value); \ 69 } while (0) 70 71/* Append a zero element to the array a and return the pointer to the element */ 72#define ARRAY_APPEND_ZERO(a) \ 73 ({ \ 74 typeof((a)->element) _tmp_ptr = _ARRAY_EXTEND(a); \ 75 memset(_tmp_ptr, 0, sizeof(*_tmp_ptr)); \ 76 _tmp_ptr; \ 77 }) 78 79/* Return the number of elements in the array a */ 80#define ARRAY_COUNT(a) ((a)->count) 81 82/* Return a pointer to the i-th element in the array a */ 83#define ARRAY_ELEMENT(a, i) ((a)->element + (i)) 84 85/* Return the index of the element pointed by p in the array a */ 86#define ARRAY_INDEX(a, p) ((p) - (a)->element) 87 88/* Go through each element in the array a and assign index and pointer 89 to the element to the variable i and ptr */ 90#define FOR_ARRAY_ELEMENT(a, i, ptr) \ 91 for ((i) = 0, (ptr) = (a)->element; (i) < (a)->count; \ 92 (i)++, (ptr)++) 93 94/* Free the memory used by the array a. The array becomes an empty array. */ 95#define ARRAY_FREE(a) \ 96 do { \ 97 free((a)->element); \ 98 (a)->element = NULL; \ 99 (a)->size = 0; \ 100 (a)->count = 0; \ 101 } while (0) 102 103 104/* Return the index of the element with the value x. -1 if not found */ 105#define ARRAY_FIND(a, x) \ 106 ({ \ 107 typeof((a)->element) _bptr = (a)->element; \ 108 typeof((a)->element) _eptr = (a)->element + (a)->count; \ 109 for (; _bptr != _eptr && *_bptr != x; _bptr++) \ 110 ; \ 111 (_bptr == _eptr) ? -1 : (_bptr - (a)->element); \ 112 }) 113 114#ifdef __cplusplus 115} /* extern "C" */ 116#endif 117 118#endif /* CRAS_ARRAY_H_ */ 119