33 #include "ucx/array.h" |
33 #include "ucx/array.h" |
34 #include "ucx/utils.h" |
34 #include "ucx/utils.h" |
35 |
35 |
36 #include <string.h> |
36 #include <string.h> |
37 #include <stdlib.h> |
37 #include <stdlib.h> |
|
38 #include <errno.h> |
38 |
39 |
39 #ifndef UCX_ARRAY_DISABLE_QSORT |
40 #ifndef UCX_ARRAY_DISABLE_QSORT |
40 #ifdef __GLIBC__ |
41 #ifdef __GLIBC__ |
41 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8) |
42 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8) |
42 #define ucx_array_sort_impl qsort_r |
43 #define ucx_array_sort_impl qsort_r |
63 required_capacity <<= 1; |
64 required_capacity <<= 1; |
64 } |
65 } |
65 if (ucx_array_reserve(array, required_capacity)) { |
66 if (ucx_array_reserve(array, required_capacity)) { |
66 return 1; |
67 return 1; |
67 } |
68 } |
|
69 } |
|
70 |
|
71 int ucx_array_util_set_a(UcxAllocator* alloc, void** array, size_t* capacity, |
|
72 size_t elmsize, size_t index, ...) { |
|
73 |
|
74 if(!alloc || !capacity || !array) { |
|
75 errno = EINVAL; |
|
76 return 1; |
|
77 } |
|
78 |
|
79 size_t newcapacity = *capacity; |
|
80 while(index >= newcapacity) { |
|
81 if(ucx_szmul(newcapacity, 2, &newcapacity)) { |
|
82 errno = EOVERFLOW; |
|
83 return 1; |
|
84 } |
|
85 } |
|
86 |
|
87 size_t memlen, offset; |
|
88 if(ucx_szmul(newcapacity, elmsize, &memlen)) { |
|
89 errno = EOVERFLOW; |
|
90 return 1; |
|
91 } |
|
92 /* we don't need to check index*elmsize - it is smaller than memlen */ |
|
93 |
|
94 |
|
95 void* newptr = alrealloc(alloc, *array, memlen); |
|
96 if(newptr == NULL) { |
|
97 errno = ENOMEM; /* we cannot assume that every allocator sets this */ |
|
98 return 1; |
|
99 } |
|
100 *array = newptr; |
|
101 *capacity = newcapacity; |
|
102 |
|
103 |
|
104 char* dest = *array; |
|
105 dest += elmsize*index; |
|
106 |
|
107 va_list ap; |
|
108 va_start(ap, index); |
|
109 int elem = va_arg(ap, int); |
|
110 memcpy(dest, &elem, elmsize); |
|
111 va_end(ap); |
|
112 |
|
113 return 0; |
68 } |
114 } |
69 |
115 |
70 UcxArray ucx_array_new(size_t capacity, size_t elemsize) { |
116 UcxArray ucx_array_new(size_t capacity, size_t elemsize) { |
71 return ucx_array_new_a(capacity, elemsize, ucx_default_allocator()); |
117 return ucx_array_new_a(capacity, elemsize, ucx_default_allocator()); |
72 } |
118 } |