Updating built in Io code to use += instead of x = x + y
[io/quag.git] / libs / basekit / source / UArray.h
blobf20a318360671c0b4321ada150d388cc0b76a307
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 typedef enum
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
43 } CTYPE;
45 typedef enum
47 CENCODING_ASCII,
48 CENCODING_UTF8,
49 CENCODING_UTF16,
50 CENCODING_UTF32,
51 CENCODING_NUMBER
52 } CENCODING;
54 typedef struct
56 uint8_t uint8;
57 uint16_t uint16;
58 uint32_t uint32;
59 uint64_t uint64;
60 int8_t int8;
61 int16_t int16;
62 int32_t int32;
63 int64_t int64;
64 float32_t float32;
65 float64_t float64;
66 uintptr_t uintptr;
67 } UArrayValueUnion;
69 #define UARRAY_DEBUG 1
71 typedef struct
73 uint8_t *data; // memory for items
74 size_t size; // number of items
75 CTYPE itemType;
76 size_t itemSize;
77 uintptr_t hash;
78 uint8_t encoding;
79 #ifdef UARRAY_DEBUG
80 int stackAllocated;
81 #endif
82 } UArray;
84 typedef UArray CharUArray;
85 typedef UArray PtrUArray;
86 typedef UArray FloatUArray;
88 BASEKIT_API const void *UArray_data(const UArray *self);
89 BASEKIT_API const uint8_t *UArray_bytes(const UArray *self);
90 BASEKIT_API uint8_t *UArray_mutableBytes(UArray *self);
91 BASEKIT_API const char *UArray_asCString(const UArray *self);
93 BASEKIT_API size_t UArray_SizeOfCtype(CTYPE type);
95 BASEKIT_API const char *CTYPE_name(CTYPE type);
96 BASEKIT_API int CTYPE_forName(const char *name);
98 BASEKIT_API const char *CENCODING_name(CENCODING encoding);
99 BASEKIT_API int CENCODING_forName(const char *name);
101 BASEKIT_API void UArray_unsupported_with_(const UArray *self, const char *methodName, const UArray *other);
102 BASEKIT_API void UArray_error_(const UArray *self, char *e);
104 BASEKIT_API UArray *UArray_new(void);
105 BASEKIT_API UArray *UArray_newWithData_type_size_copy_(void *data, CTYPE type, size_t size, int copy);
106 BASEKIT_API UArray *UArray_newWithData_type_encoding_size_copy_(void *bytes, CTYPE type, CENCODING encoding, size_t size, int copy);
107 BASEKIT_API UArray *UArray_newWithCString_copy_(char *s, int copy);
108 BASEKIT_API UArray *UArray_newWithCString_(const char *s);
109 BASEKIT_API void UArray_setCString_(UArray *self, const char *s);
110 BASEKIT_API void UArray_setData_type_size_copy_(UArray *self, void *data, CTYPE type, size_t size, int copy);
111 BASEKIT_API UArray *UArray_clone(const UArray *self);
112 BASEKIT_API void UArray_show(const UArray *self);
113 BASEKIT_API void UArray_print(const UArray *self);
115 BASEKIT_API UArray UArray_stackAllocedWithData_type_size_(void *data, CTYPE type, size_t size);
116 BASEKIT_API UArray UArray_stackAllocedWithCString_(char *s);
117 BASEKIT_API UArray UArray_stackAllocedEmptyUArray(void);
119 BASEKIT_API void UArray_stackFree(UArray *self);
120 BASEKIT_API void UArray_free(UArray *self);
122 BASEKIT_API CTYPE UArray_itemType(const UArray *self);
123 BASEKIT_API size_t UArray_itemSize(const UArray *self);
124 BASEKIT_API void UArray_setItemType_(UArray *self, CTYPE type);
125 BASEKIT_API CENCODING UArray_encoding(const UArray *self);
126 BASEKIT_API void UArray_setEncoding_(UArray *self, CENCODING encoding);
127 BASEKIT_API void UArray_convertToEncoding_(UArray *self, CENCODING encoding);
129 // copy
131 BASEKIT_API void UArray_copyItems_(UArray *self, const UArray *other);
132 BASEKIT_API void UArray_copy_(UArray *self, const UArray *other);
133 BASEKIT_API void UArray_copyData_(UArray *self, const UArray *other);
134 BASEKIT_API void UArray_convertToItemType_(UArray *self, CTYPE newItemType);
136 // size
138 #define UArray_minSizeWith_(self, other) self->size < other->size ? self->size : other->size
139 #define UArray_minSizeInBytesWith_(self, other) self->size * self->itemSize < other->size * other->itemSize ? self->size * self->itemSize : other->size * other->itemSize
141 BASEKIT_API void UArray_setSize_(UArray *self, size_t size);
142 BASEKIT_API size_t UArray_size(const UArray *self);
143 BASEKIT_API size_t UArray_sizeInBytes(const UArray *self);
145 BASEKIT_API void UArray_sizeTo_(UArray *self, size_t size);
147 // slice
149 BASEKIT_API UArray UArray_stackRange(const UArray *self, size_t start, size_t size);
150 BASEKIT_API UArray *UArray_range(const UArray *self, size_t start, size_t size);
151 BASEKIT_API UArray UArray_stackSlice(const UArray *self, long start, long end);
152 BASEKIT_API UArray *UArray_slice(const UArray *self, long start, long end);
154 // compare
156 BASEKIT_API int UArray_compare_(const UArray *self, const UArray *other);
157 BASEKIT_API int UArray_equals_(const UArray *self, const UArray *other);
158 BASEKIT_API int UArray_greaterThan_(const UArray *self, const UArray *other);
159 BASEKIT_API int UArray_lessThan_(const UArray *self, const UArray *other);
160 BASEKIT_API int UArray_greaterThanOrEqualTo_(const UArray *self, const UArray *other);
161 BASEKIT_API int UArray_lessThanOrEqualTo_(const UArray *self, const UArray *other);
162 BASEKIT_API int UArray_isZero(const UArray *self);
164 // contains
166 BASEKIT_API int UArray_contains_(const UArray *self, const UArray *other);
167 BASEKIT_API int UArray_containsAnyCase_(const UArray *self, const UArray *other);
169 // find
171 BASEKIT_API long UArray_find_(const UArray *self, const UArray *other);
172 BASEKIT_API long UArray_find_from_(const UArray *self, const UArray *other, size_t from);
173 BASEKIT_API long UArray_rFind_from_(const UArray *self, const UArray *other, size_t from);
174 BASEKIT_API long UArray_rFind_(const UArray *self, const UArray *other);
175 BASEKIT_API long UArray_rFindAnyCase_(const UArray *self, const UArray *other);
176 BASEKIT_API long UArray_rFindAnyValue_(const UArray *self, const UArray *other);
178 // insert
180 BASEKIT_API void UArray_at_putLong_(UArray *self, size_t pos, long v);
181 BASEKIT_API void UArray_at_putDouble_(UArray *self, size_t pos, double v);
182 BASEKIT_API void UArray_at_putPointer_(UArray *self, size_t pos, void *v);
183 BASEKIT_API void UArray_at_putAll_(UArray *self, size_t pos, const UArray *other);
185 BASEKIT_API void UArray_appendLong_(UArray *self, long v);
186 BASEKIT_API void UArray_appendDouble_(UArray *self, double v);
187 BASEKIT_API void UArray_appendPointer_(UArray *self, void *v);
189 BASEKIT_API void UArray_appendBytes_size_(UArray *self, uint8_t *bytes, size_t size);
191 // remove
193 BASEKIT_API void UArray_removeRange(UArray *self, size_t start, size_t size);
194 BASEKIT_API void UArray_removeFirst(UArray *self);
195 BASEKIT_API void UArray_removeLast(UArray *self);
197 // at
199 #define UARRAY_RAWAT_(self, i) \
200 switch (self->itemType)\
202 case CTYPE_uint8_t: return ((uint8_t *)self->data)[i];\
203 case CTYPE_uint16_t: return ((uint16_t *)self->data)[i];\
204 case CTYPE_uint32_t: return ((uint32_t *)self->data)[i];\
205 case CTYPE_uint64_t: return ((uint64_t *)self->data)[i];\
206 case CTYPE_int8_t: return ((int8_t *)self->data)[i];\
207 case CTYPE_int16_t: return ((int16_t *)self->data)[i];\
208 case CTYPE_int32_t: return ((int32_t *)self->data)[i];\
209 case CTYPE_int64_t: return ((int64_t *)self->data)[i];\
210 case CTYPE_float32_t: return ((float32_t *)self->data)[i];\
211 case CTYPE_float64_t: return ((float64_t *)self->data)[i];\
212 case CTYPE_uintptr_t: return ((uintptr_t *)self->data)[i];\
215 // at, without bounds check
217 BASEKIT_API void *UArray_rawPointerAt_(const UArray *self, size_t i);
218 BASEKIT_API long UArray_rawLongAt_(const UArray *self, size_t i);
219 BASEKIT_API double UArray_rawDoubleAt_(const UArray *self, size_t i);
221 // at, with bounds check
223 BASEKIT_API void *UArray_pointerAt_(const UArray *self, size_t i);
224 BASEKIT_API long UArray_longAt_(const UArray *self, size_t i);
225 BASEKIT_API double UArray_doubleAt_(const UArray *self, size_t i);
227 // at, extras
229 BASEKIT_API long UArray_lastLong(const UArray *self);
230 BASEKIT_API long UArray_firstLong(const UArray *self);
232 // types
234 BASEKIT_API int UArray_isFloatType(const UArray *self);
235 BASEKIT_API int UArray_isSignedType(const UArray *self);
237 BASEKIT_API size_t UArray_wrapPos_(const UArray *self, long pos);
239 // sort
241 BASEKIT_API void UArray_sort(UArray *self);
243 typedef int (UArraySortCallback)(const void *, const void *);
245 BASEKIT_API void UArray_sortBy_(UArray *self, UArraySortCallback *cmp);
247 // accessing
249 #define UARRAY_BYTEPOSAT_(self, n) (self->itemSize * n)
250 #define UARRAY_BYTESAT_(self, n) (self->data + (self->itemSize * n))
252 // macros
254 #define DUARRAY_INTOTHER(MACRO, OP, TYPE1, self, other) \
255 switch (other->itemType)\
257 case CTYPE_uint8_t: MACRO(OP, TYPE1, self, uint8_t, other); break;\
258 case CTYPE_uint16_t: MACRO(OP, TYPE1, self, uint16_t, other); break;\
259 case CTYPE_uint32_t: MACRO(OP, TYPE1, self, uint32_t, other); break;\
260 case CTYPE_int8_t: MACRO(OP, TYPE1, self, int8_t, other); break;\
261 case CTYPE_int16_t: MACRO(OP, TYPE1, self, int16_t, other); break;\
262 case CTYPE_int32_t: MACRO(OP, TYPE1, self, int32_t, other); break;\
263 case CTYPE_uintptr_t: MACRO(OP, TYPE1, self, uintptr_t, other); break;\
266 #define DUARRAY_OTHER(MACRO, OP, TYPE1, self, other) \
267 switch (other->itemType)\
269 case CTYPE_uint8_t: MACRO(OP, TYPE1, self, uint8_t, other); break;\
270 case CTYPE_uint16_t: MACRO(OP, TYPE1, self, uint16_t, other); break;\
271 case CTYPE_uint32_t: MACRO(OP, TYPE1, self, uint32_t, other); break;\
272 case CTYPE_uint64_t: MACRO(OP, TYPE1, self, uint64_t, other); break;\
273 case CTYPE_int8_t: MACRO(OP, TYPE1, self, int8_t, other); break;\
274 case CTYPE_int16_t: MACRO(OP, TYPE1, self, int16_t, other); break;\
275 case CTYPE_int32_t: MACRO(OP, TYPE1, self, int32_t, other); break;\
276 case CTYPE_int64_t: MACRO(OP, TYPE1, self, int64_t, other); break;\
277 case CTYPE_float32_t: MACRO(OP, TYPE1, self, float32_t, other); break;\
278 case CTYPE_float64_t: MACRO(OP, TYPE1, self, float64_t, other); break;\
279 case CTYPE_uintptr_t: MACRO(OP, TYPE1, self, uintptr_t, other); break;\
282 #define DUARRAY_INTSELF(MACRO, OP, self, other) \
283 switch (self->itemType)\
285 case CTYPE_uint8_t: DUARRAY_INTOTHER(MACRO, OP, uint8_t, self, other);\
286 case CTYPE_uint16_t: DUARRAY_INTOTHER(MACRO, OP, uint16_t, self, other);\
287 case CTYPE_uint32_t: DUARRAY_INTOTHER(MACRO, OP, uint32_t, self, other);\
288 case CTYPE_int8_t: DUARRAY_INTOTHER(MACRO, OP, int8_t, self, other);\
289 case CTYPE_int16_t: DUARRAY_INTOTHER(MACRO, OP, int16_t, self, other);\
290 case CTYPE_int32_t: DUARRAY_INTOTHER(MACRO, OP, uint32_t, self, other);\
293 #define DUARRAY_SELF(MACRO, OP, self, other) \
294 switch (self->itemType)\
296 case CTYPE_uint8_t: DUARRAY_OTHER(MACRO, OP, uint8_t, self, other);\
297 case CTYPE_uint16_t: DUARRAY_OTHER(MACRO, OP, uint16_t, self, other);\
298 case CTYPE_uint32_t: DUARRAY_OTHER(MACRO, OP, uint32_t, self, other);\
299 case CTYPE_uint64_t: DUARRAY_OTHER(MACRO, OP, uint64_t, self, other);\
300 case CTYPE_int8_t: DUARRAY_OTHER(MACRO, OP, int8_t, self, other);\
301 case CTYPE_int16_t: DUARRAY_OTHER(MACRO, OP, int16_t, self, other);\
302 case CTYPE_int32_t: DUARRAY_OTHER(MACRO, OP, uint32_t, self, other);\
303 case CTYPE_int64_t: DUARRAY_OTHER(MACRO, OP, uint64_t, self, other);\
304 case CTYPE_float32_t: DUARRAY_OTHER(MACRO, OP, float32_t, self, other);\
305 case CTYPE_float64_t: DUARRAY_OTHER(MACRO, OP, float64_t, self, other);\
306 case CTYPE_uintptr_t: DUARRAY_OTHER(MACRO, OP, uintptr_t, self, other);\
309 #define DUARRAY_OP(MACRO, OP, self, other)\
310 DUARRAY_SELF(MACRO, OP, self, other);\
311 UArray_unsupported_with_(self, #OP, other);
313 #define DUARRAY_INTOP(MACRO, OP, self, other)\
314 DUARRAY_INTSELF(MACRO, OP, self, other);\
315 UArray_unsupported_with_(self, #OP, other);
317 // two array primitive ops
319 #define UARRAY_BASICOP_TYPES(OP2, TYPE1, self, TYPE2, other)\
321 size_t i, minSize = self->size < other->size ? self->size : other->size;\
322 for(i = 0; i < minSize; i ++)\
324 ((TYPE1 *)self->data)[i] OP2 ((TYPE2 *)other->data)[i];\
326 return; \
329 //printf("%i: " #TYPE1 " %f " #OP2 " " #TYPE2 " %i\n", i, ((TYPE1 *)self->data)[i], ((TYPE2 *)other->data)[i]);
331 // single array ops
333 // foreach --------------------------
335 #define UARRAY_FOREACHTYPE(self, i, v, code, TYPE)\
337 size_t i;\
338 for(i = 0; i < self->size; i ++)\
340 TYPE v = ((TYPE *)self->data)[i];\
341 code;\
345 #define UARRAY_FOREACH_CASETYPE_(self, i, v, code, TYPE)\
346 case CTYPE_ ## TYPE: UARRAY_FOREACHTYPE(self, i, v, code, TYPE); break;
348 #define UARRAY_FOREACH(self, i, v, code)\
349 switch(self->itemType)\
351 UARRAY_FOREACH_CASETYPE_(self, i, v, code, uint8_t);\
352 UARRAY_FOREACH_CASETYPE_(self, i, v, code, uint16_t);\
353 UARRAY_FOREACH_CASETYPE_(self, i, v, code, uint32_t);\
354 UARRAY_FOREACH_CASETYPE_(self, i, v, code, uint64_t);\
355 UARRAY_FOREACH_CASETYPE_(self, i, v, code, int8_t);\
356 UARRAY_FOREACH_CASETYPE_(self, i, v, code, int16_t);\
357 UARRAY_FOREACH_CASETYPE_(self, i, v, code, int32_t);\
358 UARRAY_FOREACH_CASETYPE_(self, i, v, code, int64_t);\
359 UARRAY_FOREACH_CASETYPE_(self, i, v, code, float32_t);\
360 UARRAY_FOREACH_CASETYPE_(self, i, v, code, float64_t);\
361 UARRAY_FOREACH_CASETYPE_(self, i, v, code, uintptr_t);\
364 #define UARRAY_INTFOREACH(self, i, v, code)\
365 switch(self->itemType)\
367 UARRAY_FOREACH_CASETYPE_(self, i, v, code, uint8_t);\
368 UARRAY_FOREACH_CASETYPE_(self, i, v, code, uint16_t);\
369 UARRAY_FOREACH_CASETYPE_(self, i, v, code, uint32_t);\
370 UARRAY_FOREACH_CASETYPE_(self, i, v, code, uint64_t);\
371 UARRAY_FOREACH_CASETYPE_(self, i, v, code, int8_t);\
372 UARRAY_FOREACH_CASETYPE_(self, i, v, code, int16_t);\
373 UARRAY_FOREACH_CASETYPE_(self, i, v, code, int32_t);\
374 UARRAY_FOREACH_CASETYPE_(self, i, v, code, int64_t);\
375 UARRAY_FOREACH_CASETYPE_(self, i, v, code, float32_t);\
376 UARRAY_FOREACH_CASETYPE_(self, i, v, code, float64_t);\
377 UARRAY_FOREACH_CASETYPE_(self, i, v, code, uintptr_t);\
380 // rforeach --------------------------
382 #define UARRAY_RFOREACHTYPE(self, i, v, code, TYPE)\
384 long i;\
385 for(i = self->size - 1; i > -1; i --)\
387 TYPE v = ((TYPE *)self->data)[i];\
388 code;\
392 #define UARRAY_RFOREACH_CASETYPE_(self, i, v, code, TYPE)\
393 case CTYPE_ ## TYPE: UARRAY_RFOREACHTYPE(self, i, v, code, TYPE); break;
395 #define UARRAY_RFOREACH(self, i, v, code)\
396 switch(self->itemType)\
398 UARRAY_RFOREACH_CASETYPE_(self, i, v, code, uint8_t);\
399 UARRAY_RFOREACH_CASETYPE_(self, i, v, code, uint16_t);\
400 UARRAY_RFOREACH_CASETYPE_(self, i, v, code, uint32_t);\
401 UARRAY_RFOREACH_CASETYPE_(self, i, v, code, uint64_t);\
402 UARRAY_RFOREACH_CASETYPE_(self, i, v, code, int8_t);\
403 UARRAY_RFOREACH_CASETYPE_(self, i, v, code, int16_t);\
404 UARRAY_RFOREACH_CASETYPE_(self, i, v, code, int32_t);\
405 UARRAY_RFOREACH_CASETYPE_(self, i, v, code, int64_t);\
406 UARRAY_RFOREACH_CASETYPE_(self, i, v, code, float32_t);\
407 UARRAY_RFOREACH_CASETYPE_(self, i, v, code, float64_t);\
408 UARRAY_RFOREACH_CASETYPE_(self, i, v, code, uintptr_t);\
411 // foreach assign --------------------------
413 #define UARRAY_FOREACHTYPEASSIGN(self, i, v, code, TYPE)\
415 size_t i;\
416 for(i = 0; i < self->size; i ++)\
418 TYPE v = ((TYPE *)self->data)[i];\
419 ((TYPE *)self->data)[i] = code;\
423 #define UARRAY_FOREACHASSIGN(self, i, v, code)\
424 switch(self->itemType)\
426 case CTYPE_uint8_t: UARRAY_FOREACHTYPEASSIGN(self, i, v, code, uint8_t); break;\
427 case CTYPE_uint16_t: UARRAY_FOREACHTYPEASSIGN(self, i, v, code, uint16_t); break;\
428 case CTYPE_uint32_t: UARRAY_FOREACHTYPEASSIGN(self, i, v, code, uint32_t); break;\
429 case CTYPE_uint64_t: UARRAY_FOREACHTYPEASSIGN(self, i, v, code, uint64_t); break;\
430 case CTYPE_int8_t: UARRAY_FOREACHTYPEASSIGN(self, i, v, code, int8_t); break;\
431 case CTYPE_int16_t: UARRAY_FOREACHTYPEASSIGN(self, i, v, code, int16_t); break;\
432 case CTYPE_int32_t: UARRAY_FOREACHTYPEASSIGN(self, i, v, code, int32_t); break;\
433 case CTYPE_int64_t: UARRAY_FOREACHTYPEASSIGN(self, i, v, code, int64_t); break;\
434 case CTYPE_float32_t: UARRAY_FOREACHTYPEASSIGN(self, i, v, code, float32_t); break;\
435 case CTYPE_float64_t: UARRAY_FOREACHTYPEASSIGN(self, i, v, code, float64_t); break;\
438 // ----------------------------
440 #include "UArray_character.h"
441 #include "UArray_format.h"
442 #include "UArray_math.h"
443 #include "UArray_path.h"
444 #include "UArray_stream.h"
445 #include "UArray_string.h"
446 #include "UArray_utf.h"
448 #ifdef __cplusplus
450 #endif
451 #endif