Sample: cleaning up Inheritance
[io/quag.git] / libs / basekit / source / UArray.c
blob84c316ce101c089b4073fe18ce80c7f796d1554d
1 /*
2 copyright: Steve Dekorte, 2006. All rights reserved.
3 license: See _BSDLicense.txt.
4 */
6 #include "Base.h"
8 #define UArray_C
9 #include "UArray.h"
10 #undef UArray_C
12 #include <string.h>
13 #include <ctype.h>
14 #include <stdlib.h>
15 #include <limits.h>
17 size_t CTYPE_size(CTYPE type)
19 switch (type)
21 case CTYPE_uint8_t: return sizeof(uint8_t);
22 case CTYPE_uint16_t: return sizeof(uint16_t);
23 case CTYPE_uint32_t: return sizeof(uint32_t);
24 case CTYPE_uint64_t: return sizeof(uint64_t);
26 case CTYPE_int8_t: return sizeof(int8_t);
27 case CTYPE_int16_t: return sizeof(int16_t);
28 case CTYPE_int32_t: return sizeof(int32_t);
29 case CTYPE_int64_t: return sizeof(int64_t);
31 case CTYPE_float32_t: return sizeof(float32_t);
32 case CTYPE_float64_t: return sizeof(float64_t);
34 case CTYPE_uintptr_t: return sizeof(uintptr_t);
36 return 0;
39 const char *CTYPE_name(CTYPE type)
41 switch (type)
43 case CTYPE_uint8_t: return "uint8";
44 case CTYPE_uint16_t: return "uint16";
45 case CTYPE_uint32_t: return "uint32";
46 case CTYPE_uint64_t: return "uint64";
48 case CTYPE_int8_t: return "int8";
49 case CTYPE_int16_t: return "int16";
50 case CTYPE_int32_t: return "int32";
51 case CTYPE_int64_t: return "int64";
53 case CTYPE_float32_t: return "float32";
54 case CTYPE_float64_t: return "float64";
56 case CTYPE_uintptr_t: return "intptr";
58 return "unknown";
61 int CTYPE_forName(const char *name)
63 if(!strcmp(name, "uint8")) return CTYPE_uint8_t;
64 if(!strcmp(name, "uint16")) return CTYPE_uint16_t;
65 if(!strcmp(name, "uint32")) return CTYPE_uint32_t;
66 if(!strcmp(name, "uint64")) return CTYPE_uint64_t;
67 if(!strcmp(name, "int8")) return CTYPE_int8_t;
68 if(!strcmp(name, "int16")) return CTYPE_int16_t;
69 if(!strcmp(name, "int32")) return CTYPE_int32_t;
70 if(!strcmp(name, "int64")) return CTYPE_int64_t;
71 if(!strcmp(name, "float32")) return CTYPE_float32_t;
72 if(!strcmp(name, "float64")) return CTYPE_float64_t;
73 return -1;
76 int CENCODING_forName(const char *name)
78 if(!strcmp(name, "ascii")) return CENCODING_ASCII;
79 if(!strcmp(name, "utf8")) return CENCODING_UTF8;
80 if(!strcmp(name, "utf16")) return CENCODING_UTF16;
81 if(!strcmp(name, "utf32")) return CENCODING_UTF32;
82 if(!strcmp(name, "number")) return CENCODING_NUMBER;
83 return -1;
86 const char *CENCODING_name(CENCODING encoding)
88 switch (encoding)
90 case CENCODING_ASCII: return "ascii";
91 case CENCODING_UTF8: return "utf8";
92 case CENCODING_UTF16: return "utf16";
93 case CENCODING_UTF32: return "utf32";
94 case CENCODING_NUMBER: return "number";
96 return "unknown";
99 // error
101 void UArray_unsupported_with_(const UArray *self, const char *methodName, const UArray *other)
103 //UArray_error_(self, "Error: '%s' not supported between '%s' and '%s'\n");
104 printf("Error: '%s' not supported between '%s' and '%s'\n",
105 methodName, CTYPE_name(self->itemType), CTYPE_name(other->itemType));
106 exit(-1);
109 void UArray_error_(const UArray *self, char *e)
111 printf("%s\n", e);
112 exit(-1);
115 // new
117 CTYPE UArray_itemType(const UArray *self)
119 return self->itemType;
122 size_t UArray_itemSize(const UArray *self)
124 return self->itemSize;
127 inline size_t UArray_sizeRequiredToContain_(const UArray *self, const UArray *other)
129 return (UArray_sizeInBytes(other) + self->itemSize - 1) / self->itemSize;
132 void UArray_rawSetItemType_(UArray *self, CTYPE type)
134 size_t itemSize = CTYPE_size(type);
135 self->itemType = type;
136 self->itemSize = itemSize;
139 void UArray_setItemType_(UArray *self, CTYPE type)
141 size_t itemSize = CTYPE_size(type);
142 div_t q = div(UArray_sizeInBytes(self), itemSize);
144 if (q.rem != 0)
146 q.quot += 1;
147 UArray_setSize_(self, (q.quot * itemSize) / self->itemSize);
150 self->itemType = type;
152 self->itemSize = itemSize;
153 self->size = q.quot;
155 if (UArray_isFloatType(self))
157 self->encoding = CENCODING_NUMBER;
161 CENCODING UArray_encoding(const UArray *self)
163 return self->encoding;
166 void UArray_setEncoding_(UArray *self, CENCODING encoding)
168 // ensure that size matches new encoding
170 switch(encoding)
172 case CENCODING_ASCII:
173 case CENCODING_UTF8:
174 UArray_setItemType_(self, CTYPE_uint8_t);
175 break;
176 case CENCODING_UTF16:
177 UArray_setItemType_(self, CTYPE_uint16_t);
178 break;
179 case CENCODING_UTF32:
180 UArray_setItemType_(self, CTYPE_uint32_t);
181 break;
182 case CENCODING_NUMBER:
183 // Don't change itemType when setting raw encoding. Raw encoding
184 // used for vectors and numbers and the item type may have been set
185 // before this call.
186 break;
189 self->encoding = encoding;
192 void UArray_convertToEncoding_(UArray *self, CENCODING encoding)
194 switch(encoding)
196 case CENCODING_ASCII:
197 case CENCODING_UTF8:
198 UArray_convertToUTF8(self);
199 break;
200 case CENCODING_UTF16:
201 UArray_convertToUTF16(self);
202 break;
203 case CENCODING_UTF32:
204 UArray_convertToUTF32(self);
205 break;
206 case CENCODING_NUMBER:
207 UArray_setItemType_(self, CTYPE_uint8_t);
208 break;
211 self->encoding = encoding;
212 UArray_changed(self);
215 UArray *UArray_newWithData_type_size_copy_(void *bytes, CTYPE type, size_t size, int copy)
217 UArray *self = (UArray *)io_calloc(1, sizeof(UArray));
218 UArray_setData_type_size_copy_(self, bytes, type, size, copy);
219 self->encoding = CENCODING_ASCII;
220 return self;
223 UArray *UArray_new(void)
225 return UArray_newWithData_type_size_copy_("", CTYPE_uint8_t, 0, 1);
228 UArray *UArray_clone(const UArray *self)
230 UArray *out = UArray_new();
231 UArray_copy_(out, self);
232 return out;
235 void UArray_show(const UArray *self)
237 printf("UArray_%p %s\t", (void *)self, CTYPE_name(self->itemType));
238 printf("size: %i ", self->size);
239 printf("itemSize: %i ", self->itemSize);
240 printf("data: ");
241 UArray_print(self);
242 printf("\n");
245 void UArray_print(const UArray *self)
247 if(self->encoding == CENCODING_ASCII || self->encoding == CENCODING_UTF8)
249 printf("%s", (char *)self->data);
251 else if(self->encoding != CENCODING_NUMBER)
253 UARRAY_FOREACH(self, i, v, printf("%c", (int)v); );
255 else if(UArray_isFloatType(self))
257 printf("[");
258 UARRAY_FOREACH(self, i, v,
259 printf("%f", (float)v);
260 if(i != self->size - 1) printf(", ");
262 printf("]");
264 else
266 printf("[");
267 UARRAY_FOREACH(self, i, v,
268 printf("%i", (int)v);
269 if(i != self->size - 1) printf(", ");
271 printf("]");
275 UArray UArray_stackAllocedWithData_type_size_(void *data, CTYPE type, size_t size)
277 UArray self;
278 memset(&self, 0, sizeof(UArray));
280 #ifdef UARRAY_DEBUG
281 self.stackAllocated = 1;
282 #endif
284 self.itemType = type;
285 self.itemSize = CTYPE_size(type);
286 self.size = size;
287 self.data = data;
288 return self;
291 BASEKIT_API UArray UArray_stackAllocedEmptyUArray(void)
293 UArray self;
294 memset(&self, 0, sizeof(UArray));
296 #ifdef UARRAY_DEBUG
297 self.stackAllocated = 1;
298 #endif
300 self.itemType = CTYPE_int32_t;
301 self.itemSize = 4;
302 self.size = 0;
303 self.data = 0x0;
304 return self;
307 UArray *UArray_newWithCString_copy_(char *s, int copy)
309 return UArray_newWithData_type_size_copy_(s, CTYPE_uint8_t, strlen(s), copy);
312 UArray *UArray_newWithCString_(const char *s)
314 return UArray_newWithData_type_size_copy_((uint8_t *)s, CTYPE_uint8_t, strlen(s), 1);
317 void UArray_empty(UArray *self)
319 UArray_setSize_(self, 0);
322 void UArray_setCString_(UArray *self, const char *s)
324 UArray_empty(self);
325 UArray_setItemType_(self, CTYPE_uint8_t);
326 UArray_appendCString_(self, s);
329 #ifdef UARRAY_DEBUG
330 void UArray_checkIfOkToRelloc(UArray *self)
332 if(self->stackAllocated)
334 printf("UArray debug error: attempt to io_realloc UArray data that this UArray does not own");
335 exit(-1);
338 #endif
340 void UArray_setData_type_size_copy_(UArray *self, void *data, CTYPE type, size_t size, int copy)
342 size_t sizeInBytes;
344 UArray_rawSetItemType_(self, type);
345 self->size = size;
347 sizeInBytes = self->size * self->itemSize;
349 #ifdef UARRAY_DEBUG
350 UArray_checkIfOkToRelloc(self);
351 #endif
353 if (copy)
355 self->data = io_realloc(self->data, sizeInBytes + 1);
356 memmove(self->data, data, sizeInBytes);
357 self->data[sizeInBytes] = 0x0;
359 else
361 if(self->data) free(self->data);
362 self->data = data;
367 UArray UArray_stackAllocedWithCString_(char *s)
369 return UArray_stackAllocedWithData_type_size_(s, CTYPE_uint8_t, strlen(s));
372 const void *UArray_data(const UArray *self)
374 return self->data;
377 const uint8_t *UArray_bytes(const UArray *self)
379 return self->data;
382 uint8_t *UArray_mutableBytes(UArray *self)
384 UArray_changed(self);
385 return self->data;
388 const char *UArray_asCString(const UArray *self)
390 return (const char *)(self->data);
393 void UArray_stackFree(UArray *self)
395 if(self->data) io_free(self->data);
398 void UArray_free(UArray *self)
400 if(self->data) io_free(self->data);
401 io_free(self);
404 // size
406 void UArray_setSize_(UArray *self, size_t size)
408 if (size != self->size)
410 size_t oldSizeInBytes = UArray_sizeInBytes(self);
411 size_t newSizeInBytes = self->itemSize * size;
413 #ifdef UARRAY_DEBUG
414 UArray_checkIfOkToRelloc(self);
415 #endif
416 self->data = io_realloc(self->data, newSizeInBytes + 1);
419 self->data[newSizeInBytes] = 0x0;
420 self->size = size;
422 if (newSizeInBytes > oldSizeInBytes)
424 memset(self->data + oldSizeInBytes, 0, newSizeInBytes - oldSizeInBytes);
427 UArray_changed(self);
431 size_t UArray_size(const UArray *self)
433 return self->size;
436 size_t UArray_sizeInBytes(const UArray *self)
438 return self->size * self->itemSize;
441 void UArray_sizeTo_(UArray *self, size_t size)
443 UArray_setSize_(self, size);
447 // copy
449 void UArray_copy_(UArray *self, const UArray *other)
451 UArray_setItemType_(self, UArray_itemType(other));
452 UArray_setEncoding_(self, UArray_encoding(other));
453 UArray_setSize_(self, UArray_size(other));
454 UArray_copyItems_(self, other);
457 void UArray_copyItems_(UArray *self, const UArray *other)
459 if(self->size != other->size)
461 printf("UArray_copyItems_ error - arrays not of same size\n");
462 exit(-1);
465 if(self->itemType == other->itemType)
467 UArray_copyData_(self, other);
469 else
471 DUARRAY_OP(UARRAY_BASICOP_TYPES, =, self, other);
473 UArray_changed(self);
476 void UArray_copyData_(UArray *self, const UArray *other)
478 UArray_setSize_(self, UArray_sizeRequiredToContain_(self, other));
479 memmove(self->data, other->data, UArray_sizeInBytes(other));
482 void UArray_convertToItemType_(UArray *self, CTYPE newItemType)
484 if (self->itemType != newItemType)
486 UArray *tmp = UArray_new();
487 UArray_setItemType_(tmp, newItemType);
488 UArray_setEncoding_(tmp, UArray_encoding(self));
489 UArray_setSize_(tmp, self->size);
490 UArray_copyItems_(tmp, self);
491 UArray_copy_(self, tmp);
492 UArray_free(tmp);
493 UArray_changed(self);
497 // slice
499 UArray UArray_stackRange(const UArray *self, size_t start, size_t size)
501 UArray s;
503 memcpy(&s, self, sizeof(UArray));
504 s.hash = 0;
506 #ifdef UARRAY_DEBUG
507 s.stackAllocated = 1;
508 #endif
510 if(start < self->size || start == 0)
512 s.data = self->data + self->itemSize * start;
514 else
516 s.data = 0x0;
519 if(start + size <= self->size)
521 s.size = size;
523 else
525 s.size = 0;
528 return s;
531 UArray *UArray_range(const UArray *self, size_t start, size_t size)
533 UArray out = UArray_stackRange(self, start, size);
534 return UArray_clone(&out);
537 UArray UArray_stackSlice(const UArray *self, long start, long end)
539 start = UArray_wrapPos_(self, start);
540 end = UArray_wrapPos_(self, end);
541 if (end < start) end = start;
542 return UArray_stackRange(self, start, end - start);
545 BASEKIT_API UArray *UArray_slice(const UArray *self, long start, long end)
547 UArray out = UArray_stackSlice(self, start, end);
548 return UArray_clone(&out);
551 // at, without bounds check
553 void *UArray_rawPointerAt_(const UArray *self, size_t i)
555 if (self->itemType == CTYPE_uintptr_t)
557 return ((void **)self->data)[i];
560 UArray_error_(self, "UArray_rawPointerAt_ not supported on this type");
561 return NULL;
564 long UArray_rawLongAt_(const UArray *self, size_t i)
566 UARRAY_RAWAT_(self, i);
567 UArray_error_(self, "UArray_rawLongAt_ not supported on this type");
568 return 0;
571 double UArray_rawDoubleAt_(const UArray *self, size_t i)
573 UARRAY_RAWAT_(self, i);
574 UArray_error_(self, "UArray_doubleAt_ not supported on this type");
575 return 0;
578 // at, with bounds check
580 void *UArray_pointerAt_(const UArray *self, size_t i)
582 if (i >= self->size) { return NULL; }
583 return UArray_rawPointerAt_(self, i);
586 long UArray_longAt_(const UArray *self, size_t i)
588 if (i >= self->size) { return 0; }
589 return UArray_rawLongAt_(self, i);
592 double UArray_doubleAt_(const UArray *self, size_t i)
594 if (i >= self->size) { return 0.0; }
595 return UArray_rawDoubleAt_(self, i);
598 // at, extras
600 long UArray_firstLong(const UArray *self)
602 return UArray_rawLongAt_(self, 0);
605 long UArray_lastLong(const UArray *self)
607 if (!self->size)
609 return 0;
612 return UArray_rawLongAt_(self, self->size - 1);
615 // remove
617 void UArray_removeRange(UArray *self, size_t start, size_t removeSize)
619 if (start < self->size)
621 if (start + removeSize > self->size)
623 removeSize = self->size - start;
625 else if (start + removeSize < self->size)
627 // need to copy end
628 size_t remainder = start + removeSize;
629 size_t remainderSize = self->size - remainder;
630 memmove(UARRAY_BYTESAT_(self, start), UARRAY_BYTESAT_(self, remainder), remainderSize);
633 UArray_setSize_(self, self->size - removeSize);
635 UArray_changed(self);
638 BASEKIT_API void UArray_removeFirst(UArray *self)
640 UArray_removeRange(self, 0, 1);
643 BASEKIT_API void UArray_removeLast(UArray *self)
645 if (self->size > 0)
647 UArray_setSize_(self, self->size - 1);
651 // insert
653 #define UARRAY_RAWAT_PUT_(self, pos, v) \
654 switch (self->itemType)\
656 case CTYPE_uint8_t: ((uint8_t *)self->data)[pos] = v; return;\
657 case CTYPE_uint16_t: ((uint16_t *)self->data)[pos] = v; return;\
658 case CTYPE_uint32_t: ((uint32_t *)self->data)[pos] = v; return;\
659 case CTYPE_uint64_t: ((uint64_t *)self->data)[pos] = v; return;\
660 case CTYPE_int8_t: ((int8_t *)self->data)[pos] = v; return;\
661 case CTYPE_int16_t: ((int16_t *)self->data)[pos] = v; return;\
662 case CTYPE_int32_t: ((int32_t *)self->data)[pos] = v; return;\
663 case CTYPE_int64_t: ((int64_t *)self->data)[pos] = v; return;\
664 case CTYPE_float32_t: ((float32_t *)self->data)[pos] = v; return;\
665 case CTYPE_float64_t: ((float64_t *)self->data)[pos] = v; return;\
666 case CTYPE_uintptr_t: ((uintptr_t *)self->data)[pos] = v; return;\
669 void UArray_at_putLong_(UArray *self, size_t pos, long v)
671 if(pos >= self->size) UArray_setSize_(self, pos + 1);
673 //if(UArray_longAt_(self, pos) != v)
675 UARRAY_RAWAT_PUT_(self, pos, v);
676 UArray_changed(self);
680 void UArray_at_putDouble_(UArray *self, size_t pos, double v)
682 if(pos >= self->size) UArray_setSize_(self, pos + 1);
684 //if(UArray_doubleAt_(self, pos) != v)
686 UARRAY_RAWAT_PUT_(self, pos, v);
687 UArray_changed(self);
691 void UArray_at_putPointer_(UArray *self, size_t pos, void *v)
693 if (pos >= self->size) UArray_setSize_(self, pos + 1);
695 switch (self->itemType)
697 case CTYPE_uintptr_t:
698 if(((void **)self->data)[pos] != v)
700 ((void **)self->data)[pos] = v;
701 UArray_changed(self);
703 return;
706 UArray_error_(self, "UArray_at_putPointer_ not supported with this type");
709 void UArray_appendLong_(UArray *self, long v)
711 UArray_at_putLong_(self, self->size, v);
714 void UArray_appendDouble_(UArray *self, double v)
716 UArray_at_putDouble_(self, self->size, v);
719 void UArray_appendPointer_(UArray *self, void *v)
721 UArray_at_putPointer_(self, self->size, v);
724 void UArray_appendBytes_size_(UArray *self, uint8_t *bytes, size_t size)
726 UArray a = UArray_stackAllocedWithData_type_size_(bytes, CTYPE_uint8_t, size);
727 UArray_append_(self, &a);
730 void UArray_at_putAll_(UArray *self, size_t pos, const UArray *other)
732 if (other->size == 0) return;
734 if (pos > self->size)
736 UArray_setSize_(self, pos);
740 size_t chunkSize = self->size - pos;
741 size_t originalSelfSize = self->size;
743 UArray_setSize_(self, self->size + other->size);
746 UArray oldChunk = UArray_stackRange(self, pos, chunkSize);
747 UArray newChunk = UArray_stackRange(self, pos + other->size, chunkSize);
748 UArray insertChunk = UArray_stackRange(self, pos, other->size);
750 if (
751 //(&newChunk)->data == 0x0 ||
752 (&insertChunk)->data == 0x0)
754 printf("oldChunk.data %p size %i\n", (void *)(&oldChunk)->data, oldChunk.size);
755 printf("newChunk.data %p size %i\n", (void *)(&newChunk)->data, newChunk.size);
756 printf("insertChunk.data %p size %i\n", (void *)(&insertChunk)->data, insertChunk.size);
757 printf("originalSelfSize = %i\n", originalSelfSize);
758 printf("self->size = %i\n", self->size);
759 printf("other->size = %i\n", other->size);
760 printf("pos = %i\n", pos);
761 //exit(-1);
763 oldChunk = UArray_stackRange(self, pos, chunkSize);
764 newChunk = UArray_stackRange(self, pos + other->size, chunkSize);
765 insertChunk = UArray_stackRange(self, pos, other->size);
766 return;
769 if (newChunk.size) //UArray_copy_(&newChunk, &oldChunk); // copy chunk to end
770 UArray_copyItems_(&newChunk, &oldChunk);
771 //UArray_copy_(&insertChunk, other); // insert other
772 UArray_copyItems_(&insertChunk, other);
775 UArray_changed(self);
779 // compare
781 #define UARRAY_COMPARE_TYPES(OP2, TYPE1, self, TYPE2, other)\
783 size_t i, minSize = self->size < other->size ? self->size : other->size;\
784 for(i = 0; i < minSize; i ++)\
786 TYPE1 v1 = ((TYPE1 *)self->data)[i];\
787 TYPE2 v2 = ((TYPE2 *)other->data)[i];\
788 if (v1 > v2) return 1;\
789 if (v1 < v2) return -1;\
791 if(self->size != other->size)\
793 return self->size < other->size ? -1 : 1;\
795 return 0;\
798 #define UARRAY_EQ_TYPES(OP2, TYPE1, self, TYPE2, other)\
800 size_t i, minSize = self->size < other->size ? self->size : other->size;\
801 for(i = 0; i < minSize; i ++)\
803 TYPE1 v1 = ((TYPE1 *)self->data)[i];\
804 TYPE2 v2 = ((TYPE2 *)other->data)[i];\
805 if (v1 != v2) return 0;\
807 return 1;\
810 #define UARRAY_GT_TYPES(OP2, TYPE1, self, TYPE2, other)\
812 size_t i, minSize = self->size < other->size ? self->size : other->size;\
813 for(i = 0; i < minSize; i ++)\
815 TYPE1 v1 = ((TYPE1 *)self->data)[i];\
816 TYPE2 v2 = ((TYPE2 *)other->data)[i];\
817 if (v1 < v2) return 0;\
819 return 1;\
822 #define UARRAY_LT_TYPES(OP2, TYPE1, self, TYPE2, other)\
824 size_t i, minSize = self->size < other->size ? self->size : other->size;\
825 for(i = 0; i < minSize; i ++)\
827 TYPE1 v1 = ((TYPE1 *)self->data)[i];\
828 TYPE2 v2 = ((TYPE2 *)other->data)[i];\
829 if (v1 > v2) return 0;\
831 return 1;\
834 int UArray_compare_(const UArray *self, const UArray *other)
836 DUARRAY_OP(UARRAY_COMPARE_TYPES, NULL, self, other);
837 return 0;
840 int UArray_equals_(const UArray *self, const UArray *other)
842 if (self->size != other->size) return 0;
843 DUARRAY_OP(UARRAY_EQ_TYPES, NULL, self, other);
844 return 0;
847 int UArray_greaterThan_(const UArray *self, const UArray *other)
849 if(self->encoding == CENCODING_NUMBER)
850 { DUARRAY_OP(UARRAY_GT_TYPES, NULL, self, other); }
852 return UArray_compare_(self, other) > 0;
855 int UArray_lessThan_(const UArray *self, const UArray *other)
857 if(self->encoding == CENCODING_NUMBER)
858 { DUARRAY_OP(UARRAY_LT_TYPES, NULL, self, other); }
860 return UArray_compare_(self, other) < 0;
863 int UArray_greaterThanOrEqualTo_(const UArray *self, const UArray *other)
865 if(self->encoding == CENCODING_NUMBER)
867 if (UArray_greaterThan_(self, other) | UArray_equals_(self, other))
868 { return 1; } else { return 0; }
871 return UArray_compare_(self, other) >= 0;
874 int UArray_lessThanOrEqualTo_(const UArray *self, const UArray *other)
876 if(self->encoding == CENCODING_NUMBER)
878 if (UArray_lessThan_(self, other) | UArray_equals_(self, other))
879 { return 1; } else { return 0; }
882 return UArray_compare_(self, other) <= 0;
885 int UArray_isZero(const UArray *self)
887 UARRAY_FOREACH(self, i, v, if (v) return 0;)
888 return 1;
891 // find
893 // printf("i %i %c j %i %c\n", i, v1, j, v2);\
894 // printf("j%i == %i\n", i, other->size);\
896 #define UARRAY_FIND_TYPES(OP2, TYPE1, self, TYPE2, other)\
898 size_t i;\
899 if(self->size < other->size || self->size == 0) return -1;\
900 for(i = 0; i < self->size - other->size + 1; i ++)\
902 size_t j;\
903 int match = 1;\
904 for(j = 0; j < other->size; j ++)\
906 TYPE1 v1 = ((TYPE1 *)self->data)[i + j];\
907 TYPE2 v2 = ((TYPE2 *)other->data)[j];\
908 if (v1 != v2) { match = 0; break; }\
910 if (match) return i;\
912 return -1;\
915 long UArray_find_(const UArray *self, const UArray *other)
917 DUARRAY_OP(UARRAY_FIND_TYPES, NULL, self, other);
918 return -1;
921 int UArray_contains_(const UArray *self, const UArray *other)
923 return UArray_find_(self, other) != -1;
926 long UArray_find_from_(const UArray *self, const UArray *other, size_t from)
928 UArray s = UArray_stackRange(self, from, self->size - from);
929 long i = UArray_find_(&s, other);
931 return i == -1 ? -1 : from + i;
934 #define UARRAY_FINDANYCASE_TYPES(OP2, TYPE1, self, TYPE2, other)\
936 size_t i;\
937 if(self->size < other->size) return -1;\
938 for(i = 0; i < self->size - other->size + 1; i ++)\
940 size_t j;\
941 int match = 1;\
942 for(j = 0; j < other->size; j ++)\
944 TYPE1 v1 = ((TYPE1 *)self->data)[i + j];\
945 TYPE2 v2 = ((TYPE2 *)other->data)[j];\
946 if (tolower((int)v1) != tolower((int)v2)) { match = 0; break; }\
948 if(match) { return i; }\
950 return -1;\
953 long UArray_findAnyCase_(const UArray *self, const UArray *other)
955 DUARRAY_OP(UARRAY_FINDANYCASE_TYPES, NULL, self, other);
956 return -1;
959 int UArray_containsAnyCase_(const UArray *self, const UArray *other)
961 long i = UArray_findAnyCase_(self, other);
962 return i != -1;
965 long UArray_findLongValue_(const UArray *self, long value)
967 UARRAY_FOREACH(self, i, v, if(v == value) return i);
968 return -1;
971 int UArray_containsLong_(const UArray *self, long value)
973 return UArray_findLongValue_(self, value) != -1;
976 long UArray_findDoubleValue_(const UArray *self, double value)
978 UARRAY_FOREACH(self, i, v, if(v == value) return i);
979 return -1;
982 int UArray_containsDouble_(const UArray *self, double value)
984 return UArray_findDoubleValue_(self, value) != -1;
987 #define UARRAY_RFIND_TYPES(OP2, TYPE1, self, TYPE2, other)\
989 long i, j;\
990 if(self->size < other->size) return -1;\
991 for(i = self->size - other->size + 1; i > -1; i --)\
993 int match = 1;\
994 for(j = 0; j < other->size; j ++)\
996 TYPE1 v1 = ((TYPE1 *)self->data)[i+j];\
997 TYPE2 v2 = ((TYPE2 *)other->data)[j];\
998 if (v1 != v2) { match = 0; break; }\
1000 if(match) { return i;}\
1002 return -1;\
1005 long UArray_rFind_(const UArray *self, const UArray *other)
1007 DUARRAY_OP(UARRAY_RFIND_TYPES, NULL, self, other);
1008 return -1;
1011 BASEKIT_API long UArray_rFind_from_(const UArray *self, const UArray *other, size_t from)
1013 UArray s = UArray_stackRange(self, 0, from);
1014 long i = UArray_rFind_(&s, other);
1015 return i;
1018 #define UARRAY_RFINDANYCASE_TYPES(OP2, TYPE1, self, TYPE2, other)\
1020 long i, j;\
1021 if(self->size < other->size) return -1;\
1022 for(i = self->size - other->size + 1; i > -1; i --)\
1024 int match = 1;\
1025 for(j = 0; j < other->size; j ++)\
1027 int v1 = ((TYPE1 *)self->data)[i+j];\
1028 int v2 = ((TYPE2 *)other->data)[j];\
1029 if (tolower(v1) != tolower(v2)) { match = 0; break; }\
1031 if(match) return i;\
1033 return -1;\
1036 long UArray_rFindAnyCase_(const UArray *self, const UArray *other)
1038 DUARRAY_OP(UARRAY_RFINDANYCASE_TYPES, NULL, self, other);
1039 return -1;
1042 #define UARRAY_RFINDANYVALUE_TYPES(OP2, TYPE1, self, TYPE2, other)\
1044 long i, j;\
1045 if(self->size < other->size) return -1;\
1046 for(i = self->size - 1; i > -1; i --)\
1048 TYPE1 v1 = ((TYPE1 *)self->data)[i];\
1049 for(j = 0; j < other->size; j ++)\
1051 TYPE2 v2 = ((TYPE2 *)other->data)[j];\
1052 if (v1 == v2) { return i; }\
1055 return -1;\
1058 long UArray_rFindAnyValue_(const UArray *self, const UArray *other)
1060 DUARRAY_OP(UARRAY_RFINDANYVALUE_TYPES, NULL, self, other);
1061 return -1;
1064 // types
1066 int UArray_isFloatType(const UArray *self)
1068 return self->itemType == CTYPE_float32_t || self->itemType == CTYPE_float64_t;
1071 int UArray_isSignedType(const UArray *self)
1073 switch (self->itemType)
1075 case CTYPE_uint8_t: return 0;
1076 case CTYPE_uint16_t: return 0;
1077 case CTYPE_uint32_t: return 0;
1078 case CTYPE_uint64_t: return 0;
1079 case CTYPE_int8_t: return 1;
1080 case CTYPE_int16_t: return 1;
1081 case CTYPE_int32_t: return 1;
1082 case CTYPE_int64_t: return 1;
1083 case CTYPE_float32_t: return 1;
1084 case CTYPE_float64_t: return 1;
1086 return 0;
1089 size_t UArray_wrapPos_(const UArray *self, long pos)
1091 long size = self->size;
1093 if (pos > size - 1)
1095 return size;
1098 if (pos < 0)
1100 pos = size + pos;
1102 if (pos < 0)
1104 pos = 0;
1108 return pos;
1111 int cmp_uint8_t(const uint8_t *a, const uint8_t *b) { return *a == *b ? 0 : (*a < *b ? -1 : 1); }
1112 int cmp_uint16_t(const uint16_t *a, const uint16_t *b) { return *a == *b ? 0 : (*a < *b ? -1 : 1); }
1113 int cmp_uint32_t(const uint32_t *a, const uint32_t *b) { return *a == *b ? 0 : (*a < *b ? -1 : 1); }
1114 int cmp_uint64_t(const uint64_t *a, const uint64_t *b) { return *a == *b ? 0 : (*a < *b ? -1 : 1); }
1116 int cmp_int8_t(const int8_t *a, const int8_t *b) { return *a == *b ? 0 : (*a < *b ? -1 : 1); }
1117 int cmp_int16_t(const int16_t *a, const int16_t *b) { return *a == *b ? 0 : (*a < *b ? -1 : 1); }
1118 int cmp_int32_t(const int32_t *a, const int32_t *b) { return *a == *b ? 0 : (*a < *b ? -1 : 1); }
1119 int cmp_int64_t(const int64_t *a, const int64_t *b) { return *a == *b ? 0 : (*a < *b ? -1 : 1); }
1121 int cmp_float32_t(const float32_t *a, const float32_t *b) { return *a == *b ? 0 : (*a < *b ? -1 : 1); }
1122 int cmp_float64_t(const float64_t *a, const float64_t *b) { return *a == *b ? 0 : (*a < *b ? -1 : 1); }
1123 int cmp_uintptr_t(const uintptr_t *a, const uintptr_t *b) { return *a == *b ? 0 : (*a < *b ? -1 : 1); }
1125 void UArray_sort(UArray *self)
1127 void *base = self->data;
1128 size_t size = self->size;
1130 UArray_changed(self);
1132 switch(self->itemType)
1134 case CTYPE_uint8_t: qsort(base, size, sizeof(uint8_t), (UArraySortCallback *)cmp_uint8_t); return;
1135 case CTYPE_uint16_t: qsort(base, size, sizeof(uint16_t), (UArraySortCallback *)cmp_uint16_t); return;
1136 case CTYPE_uint32_t: qsort(base, size, sizeof(uint32_t), (UArraySortCallback *)cmp_uint32_t); return;
1137 case CTYPE_uint64_t: qsort(base, size, sizeof(uint64_t), (UArraySortCallback *)cmp_uint64_t); return;
1139 case CTYPE_int8_t: qsort(base, size, sizeof(int8_t), (UArraySortCallback *)cmp_int8_t); return;
1140 case CTYPE_int16_t: qsort(base, size, sizeof(int16_t), (UArraySortCallback *)cmp_int16_t); return;
1141 case CTYPE_int32_t: qsort(base, size, sizeof(int32_t), (UArraySortCallback *)cmp_int32_t); return;
1142 case CTYPE_int64_t: qsort(base, size, sizeof(int64_t), (UArraySortCallback *)cmp_int64_t); return;
1144 case CTYPE_float32_t: qsort(base, size, sizeof(float32_t), (UArraySortCallback *)cmp_float32_t); return;
1145 case CTYPE_float64_t: qsort(base, size, sizeof(float64_t), (UArraySortCallback *)cmp_float64_t); return;
1146 case CTYPE_uintptr_t: qsort(base, size, sizeof(uintptr_t), (UArraySortCallback *)cmp_uintptr_t); return;
1150 void UArray_sortBy_(UArray *self, UArraySortCallback *cmp)
1152 void *base = self->data;
1153 size_t size = self->size;
1155 UArray_changed(self);
1157 switch(self->itemType)
1159 case CTYPE_uint8_t: qsort(base, size, sizeof(uint8_t), cmp); return;
1160 case CTYPE_uint16_t: qsort(base, size, sizeof(uint16_t), cmp); return;
1161 case CTYPE_uint32_t: qsort(base, size, sizeof(uint32_t), cmp); return;
1162 case CTYPE_uint64_t: qsort(base, size, sizeof(uint64_t), cmp); return;
1164 case CTYPE_int8_t: qsort(base, size, sizeof(int8_t), cmp); return;
1165 case CTYPE_int16_t: qsort(base, size, sizeof(int16_t), cmp); return;
1166 case CTYPE_int32_t: qsort(base, size, sizeof(int32_t), cmp); return;
1167 case CTYPE_int64_t: qsort(base, size, sizeof(int64_t), cmp); return;
1169 case CTYPE_float32_t: qsort(base, size, sizeof(float32_t), cmp); return;
1170 case CTYPE_float64_t: qsort(base, size, sizeof(float64_t), cmp); return;
1171 case CTYPE_uintptr_t: qsort(base, size, sizeof(uintptr_t), cmp); return;