2 copyright: Steve Dekorte, 2006. All rights reserved.
3 license: See _BSDLicense.txt.
17 size_t CTYPE_size(CTYPE 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);
39 const char *CTYPE_name(CTYPE 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";
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
;
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
;
86 const char *CENCODING_name(CENCODING 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";
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
));
109 void UArray_error_(const UArray
*self
, char *e
)
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
);
147 UArray_setSize_(self
, (q
.quot
* itemSize
) / self
->itemSize
);
150 self
->itemType
= type
;
152 self
->itemSize
= itemSize
;
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
172 case CENCODING_ASCII
:
174 UArray_setItemType_(self
, CTYPE_uint8_t
);
176 case CENCODING_UTF16
:
177 UArray_setItemType_(self
, CTYPE_uint16_t
);
179 case CENCODING_UTF32
:
180 UArray_setItemType_(self
, CTYPE_uint32_t
);
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
189 self
->encoding
= encoding
;
192 void UArray_convertToEncoding_(UArray
*self
, CENCODING encoding
)
196 case CENCODING_ASCII
:
198 UArray_convertToUTF8(self
);
200 case CENCODING_UTF16
:
201 UArray_convertToUTF16(self
);
203 case CENCODING_UTF32
:
204 UArray_convertToUTF32(self
);
206 case CENCODING_NUMBER
:
207 UArray_setItemType_(self
, CTYPE_uint8_t
);
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
;
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
);
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
);
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
))
258 UARRAY_FOREACH(self
, i
, v
,
259 printf("%f", (float)v
);
260 if(i
!= self
->size
- 1) printf(", ");
267 UARRAY_FOREACH(self
, i
, v
,
268 printf("%i", (int)v
);
269 if(i
!= self
->size
- 1) printf(", ");
275 UArray
UArray_stackAllocedWithData_type_size_(void *data
, CTYPE type
, size_t size
)
278 memset(&self
, 0, sizeof(UArray
));
281 self
.stackAllocated
= 1;
284 self
.itemType
= type
;
285 self
.itemSize
= CTYPE_size(type
);
291 BASEKIT_API UArray
UArray_stackAllocedEmptyUArray(void)
294 memset(&self
, 0, sizeof(UArray
));
297 self
.stackAllocated
= 1;
300 self
.itemType
= CTYPE_int32_t
;
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
)
325 UArray_setItemType_(self
, CTYPE_uint8_t
);
326 UArray_appendCString_(self
, s
);
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");
340 void UArray_setData_type_size_copy_(UArray
*self
, void *data
, CTYPE type
, size_t size
, int copy
)
344 UArray_rawSetItemType_(self
, type
);
347 sizeInBytes
= self
->size
* self
->itemSize
;
350 UArray_checkIfOkToRelloc(self
);
355 self
->data
= io_realloc(self
->data
, sizeInBytes
+ 1);
356 memmove(self
->data
, data
, sizeInBytes
);
357 self
->data
[sizeInBytes
] = 0x0;
361 if(self
->data
) free(self
->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
)
377 const uint8_t *UArray_bytes(const UArray
*self
)
382 uint8_t *UArray_mutableBytes(UArray
*self
)
384 UArray_changed(self
);
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
);
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
;
414 UArray_checkIfOkToRelloc(self
);
416 self
->data
= io_realloc(self
->data
, newSizeInBytes
+ 1);
419 self
->data
[newSizeInBytes
] = 0x0;
422 if (newSizeInBytes
> oldSizeInBytes
)
424 memset(self
->data
+ oldSizeInBytes
, 0, newSizeInBytes
- oldSizeInBytes
);
427 UArray_changed(self
);
431 size_t UArray_size(const UArray
*self
)
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
);
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");
465 if(self
->itemType
== other
->itemType
)
467 UArray_copyData_(self
, other
);
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
);
493 UArray_changed(self
);
499 UArray
UArray_stackRange(const UArray
*self
, size_t start
, size_t size
)
503 memcpy(&s
, self
, sizeof(UArray
));
507 s
.stackAllocated
= 1;
510 if(start
< self
->size
|| start
== 0)
512 s
.data
= self
->data
+ self
->itemSize
* start
;
519 if(start
+ size
<= self
->size
)
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");
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");
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");
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
);
600 long UArray_firstLong(const UArray
*self
)
602 return UArray_rawLongAt_(self
, 0);
605 long UArray_lastLong(const UArray
*self
)
612 return UArray_rawLongAt_(self
, self
->size
- 1);
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
)
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
)
647 UArray_setSize_(self
, self
->size
- 1);
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
);
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
);
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
);
763 oldChunk
= UArray_stackRange(self
, pos
, chunkSize
);
764 newChunk
= UArray_stackRange(self
, pos
+ other
->size
, chunkSize
);
765 insertChunk
= UArray_stackRange(self
, pos
, other
->size
);
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
);
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;\
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;\
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;\
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;\
834 int UArray_compare_(const UArray
*self
, const UArray
*other
)
836 DUARRAY_OP(UARRAY_COMPARE_TYPES
, NULL
, self
, other
);
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
);
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;)
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)\
899 if(self->size < other->size || self->size == 0) return -1;\
900 for(i = 0; i < self->size - other->size + 1; i ++)\
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;\
915 long UArray_find_(const UArray
*self
, const UArray
*other
)
917 DUARRAY_OP(UARRAY_FIND_TYPES
, NULL
, self
, other
);
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)\
937 if(self->size < other->size) return -1;\
938 for(i = 0; i < self->size - other->size + 1; i ++)\
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; }\
953 long UArray_findAnyCase_(const UArray
*self
, const UArray
*other
)
955 DUARRAY_OP(UARRAY_FINDANYCASE_TYPES
, NULL
, self
, other
);
959 int UArray_containsAnyCase_(const UArray
*self
, const UArray
*other
)
961 long i
= UArray_findAnyCase_(self
, other
);
965 long UArray_findLongValue_(const UArray
*self
, long value
)
967 UARRAY_FOREACH(self
, i
, v
, if(v
== value
) return i
);
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
);
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)\
990 if(self->size < other->size) return -1;\
991 for(i = self->size - other->size + 1; i > -1; i --)\
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;}\
1005 long UArray_rFind_(const UArray
*self
, const UArray
*other
)
1007 DUARRAY_OP(UARRAY_RFIND_TYPES
, NULL
, self
, other
);
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
);
1018 #define UARRAY_RFINDANYCASE_TYPES(OP2, TYPE1, self, TYPE2, other)\
1021 if(self->size < other->size) return -1;\
1022 for(i = self->size - other->size + 1; i > -1; i --)\
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;\
1036 long UArray_rFindAnyCase_(const UArray
*self
, const UArray
*other
)
1038 DUARRAY_OP(UARRAY_RFINDANYCASE_TYPES
, NULL
, self
, other
);
1042 #define UARRAY_RFINDANYVALUE_TYPES(OP2, TYPE1, self, TYPE2, other)\
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; }\
1058 long UArray_rFindAnyValue_(const UArray
*self
, const UArray
*other
)
1060 DUARRAY_OP(UARRAY_RFINDANYVALUE_TYPES
, NULL
, self
, other
);
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;
1089 size_t UArray_wrapPos_(const UArray
*self
, long pos
)
1091 long size
= self
->size
;
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;