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, __args...) \
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;\
46 } __name##_t, *__name##_p;
48 #define C_ARRAY_NULL { 0, 0, NULL }
50 #define IMPLEMENT_C_ARRAY(__name) \
51 static const __name##_t __name##_zero = C_ARRAY_NULL; \
52 static C_ARRAY_INLINE \
57 if (a->e) free(a->e);\
60 static C_ARRAY_INLINE \
67 static C_ARRAY_INLINE \
68 void __name##_realloc(\
69 __name##_p a, __name##_count_t size) \
71 if (!a || a->size == size) return; \
72 a->e = realloc(a->e, size * sizeof(__name##_element_t));\
75 static C_ARRAY_INLINE \
80 __name##_count_t n = a->count + __name##_page_size;\
81 n -= (n % __name##_page_size);\
83 __name##_realloc(a, n);\
85 static C_ARRAY_INLINE \
86 __name##_element_t * __name##_get_ptr(\
87 __name##_p a, __name##_count_t index) \
90 if (index > a->count) index = a->count;\
91 return index < a->count ? a->e + index : NULL;\
93 static C_ARRAY_INLINE \
94 __name##_count_t __name##_add(\
95 __name##_p a, __name##_element_t e) \
98 if (a->count + 1 >= a->size)\
99 __name##_realloc(a, a->size + __name##_page_size);\
100 a->e[a->count++] = e;\
103 static C_ARRAY_INLINE \
104 __name##_count_t __name##_insert(\
105 __name##_p a, __name##_count_t index, \
106 __name##_element_t * e, __name##_count_t count) \
109 if (index > a->count) index = a->count;\
110 if (a->count + count >= a->size) \
111 __name##_realloc(a, (((a->count + count) / __name##_page_size)+1) * __name##_page_size);\
112 if (index < a->count)\
113 memmove(&a->e[index + count], &a->e[index], \
114 (a->count - index + count) * sizeof(__name##_element_t));\
115 memmove(&a->e[index], e, count * sizeof(__name##_element_t));\
119 static C_ARRAY_INLINE \
120 __name##_count_t __name##_delete(\
121 __name##_p a, __name##_count_t index, __name##_count_t count) \
124 if (index > a->count) index = a->count;\
125 if (index + count > a->count) \
126 count = a->count - index;\
127 if (count && a->count - index) { \
128 memmove(&a->e[index], &a->e[index + count], \
129 (a->count - index - count) * sizeof(__name##_element_t));\
135 #endif /* __C_ARRAY_H___ */