2 docCopyright("Steve Dekorte", 2002)
3 docLicense("BSD revised")
13 List
*self
= (List
*)io_calloc(1, sizeof(List
));
15 self
->memSize
= sizeof(void *)*LIST_START_SIZE
;
16 self
->items
= (void **)io_calloc(1, self
->memSize
);
20 List
*List_clone(const List
*self
)
22 List
*child
= List_new();
23 List_copy_(child
, self
);
25 List *child = cpalloc(self, sizeof(List));
26 child->items = cpalloc(self->items, self->memSize);
31 static size_t indexWrap(long index
, size_t size
)
43 if (index
> (int)size
)
51 void List_sliceInPlace(List
* self
, long startIndex
, long endIndex
)
53 size_t i
, size
= List_size(self
);
54 List
*tmp
= List_new();
55 size_t start
= indexWrap(startIndex
, size
);
56 size_t end
= indexWrap(endIndex
, size
);
58 for (i
= start
; i
< size
&& i
< end
+ 1; i
++)
60 List_append_(tmp
, List_at_(self
, i
));
63 List_copy_(self
, tmp
);
67 List
*List_cloneSlice(const List
*self
, long startIndex
, long endIndex
)
69 List
*child
= List_clone(self
);
70 List_sliceInPlace(child
, startIndex
, endIndex
);
74 void List_free(List
*self
)
76 //printf("List_free(%p)\n", (void *)self);
81 UArray
List_asStackAllocatedUArray(List
*self
)
83 UArray a
= UArray_stackAllocedEmptyUArray();
84 a
.itemType
= CTYPE_uintptr_t
;
85 a
.itemSize
= sizeof(uintptr_t);
87 a
.data
= (uint8_t *)(self
->items
);
91 size_t List_memorySize(const List
*self
)
93 return sizeof(List
) + (self
->size
* sizeof(void *));
96 void List_removeAll(List
*self
)
99 List_compactIfNeeded(self
);
102 void List_copy_(List
*self
, const List
*otherList
)
104 if (self
== otherList
|| (!otherList
->size
&& !self
->size
))
109 List_preallocateToSize_(self
, otherList
->size
);
110 memmove(self
->items
, otherList
->items
, sizeof(void *) * (otherList
->size
));
111 self
->size
= otherList
->size
;
114 int List_equals_(const List
*self
, const List
*otherList
)
116 return (self
->size
== otherList
->size
&&
117 memcmp(self
->items
, otherList
->items
, sizeof(void *) * self
->size
) == 0);
120 /* --- sizing ------------------------------------------------ */
122 void List_setSize_(List
*self
, size_t index
)
124 List_ifNeededSizeTo_(self
, index
);
128 void List_preallocateToSize_(List
*self
, size_t index
)
130 size_t s
= index
* sizeof(void *);
132 if (s
>= self
->memSize
)
134 size_t newSize
= self
->memSize
* LIST_RESIZE_FACTOR
;
141 self
->items
= (void **)io_realloc(self
->items
, newSize
);
142 memset(self
->items
+ self
->size
, 0, (newSize
- (self
->size
*sizeof(void *))));
143 self
->memSize
= newSize
;
147 void List_compact(List
*self
)
149 self
->memSize
= self
->size
* sizeof(void *);
150 self
->items
= (void **)io_realloc(self
->items
, self
->memSize
);
153 // -----------------------------------------------------------
155 void List_print(const List
*self
)
159 printf("List <%p> [%i bytes]\n", (void *)self
, (int)self
->memSize
);
161 for (i
= 0; i
< self
->size
; i
++)
163 printf("%i: %p\n", i
, (void *)self
->items
[i
]);
169 // enumeration -----------------------------------------
171 void List_do_(List
*self
, ListDoCallback
*callback
)
173 LIST_FOREACH(self
, i
, v
, if (v
) (*callback
)(v
));
176 void List_do_with_(List
*self
, ListDoWithCallback
*callback
, void *arg
)
178 LIST_FOREACH(self
, i
, v
, if (v
) (*callback
)(v
, arg
));
181 void List_mapInPlace_(List
*self
, ListCollectCallback
*callback
)
183 void **items
= self
->items
;
184 LIST_FOREACH(self
, i
, v
, items
[i
] = (*callback
)(v
));
187 List
*List_map_(List
*self
, ListCollectCallback
*callback
)
189 List
*r
= List_new();
190 LIST_FOREACH(self
, i
, v
, List_append_(r
, (*callback
)(v
)););
194 List
*List_select_(List
*self
, ListSelectCallback
*callback
)
196 List
*r
= List_new();
197 LIST_FOREACH(self
, i
, v
, if ((*callback
)(v
)) List_append_(r
, v
));
201 void *List_detect_(List
*self
, ListDetectCallback
*callback
)
203 LIST_FOREACH(self
, i
, v
, if (v
&& (*callback
)(v
)) return v
; );
207 void *List_anyOne(const List
*self
)
218 return LIST_AT_(self
, 0);
221 i
= (rand() >> 4) % (self
->size
); // without the shift, just get a sequence!
223 return LIST_AT_(self
, i
);
226 void List_shuffle(List
*self
)
230 for (i
= 0; i
< self
->size
- 1; i
++)
232 j
= i
+ rand() % (self
->size
- i
);
233 List_swap_with_(self
, i
, j
);
237 void *List_removeLast(List
*self
)
239 void *item
= List_at_(self
, self
->size
- 1);
244 List_compactIfNeeded(self
);