Sample: cleaning up Inheritance
[io/quag.git] / libs / basekit / source / UArray.h
blobb3e10dd5a2d78848f99e205424f38f9152f0b8e0
1 /*
2 copyright: Steve Dekorte, 2006. All rights reserved.
3 license: See _BSDLicense.txt.
4 description: A mutable array of same-sized values.
5 */
8 #ifndef UARRAY_DEFINED
9 #define UARRAY_DEFINED 1
11 #include "Common.h"
12 #include <stdarg.h>
13 #include <stdio.h>
14 #include <stddef.h>
16 #ifdef __cplusplus
17 extern "C" {
18 #endif
20 #if !defined(float32_t)
21 typedef float float32_t;
22 typedef double float64_t;
23 #endif
25 typedef size_t PID_TYPE;
27 enum CTYPE
29 CTYPE_uint8_t,
30 CTYPE_uint16_t,
31 CTYPE_uint32_t,
32 CTYPE_uint64_t,
34 CTYPE_int8_t,
35 CTYPE_int16_t,
36 CTYPE_int32_t,
37 CTYPE_int64_t,
39 CTYPE_float32_t,
40 CTYPE_float64_t,
42 CTYPE_uintptr_t
45 typedef int CTYPE;
47 enum CENCODING
49 CENCODING_ASCII,
50 CENCODING_UTF8,
51 CENCODING_UTF16,
52 CENCODING_UTF32,
53 CENCODING_NUMBER
56 typedef int CENCODING;
58 typedef struct
60 uint8_t uint8_t;
61 uint16_t uint16_t;
62 uint32_t uint32_t;
63 uint64_t uint64_t;
64 int8_t int8_t;
65 int16_t int16_t;
66 int32_t int32_t;
67 int64_t int64_t;
68 float32_t float32_t;
69 float64_t float64_t;
70 uintptr_t uintptr_t;
71 } UArrayValueUnion;
73 #define UARRAY_DEBUG 1
75 typedef struct
77 uint8_t *data; // memory for items
78 size_t size; // number of items
79 CTYPE itemType;
80 size_t itemSize;
81 uintptr_t hash;
82 uint8_t encoding;
83 #ifdef UARRAY_DEBUG
84 int stackAllocated;
85 #endif
86 } UArray;
88 typedef UArray CharUArray;
89 typedef UArray PtrUArray;
90 typedef UArray FloatUArray;
92 BASEKIT_API const void *UArray_data(const UArray *self);
93 BASEKIT_API const uint8_t *UArray_bytes(const UArray *self);
94 BASEKIT_API uint8_t *UArray_mutableBytes(UArray *self);
95 BASEKIT_API const char *UArray_asCString(const UArray *self);
97 BASEKIT_API size_t UArray_SizeOfCtype(CTYPE type);
99 BASEKIT_API const char *CTYPE_name(CTYPE type);
100 BASEKIT_API int CTYPE_forName(const char *name);
102 BASEKIT_API const char *CENCODING_name(CENCODING encoding);
103 BASEKIT_API int CENCODING_forName(const char *name);
105 BASEKIT_API void UArray_unsupported_with_(const UArray *self, const char *methodName, const UArray *other);
106 BASEKIT_API void UArray_error_(const UArray *self, char *e);
108 BASEKIT_API UArray *UArray_new(void);
109 BASEKIT_API UArray *UArray_newWithData_type_size_copy_(void *data, CTYPE type, size_t size, int copy);
110 BASEKIT_API UArray *UArray_newWithCString_copy_(char *s, int copy);
111 BASEKIT_API UArray *UArray_newWithCString_(const char *s);
112 BASEKIT_API void UArray_setCString_(UArray *self, const char *s);
113 BASEKIT_API void UArray_setData_type_size_copy_(UArray *self, void *data, CTYPE type, size_t size, int copy);
114 BASEKIT_API UArray *UArray_clone(const UArray *self);
115 BASEKIT_API void UArray_show(const UArray *self);
116 BASEKIT_API void UArray_print(const UArray *self);
118 BASEKIT_API UArray UArray_stackAllocedWithData_type_size_(void *data, CTYPE type, size_t size);
119 BASEKIT_API UArray UArray_stackAllocedWithCString_(char *s);
120 BASEKIT_API UArray UArray_stackAllocedEmptyUArray(void);
122 BASEKIT_API void UArray_stackFree(UArray *self);
123 BASEKIT_API void UArray_free(UArray *self);
125 BASEKIT_API CTYPE UArray_itemType(const UArray *self);
126 BASEKIT_API size_t UArray_itemSize(const UArray *self);
127 BASEKIT_API void UArray_setItemType_(UArray *self, CTYPE type);
128 BASEKIT_API CENCODING UArray_encoding(const UArray *self);
129 BASEKIT_API void UArray_setEncoding_(UArray *self, CENCODING encoding);
130 BASEKIT_API void UArray_convertToEncoding_(UArray *self, CENCODING encoding);
132 // copy
134 BASEKIT_API void UArray_copyItems_(UArray *self, const UArray *other);
135 BASEKIT_API void UArray_copy_(UArray *self, const UArray *other);
136 BASEKIT_API void UArray_copyData_(UArray *self, const UArray *other);
137 BASEKIT_API void UArray_convertToItemType_(UArray *self, CTYPE newItemType);
139 // size
141 #define UArray_minSizeWith_(self, other) self->size < other->size ? self->size : other->size
142 #define UArray_minSizeInBytesWith_(self, other) self->size * self->itemSize < other->size * other->itemSize ? self->size * self->itemSize : other->size * other->itemSize
144 BASEKIT_API void UArray_setSize_(UArray *self, size_t size);
145 BASEKIT_API size_t UArray_size(const UArray *self);
146 BASEKIT_API size_t UArray_sizeInBytes(const UArray *self);
148 BASEKIT_API void UArray_sizeTo_(UArray *self, size_t size);
150 // slice
152 BASEKIT_API UArray UArray_stackRange(const UArray *self, size_t start, size_t size);
153 BASEKIT_API UArray *UArray_range(const UArray *self, size_t start, size_t size);
154 BASEKIT_API UArray UArray_stackSlice(const UArray *self, long start, long end);
155 BASEKIT_API UArray *UArray_slice(const UArray *self, long start, long end);
157 // compare
159 BASEKIT_API int UArray_compare_(const UArray *self, const UArray *other);
160 BASEKIT_API int UArray_equals_(const UArray *self, const UArray *other);
161 BASEKIT_API int UArray_greaterThan_(const UArray *self, const UArray *other);
162 BASEKIT_API int UArray_lessThan_(const UArray *self, const UArray *other);
163 BASEKIT_API int UArray_greaterThanOrEqualTo_(const UArray *self, const UArray *other);
164 BASEKIT_API int UArray_lessThanOrEqualTo_(const UArray *self, const UArray *other);
165 BASEKIT_API int UArray_isZero(const UArray *self);
167 // contains
169 BASEKIT_API int UArray_contains_(const UArray *self, const UArray *other);
170 BASEKIT_API int UArray_containsAnyCase_(const UArray *self, const UArray *other);
172 // find
174 BASEKIT_API long UArray_find_(const UArray *self, const UArray *other);
175 BASEKIT_API long UArray_find_from_(const UArray *self, const UArray *other, size_t from);
176 BASEKIT_API long UArray_rFind_from_(const UArray *self, const UArray *other, size_t from);
177 BASEKIT_API long UArray_rFind_(const UArray *self, const UArray *other);
178 BASEKIT_API long UArray_rFindAnyCase_(const UArray *self, const UArray *other);
179 BASEKIT_API long UArray_rFindAnyValue_(const UArray *self, const UArray *other);
181 // insert
183 BASEKIT_API void UArray_at_putLong_(UArray *self, size_t pos, long v);
184 BASEKIT_API void UArray_at_putDouble_(UArray *self, size_t pos, double v);
185 BASEKIT_API void UArray_at_putPointer_(UArray *self, size_t pos, void *v);
186 BASEKIT_API void UArray_at_putAll_(UArray *self, size_t pos, const UArray *other);
188 BASEKIT_API void UArray_appendLong_(UArray *self, long v);
189 BASEKIT_API void UArray_appendDouble_(UArray *self, double v);
190 BASEKIT_API void UArray_appendPointer_(UArray *self, void *v);
192 BASEKIT_API void UArray_appendBytes_size_(UArray *self, uint8_t *bytes, size_t size);
194 // remove
196 BASEKIT_API void UArray_removeRange(UArray *self, size_t start, size_t size);
197 BASEKIT_API void UArray_removeFirst(UArray *self);
198 BASEKIT_API void UArray_removeLast(UArray *self);
200 // at
202 #define UARRAY_RAWAT_(self, i) \
203 switch (self->itemType)\
205 case CTYPE_uint8_t: return ((uint8_t *)self->data)[i];\
206 case CTYPE_uint16_t: return ((uint16_t *)self->data)[i];\
207 case CTYPE_uint32_t: return ((uint32_t *)self->data)[i];\
208 case CTYPE_uint64_t: return ((uint64_t *)self->data)[i];\
209 case CTYPE_int8_t: return ((int8_t *)self->data)[i];\
210 case CTYPE_int16_t: return ((int16_t *)self->data)[i];\
211 case CTYPE_int32_t: return ((int32_t *)self->data)[i];\
212 case CTYPE_int64_t: return ((int64_t *)self->data)[i];\
213 case CTYPE_float32_t: return ((float32_t *)self->data)[i];\
214 case CTYPE_float64_t: return ((float64_t *)self->data)[i];\
215 case CTYPE_uintptr_t: return ((uintptr_t *)self->data)[i];\
218 // at, without bounds check
220 BASEKIT_API void *UArray_rawPointerAt_(const UArray *self, size_t i);
221 BASEKIT_API long UArray_rawLongAt_(const UArray *self, size_t i);
222 BASEKIT_API double UArray_rawDoubleAt_(const UArray *self, size_t i);
224 // at, with bounds check
226 BASEKIT_API void *UArray_pointerAt_(const UArray *self, size_t i);
227 BASEKIT_API long UArray_longAt_(const UArray *self, size_t i);
228 BASEKIT_API double UArray_doubleAt_(const UArray *self, size_t i);
230 // at, extras
232 BASEKIT_API long UArray_lastLong(const UArray *self);
233 BASEKIT_API long UArray_firstLong(const UArray *self);
235 // types
237 BASEKIT_API int UArray_isFloatType(const UArray *self);
238 BASEKIT_API int UArray_isSignedType(const UArray *self);
240 BASEKIT_API size_t UArray_wrapPos_(const UArray *self, long pos);
242 // sort
244 BASEKIT_API void UArray_sort(UArray *self);
246 typedef int (UArraySortCallback)(const void *, const void *);
248 BASEKIT_API void UArray_sortBy_(UArray *self, UArraySortCallback *cmp);
250 // accessing
252 #define UARRAY_BYTEPOSAT_(self, n) (self->itemSize * n)
253 #define UARRAY_BYTESAT_(self, n) (self->data + (self->itemSize * n))
255 // macros
257 #define DUARRAY_INTOTHER(MACRO, OP, TYPE1, self, other) \
258 switch (other->itemType)\
260 case CTYPE_uint8_t: MACRO(OP, TYPE1, self, uint8_t, other); break;\
261 case CTYPE_uint16_t: MACRO(OP, TYPE1, self, uint16_t, other); break;\
262 case CTYPE_uint32_t: MACRO(OP, TYPE1, self, uint32_t, other); break;\
263 case CTYPE_int8_t: MACRO(OP, TYPE1, self, int8_t, other); break;\
264 case CTYPE_int16_t: MACRO(OP, TYPE1, self, int16_t, other); break;\
265 case CTYPE_int32_t: MACRO(OP, TYPE1, self, int32_t, other); break;\
266 case CTYPE_uintptr_t: MACRO(OP, TYPE1, self, uintptr_t, other); break;\
269 #define DUARRAY_OTHER(MACRO, OP, TYPE1, self, other) \
270 switch (other->itemType)\
272 case CTYPE_uint8_t: MACRO(OP, TYPE1, self, uint8_t, other); break;\
273 case CTYPE_uint16_t: MACRO(OP, TYPE1, self, uint16_t, other); break;\
274 case CTYPE_uint32_t: MACRO(OP, TYPE1, self, uint32_t, other); break;\
275 case CTYPE_uint64_t: MACRO(OP, TYPE1, self, uint64_t, other); break;\
276 case CTYPE_int8_t: MACRO(OP, TYPE1, self, int8_t, other); break;\
277 case CTYPE_int16_t: MACRO(OP, TYPE1, self, int16_t, other); break;\
278 case CTYPE_int32_t: MACRO(OP, TYPE1, self, int32_t, other); break;\
279 case CTYPE_int64_t: MACRO(OP, TYPE1, self, int64_t, other); break;\
280 case CTYPE_float32_t: MACRO(OP, TYPE1, self, float32_t, other); break;\
281 case CTYPE_float64_t: MACRO(OP, TYPE1, self, float64_t, other); break;\
282 case CTYPE_uintptr_t: MACRO(OP, TYPE1, self, uintptr_t, other); break;\
285 #define DUARRAY_INTSELF(MACRO, OP, self, other) \
286 switch (self->itemType)\
288 case CTYPE_uint8_t: DUARRAY_INTOTHER(MACRO, OP, uint8_t, self, other);\
289 case CTYPE_uint16_t: DUARRAY_INTOTHER(MACRO, OP, uint16_t, self, other);\
290 case CTYPE_uint32_t: DUARRAY_INTOTHER(MACRO, OP, uint32_t, self, other);\
291 case CTYPE_int8_t: DUARRAY_INTOTHER(MACRO, OP, int8_t, self, other);\
292 case CTYPE_int16_t: DUARRAY_INTOTHER(MACRO, OP, int16_t, self, other);\
293 case CTYPE_int32_t: DUARRAY_INTOTHER(MACRO, OP, uint32_t, self, other);\
296 #define DUARRAY_SELF(MACRO, OP, self, other) \
297 switch (self->itemType)\
299 case CTYPE_uint8_t: DUARRAY_OTHER(MACRO, OP, uint8_t, self, other);\
300 case CTYPE_uint16_t: DUARRAY_OTHER(MACRO, OP, uint16_t, self, other);\
301 case CTYPE_uint32_t: DUARRAY_OTHER(MACRO, OP, uint32_t, self, other);\
302 case CTYPE_uint64_t: DUARRAY_OTHER(MACRO, OP, uint64_t, self, other);\
303 case CTYPE_int8_t: DUARRAY_OTHER(MACRO, OP, int8_t, self, other);\
304 case CTYPE_int16_t: DUARRAY_OTHER(MACRO, OP, int16_t, self, other);\
305 case CTYPE_int32_t: DUARRAY_OTHER(MACRO, OP, uint32_t, self, other);\
306 case CTYPE_int64_t: DUARRAY_OTHER(MACRO, OP, uint64_t, self, other);\
307 case CTYPE_float32_t: DUARRAY_OTHER(MACRO, OP, float32_t, self, other);\
308 case CTYPE_float64_t: DUARRAY_OTHER(MACRO, OP, float64_t, self, other);\
309 case CTYPE_uintptr_t: DUARRAY_OTHER(MACRO, OP, uintptr_t, self, other);\
312 #define DUARRAY_OP(MACRO, OP, self, other)\
313 DUARRAY_SELF(MACRO, OP, self, other);\
314 UArray_unsupported_with_(self, #OP, other);
316 #define DUARRAY_INTOP(MACRO, OP, self, other)\
317 DUARRAY_INTSELF(MACRO, OP, self, other);\
318 UArray_unsupported_with_(self, #OP, other);
320 // two array primitive ops
322 #define UARRAY_BASICOP_TYPES(OP2, TYPE1, self, TYPE2, other)\
324 size_t i, minSize = self->size < other->size ? self->size : other->size;\
325 for(i = 0; i < minSize; i ++)\
327 ((TYPE1 *)self->data)[i] OP2 ((TYPE2 *)other->data)[i];\
329 return; \
332 //printf("%i: " #TYPE1 " %f " #OP2 " " #TYPE2 " %i\n", i, ((TYPE1 *)self->data)[i], ((TYPE2 *)other->data)[i]);
334 // single array ops
336 // foreach --------------------------
338 #define UARRAY_FOREACHTYPE(self, i, v, code, TYPE)\
340 size_t i;\
341 for(i = 0; i < self->size; i ++)\
343 TYPE v = ((TYPE *)self->data)[i];\
344 code;\
348 #define UARRAY_FOREACH_CASETYPE_(self, i, v, code, TYPE)\
349 case CTYPE_ ## TYPE: UARRAY_FOREACHTYPE(self, i, v, code, TYPE); break;
351 #define UARRAY_FOREACH(self, i, v, code)\
352 switch(self->itemType)\
354 UARRAY_FOREACH_CASETYPE_(self, i, v, code, uint8_t);\
355 UARRAY_FOREACH_CASETYPE_(self, i, v, code, uint16_t);\
356 UARRAY_FOREACH_CASETYPE_(self, i, v, code, uint32_t);\
357 UARRAY_FOREACH_CASETYPE_(self, i, v, code, uint64_t);\
358 UARRAY_FOREACH_CASETYPE_(self, i, v, code, int8_t);\
359 UARRAY_FOREACH_CASETYPE_(self, i, v, code, int16_t);\
360 UARRAY_FOREACH_CASETYPE_(self, i, v, code, int32_t);\
361 UARRAY_FOREACH_CASETYPE_(self, i, v, code, int64_t);\
362 UARRAY_FOREACH_CASETYPE_(self, i, v, code, float32_t);\
363 UARRAY_FOREACH_CASETYPE_(self, i, v, code, float64_t);\
364 UARRAY_FOREACH_CASETYPE_(self, i, v, code, uintptr_t);\
367 #define UARRAY_INTFOREACH(self, i, v, code)\
368 switch(self->itemType)\
370 UARRAY_FOREACH_CASETYPE_(self, i, v, code, uint8_t);\
371 UARRAY_FOREACH_CASETYPE_(self, i, v, code, uint16_t);\
372 UARRAY_FOREACH_CASETYPE_(self, i, v, code, uint32_t);\
373 UARRAY_FOREACH_CASETYPE_(self, i, v, code, uint64_t);\
374 UARRAY_FOREACH_CASETYPE_(self, i, v, code, int8_t);\
375 UARRAY_FOREACH_CASETYPE_(self, i, v, code, int16_t);\
376 UARRAY_FOREACH_CASETYPE_(self, i, v, code, int32_t);\
377 UARRAY_FOREACH_CASETYPE_(self, i, v, code, int64_t);\
378 UARRAY_FOREACH_CASETYPE_(self, i, v, code, float32_t);\
379 UARRAY_FOREACH_CASETYPE_(self, i, v, code, float64_t);\
380 UARRAY_FOREACH_CASETYPE_(self, i, v, code, uintptr_t);\
383 // rforeach --------------------------
385 #define UARRAY_RFOREACHTYPE(self, i, v, code, TYPE)\
387 long i;\
388 for(i = self->size - 1; i > -1; i --)\
390 TYPE v = ((TYPE *)self->data)[i];\
391 code;\
395 #define UARRAY_RFOREACH_CASETYPE_(self, i, v, code, TYPE)\
396 case CTYPE_ ## TYPE: UARRAY_RFOREACHTYPE(self, i, v, code, TYPE); break;
398 #define UARRAY_RFOREACH(self, i, v, code)\
399 switch(self->itemType)\
401 UARRAY_RFOREACH_CASETYPE_(self, i, v, code, uint8_t);\
402 UARRAY_RFOREACH_CASETYPE_(self, i, v, code, uint16_t);\
403 UARRAY_RFOREACH_CASETYPE_(self, i, v, code, uint32_t);\
404 UARRAY_RFOREACH_CASETYPE_(self, i, v, code, uint64_t);\
405 UARRAY_RFOREACH_CASETYPE_(self, i, v, code, int8_t);\
406 UARRAY_RFOREACH_CASETYPE_(self, i, v, code, int16_t);\
407 UARRAY_RFOREACH_CASETYPE_(self, i, v, code, int32_t);\
408 UARRAY_RFOREACH_CASETYPE_(self, i, v, code, int64_t);\
409 UARRAY_RFOREACH_CASETYPE_(self, i, v, code, float32_t);\
410 UARRAY_RFOREACH_CASETYPE_(self, i, v, code, float64_t);\
411 UARRAY_RFOREACH_CASETYPE_(self, i, v, code, uintptr_t);\
414 // foreach assign --------------------------
416 #define UARRAY_FOREACHTYPEASSIGN(self, i, v, code, TYPE)\
418 size_t i;\
419 for(i = 0; i < self->size; i ++)\
421 TYPE v = ((TYPE *)self->data)[i];\
422 ((TYPE *)self->data)[i] = code;\
426 #define UARRAY_FOREACHASSIGN(self, i, v, code)\
427 switch(self->itemType)\
429 case CTYPE_uint8_t: UARRAY_FOREACHTYPEASSIGN(self, i, v, code, uint8_t); break;\
430 case CTYPE_uint16_t: UARRAY_FOREACHTYPEASSIGN(self, i, v, code, uint16_t); break;\
431 case CTYPE_uint32_t: UARRAY_FOREACHTYPEASSIGN(self, i, v, code, uint32_t); break;\
432 case CTYPE_uint64_t: UARRAY_FOREACHTYPEASSIGN(self, i, v, code, uint64_t); break;\
433 case CTYPE_int8_t: UARRAY_FOREACHTYPEASSIGN(self, i, v, code, int8_t); break;\
434 case CTYPE_int16_t: UARRAY_FOREACHTYPEASSIGN(self, i, v, code, int16_t); break;\
435 case CTYPE_int32_t: UARRAY_FOREACHTYPEASSIGN(self, i, v, code, int32_t); break;\
436 case CTYPE_int64_t: UARRAY_FOREACHTYPEASSIGN(self, i, v, code, int64_t); break;\
437 case CTYPE_float32_t: UARRAY_FOREACHTYPEASSIGN(self, i, v, code, float32_t); break;\
438 case CTYPE_float64_t: UARRAY_FOREACHTYPEASSIGN(self, i, v, code, float64_t); break;\
441 // ----------------------------
443 #include "UArray_character.h"
444 #include "UArray_format.h"
445 #include "UArray_math.h"
446 #include "UArray_path.h"
447 #include "UArray_stream.h"
448 #include "UArray_string.h"
449 #include "UArray_utf.h"
451 #ifdef __cplusplus
453 #endif
454 #endif