| 48 } |
48 } |
| 49 return cxReallocDefault(array, n); |
49 return cxReallocDefault(array, n); |
| 50 } |
50 } |
| 51 |
51 |
| 52 CxArrayReallocator cx_array_default_reallocator_impl = { |
52 CxArrayReallocator cx_array_default_reallocator_impl = { |
| 53 cx_array_default_realloc, NULL, NULL, 0, 0 |
53 cx_array_default_realloc, NULL, NULL |
| 54 }; |
54 }; |
| 55 |
55 |
| 56 CxArrayReallocator *cx_array_default_reallocator = &cx_array_default_reallocator_impl; |
56 CxArrayReallocator *cx_array_default_reallocator = &cx_array_default_reallocator_impl; |
| 57 |
57 |
| 58 // Stack-aware array reallocator |
58 // Stack-aware array reallocator |
| 70 errno = EOVERFLOW; |
70 errno = EOVERFLOW; |
| 71 return NULL; |
71 return NULL; |
| 72 } |
72 } |
| 73 |
73 |
| 74 // retrieve the pointer to the actual allocator |
74 // retrieve the pointer to the actual allocator |
| 75 const CxAllocator *al = alloc->ptr1; |
75 const CxAllocator *al = alloc->allocator; |
| 76 |
76 |
| 77 // check if the array is still located on the stack |
77 // check if the array is still located on the stack |
| 78 void *newmem; |
78 void *newmem; |
| 79 if (array == alloc->ptr2) { |
79 if (array == alloc->stack_ptr) { |
| 80 newmem = cxMalloc(al, n); |
80 newmem = cxMalloc(al, n); |
| 81 if (newmem != NULL && array != NULL) { |
81 if (newmem != NULL && array != NULL) { |
| 82 memcpy(newmem, array, old_capacity*elem_size); |
82 memcpy(newmem, array, old_capacity*elem_size); |
| 83 } |
83 } |
| 84 } else { |
84 } else { |
| 87 return newmem; |
87 return newmem; |
| 88 } |
88 } |
| 89 |
89 |
| 90 struct cx_array_reallocator_s cx_array_reallocator( |
90 struct cx_array_reallocator_s cx_array_reallocator( |
| 91 const struct cx_allocator_s *allocator, |
91 const struct cx_allocator_s *allocator, |
| 92 const void *stackmem |
92 const void *stack_ptr |
| 93 ) { |
93 ) { |
| 94 if (allocator == NULL) { |
94 if (allocator == NULL) { |
| 95 allocator = cxDefaultAllocator; |
95 allocator = cxDefaultAllocator; |
| 96 } |
96 } |
| 97 return (struct cx_array_reallocator_s) { |
97 return (struct cx_array_reallocator_s) { |
| 98 cx_array_advanced_realloc, |
98 cx_array_advanced_realloc, |
| 99 (void*) allocator, (void*) stackmem, |
99 allocator, stack_ptr, |
| 100 0, 0 |
|
| 101 }; |
100 }; |
| 102 } |
101 } |
| 103 |
102 |
| 104 // LOW LEVEL ARRAY LIST FUNCTIONS |
103 // LOW LEVEL ARRAY LIST FUNCTIONS |
| 105 |
104 |
| 879 static int cx_arl_insert_iter( |
878 static int cx_arl_insert_iter( |
| 880 struct cx_iterator_s *iter, |
879 struct cx_iterator_s *iter, |
| 881 const void *elem, |
880 const void *elem, |
| 882 int prepend |
881 int prepend |
| 883 ) { |
882 ) { |
| 884 struct cx_list_s *list = iter->src_handle.m; |
883 struct cx_list_s *list = iter->src_handle; |
| 885 if (iter->index < list->collection.size) { |
884 if (iter->index < list->collection.size) { |
| 886 if (cx_arl_insert_element(list, |
885 if (cx_arl_insert_element(list, |
| 887 iter->index + 1 - prepend, elem) == NULL) { |
886 iter->index + 1 - prepend, elem) == NULL) { |
| 888 return 1; |
887 return 1; |
| 889 } |
888 } |
| 1090 } |
1089 } |
| 1091 } |
1090 } |
| 1092 |
1091 |
| 1093 static bool cx_arl_iter_valid(const void *it) { |
1092 static bool cx_arl_iter_valid(const void *it) { |
| 1094 const struct cx_iterator_s *iter = it; |
1093 const struct cx_iterator_s *iter = it; |
| 1095 const struct cx_list_s *list = iter->src_handle.c; |
1094 const struct cx_list_s *list = iter->src_handle; |
| 1096 return iter->index < list->collection.size; |
1095 return iter->index < list->collection.size; |
| 1097 } |
1096 } |
| 1098 |
1097 |
| 1099 static void *cx_arl_iter_current(const void *it) { |
1098 static void *cx_arl_iter_current(const void *it) { |
| 1100 const struct cx_iterator_s *iter = it; |
1099 const struct cx_iterator_s *iter = it; |
| 1103 |
1102 |
| 1104 static void cx_arl_iter_next(void *it) { |
1103 static void cx_arl_iter_next(void *it) { |
| 1105 struct cx_iterator_s *iter = it; |
1104 struct cx_iterator_s *iter = it; |
| 1106 if (iter->base.remove) { |
1105 if (iter->base.remove) { |
| 1107 iter->base.remove = false; |
1106 iter->base.remove = false; |
| 1108 cx_arl_remove(iter->src_handle.m, iter->index, 1, NULL); |
1107 cx_arl_remove(iter->src_handle, iter->index, 1, NULL); |
| 1109 iter->elem_count--; |
1108 iter->elem_count--; |
| 1110 } else { |
1109 } else { |
| 1111 iter->index++; |
1110 iter->index++; |
| 1112 iter->elem_handle = |
1111 iter->elem_handle = |
| 1113 ((char *) iter->elem_handle) |
1112 ((char *) iter->elem_handle) |
| 1114 + ((const struct cx_list_s *) iter->src_handle.c)->collection.elem_size; |
1113 + ((const struct cx_list_s *) iter->src_handle)->collection.elem_size; |
| 1115 } |
1114 } |
| 1116 } |
1115 } |
| 1117 |
1116 |
| 1118 static void cx_arl_iter_prev(void *it) { |
1117 static void cx_arl_iter_prev(void *it) { |
| 1119 struct cx_iterator_s *iter = it; |
1118 struct cx_iterator_s *iter = it; |
| 1120 const cx_array_list *list = iter->src_handle.c; |
|
| 1121 if (iter->base.remove) { |
1119 if (iter->base.remove) { |
| 1122 iter->base.remove = false; |
1120 iter->base.remove = false; |
| 1123 cx_arl_remove(iter->src_handle.m, iter->index, 1, NULL); |
1121 cx_arl_remove(iter->src_handle, iter->index, 1, NULL); |
| 1124 iter->elem_count--; |
1122 iter->elem_count--; |
| 1125 } |
1123 } |
| 1126 iter->index--; |
1124 iter->index--; |
| |
1125 cx_array_list *list = iter->src_handle; |
| 1127 if (iter->index < list->base.collection.size) { |
1126 if (iter->index < list->base.collection.size) { |
| 1128 iter->elem_handle = ((char *) list->data) |
1127 iter->elem_handle = ((char *) list->data) |
| 1129 + iter->index * list->base.collection.elem_size; |
1128 + iter->index * list->base.collection.elem_size; |
| 1130 } |
1129 } |
| 1131 } |
1130 } |
| 1137 bool backwards |
1136 bool backwards |
| 1138 ) { |
1137 ) { |
| 1139 struct cx_iterator_s iter; |
1138 struct cx_iterator_s iter; |
| 1140 |
1139 |
| 1141 iter.index = index; |
1140 iter.index = index; |
| 1142 iter.src_handle.c = list; |
1141 iter.src_handle = (void*)list; |
| 1143 iter.elem_handle = cx_arl_at(list, index); |
1142 iter.elem_handle = cx_arl_at(list, index); |
| 1144 iter.elem_size = list->collection.elem_size; |
1143 iter.elem_size = list->collection.elem_size; |
| 1145 iter.elem_count = list->collection.size; |
1144 iter.elem_count = list->collection.size; |
| 1146 iter.base.valid = cx_arl_iter_valid; |
1145 iter.base.valid = cx_arl_iter_valid; |
| 1147 iter.base.current = cx_arl_iter_current; |
1146 iter.base.current = cx_arl_iter_current; |
| 1148 iter.base.next = backwards ? cx_arl_iter_prev : cx_arl_iter_next; |
1147 iter.base.next = backwards ? cx_arl_iter_prev : cx_arl_iter_next; |
| 1149 iter.base.remove = false; |
1148 iter.base.remove = false; |
| 1150 iter.base.mutating = false; |
1149 iter.base.allow_remove = true; |
| 1151 |
1150 |
| 1152 return iter; |
1151 return iter; |
| 1153 } |
1152 } |
| 1154 |
1153 |
| 1155 static cx_list_class cx_array_list_class = { |
1154 static cx_list_class cx_array_list_class = { |