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 10 extern "C" { 11 #endif 12 13 #include <string.h> 14 15 /* 16 17 Sample usage: 18 19 DECLARE_ARRAY_TYPE(double, double_array); 20 21 void 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 ARRAY_ELEMENT_FOREACH(&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 } 51 52 #define _ARRAY_EXTEND(a) \ 53 ({ \ 54 if ((a)->count >= (a)->size) { \ 55 if ((a)->size == 0) \ 56 (a)->size = 4; \ 57 else \ 58 (a)->size *= 2; \ 59 (a)->element = (__typeof((a)->element))realloc( \ 60 (a)->element, \ 61 (a)->size * sizeof((a)->element[0])); \ 62 } \ 63 &(a)->element[((a)->count)++]; \ 64 }) 65 66 /* Append an element with the given value to the array a */ 67 #define ARRAY_APPEND(a, value) \ 68 do { \ 69 *_ARRAY_EXTEND(a) = (value); \ 70 } while (0) 71 72 /* Append a zero element to the array a and return the pointer to the element */ 73 #define ARRAY_APPEND_ZERO(a) \ 74 ({ \ 75 typeof((a)->element) _tmp_ptr = _ARRAY_EXTEND(a); \ 76 memset(_tmp_ptr, 0, sizeof(*_tmp_ptr)); \ 77 _tmp_ptr; \ 78 }) 79 80 /* Return the number of elements in the array a */ 81 #define ARRAY_COUNT(a) ((a)->count) 82 83 /* Return a pointer to the i-th element in the array a */ 84 #define ARRAY_ELEMENT(a, i) ((a)->element + (i)) 85 86 /* Return the index of the element pointed by p in the array a */ 87 #define ARRAY_INDEX(a, p) ((p) - (a)->element) 88 89 /* Go through each element in the array a and assign index and pointer 90 to the element to the variable i and ptr */ 91 #define ARRAY_ELEMENT_FOREACH(a, i, ptr) \ 92 for ((i) = 0, (ptr) = (a)->element; (i) < (a)->count; (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 /* Return the index of the element with the value x. -1 if not found */ 104 #define ARRAY_FIND(a, x) \ 105 ({ \ 106 typeof((a)->element) _bptr = (a)->element; \ 107 typeof((a)->element) _eptr = (a)->element + (a)->count; \ 108 for (; _bptr != _eptr && *_bptr != x; _bptr++) \ 109 ; \ 110 (_bptr == _eptr) ? -1 : (_bptr - (a)->element); \ 111 }) 112 113 #ifdef __cplusplus 114 } /* extern "C" */ 115 #endif 116 117 #endif /* CRAS_ARRAY_H_ */ 118