4 Copyright 2012 Michel Pollet <buserror@gmail.com>
6 This file is part of gcodepp.
8 gcodepp is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 gcodepp is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with gcodepp. If not, see <http://www.gnu.org/licenses/>.
23 #ifndef __C_ARRAY_H___
24 #define __C_ARRAY_H___
30 #ifndef C_ARRAY_INLINE
31 #define C_ARRAY_INLINE inline
33 #ifndef C_ARRAY_SIZE_TYPE
34 #define C_ARRAY_SIZE_TYPE uint32_t
37 #define DECLARE_C_ARRAY(__type, __name, __page) \
38 enum { __name##_page_size = __page }; \
39 typedef __type __name##_element_t; \
40 typedef C_ARRAY_SIZE_TYPE __name##_count_t; \
41 typedef struct __name##_t {\
42 volatile __name##_count_t count;\
43 volatile __name##_count_t size;\
44 __name##_element_t * e;\
45 } __name##_t, *__name##_p;
47 #define C_ARRAY_NULL { 0, 0, NULL }
49 #define IMPLEMENT_C_ARRAY(__name) \
50 static const __name##_t __name##_zero = C_ARRAY_NULL; \
51 static C_ARRAY_INLINE \
56 if (a->e) free(a->e);\
59 static C_ARRAY_INLINE \
66 static C_ARRAY_INLINE \
67 void __name##_realloc(\
68 __name##_p a, __name##_count_t size) \
70 if (!a || a->size == size) return; \
71 a->e = realloc(a->e, size * sizeof(__name##_element_t));\
74 static C_ARRAY_INLINE \
79 __name##_count_t n = a->count + __name##_page_size;\
80 n -= (n % __name##_page_size);\
82 __name##_realloc(a, n);\
84 static C_ARRAY_INLINE \
85 __name##_element_t * __name##_get_ptr(\
86 __name##_p a, __name##_count_t index) \
89 if (index > a->count) index = a->count;\
90 return index < a->count ? a->e + index : NULL;\
92 static C_ARRAY_INLINE \
93 __name##_count_t __name##_add(\
94 __name##_p a, __name##_element_t e) \
97 if (a->count + 1 >= a->size)\
98 __name##_realloc(a, a->size + __name##_page_size);\
99 a->e[a->count++] = e;\
102 static C_ARRAY_INLINE \
103 __name##_count_t __name##_insert(\
104 __name##_p a, __name##_count_t index, \
105 __name##_element_t * e, __name##_count_t count) \
108 if (index > a->count) index = a->count;\
109 if (a->count + count >= a->size) \
110 __name##_realloc(a, (((a->count + count) / __name##_page_size)+1) * __name##_page_size);\
111 if (index < a->count)\
112 memmove(&a->e[index + count], &a->e[index], \
113 (a->count - index + count) * sizeof(__name##_element_t));\
114 memmove(&a->e[index], e, count * sizeof(__name##_element_t));\
118 static C_ARRAY_INLINE \
119 __name##_count_t __name##_delete(\
120 __name##_p a, __name##_count_t index, __name##_count_t count) \
123 if (index > a->count) index = a->count;\
124 if (index + count > a->count) \
125 count = a->count - index;\
126 if (count && a->count - index) { \
127 memmove(&a->e[index], &a->e[index + count], \
128 (a->count - index - count) * sizeof(__name##_element_t));\
134 #endif /* __C_ARRAY_H___ */