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 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