1 //metadoc List copyright Steve Dekorte 2002
2 //metadoc List license BSD revised
11 List
*self
= (List
*)io_calloc(1, sizeof(List
));
13 self
->memSize
= sizeof(void *)*LIST_START_SIZE
;
14 self
->items
= (void **)io_calloc(1, self
->memSize
);
18 List
*List_clone(const List
*self
)
20 List
*child
= List_new();
21 List_copy_(child
, self
);
23 List *child = cpalloc(self, sizeof(List));
24 child->items = cpalloc(self->items, self->memSize);
29 static size_t indexWrap(long index
, size_t size
)
41 if (index
> (int)size
)
49 void List_sliceInPlace(List
* self
, long startIndex
, long endIndex
)
51 size_t i
, size
= List_size(self
);
52 List
*tmp
= List_new();
53 size_t start
= indexWrap(startIndex
, size
);
54 size_t end
= indexWrap(endIndex
, size
);
56 for (i
= start
; i
< size
&& i
< end
+ 1; i
++)
58 List_append_(tmp
, List_at_(self
, i
));
61 List_copy_(self
, tmp
);
65 List
*List_cloneSlice(const List
*self
, long startIndex
, long endIndex
)
67 List
*child
= List_clone(self
);
68 List_sliceInPlace(child
, startIndex
, endIndex
);
72 void List_free(List
*self
)
74 //printf("List_free(%p)\n", (void *)self);
79 UArray
List_asStackAllocatedUArray(List
*self
)
81 UArray a
= UArray_stackAllocedEmptyUArray();
82 a
.itemType
= CTYPE_uintptr_t
;
83 a
.itemSize
= sizeof(uintptr_t);
85 a
.data
= (uint8_t *)(self
->items
);
89 size_t List_memorySize(const List
*self
)
91 return sizeof(List
) + (self
->size
* sizeof(void *));
94 void List_removeAll(List
*self
)
97 List_compactIfNeeded(self
);
100 void List_copy_(List
*self
, const List
*otherList
)
102 if (self
== otherList
|| (!otherList
->size
&& !self
->size
))
107 List_preallocateToSize_(self
, otherList
->size
);
108 memmove(self
->items
, otherList
->items
, sizeof(void *) * (otherList
->size
));
109 self
->size
= otherList
->size
;
112 int List_equals_(const List
*self
, const List
*otherList
)
114 return (self
->size
== otherList
->size
&&
115 memcmp(self
->items
, otherList
->items
, sizeof(void *) * self
->size
) == 0);
118 /* --- sizing ------------------------------------------------ */
120 void List_setSize_(List
*self
, size_t index
)
122 List_ifNeededSizeTo_(self
, index
);
126 void List_preallocateToSize_(List
*self
, size_t index
)
128 size_t s
= index
* sizeof(void *);
130 if (s
>= self
->memSize
)
132 size_t newSize
= self
->memSize
* LIST_RESIZE_FACTOR
;
139 self
->items
= (void **)io_realloc(self
->items
, newSize
);
140 memset(self
->items
+ self
->size
, 0, (newSize
- (self
->size
*sizeof(void *))));
141 self
->memSize
= newSize
;
145 void List_compact(List
*self
)
147 self
->memSize
= self
->size
* sizeof(void *);
148 self
->items
= (void **)io_realloc(self
->items
, self
->memSize
);
151 // -----------------------------------------------------------
153 void List_print(const List
*self
)
157 printf("List <%p> [%i bytes]\n", (void *)self
, (int)self
->memSize
);
159 for (i
= 0; i
< self
->size
; i
++)
161 printf("%i: %p\n", i
, (void *)self
->items
[i
]);
167 // enumeration -----------------------------------------
169 void List_do_(List
*self
, ListDoCallback
*callback
)
171 LIST_FOREACH(self
, i
, v
, if (v
) (*callback
)(v
));
174 void List_do_with_(List
*self
, ListDoWithCallback
*callback
, void *arg
)
176 LIST_FOREACH(self
, i
, v
, if (v
) (*callback
)(v
, arg
));
179 void List_mapInPlace_(List
*self
, ListCollectCallback
*callback
)
181 void **items
= self
->items
;
182 LIST_FOREACH(self
, i
, v
, items
[i
] = (*callback
)(v
));
185 List
*List_map_(List
*self
, ListCollectCallback
*callback
)
187 List
*r
= List_new();
188 LIST_FOREACH(self
, i
, v
, List_append_(r
, (*callback
)(v
)););
192 List
*List_select_(List
*self
, ListSelectCallback
*callback
)
194 List
*r
= List_new();
195 LIST_FOREACH(self
, i
, v
, if ((*callback
)(v
)) List_append_(r
, v
));
199 void *List_detect_(List
*self
, ListDetectCallback
*callback
)
201 LIST_FOREACH(self
, i
, v
, if (v
&& (*callback
)(v
)) return v
; );
205 void *List_anyOne(const List
*self
)
216 return LIST_AT_(self
, 0);
219 i
= (rand() >> 4) % (self
->size
); // without the shift, just get a sequence!
221 return LIST_AT_(self
, i
);
224 void List_shuffle(List
*self
)
228 for (i
= 0; i
< self
->size
- 1; i
++)
230 j
= i
+ rand() % (self
->size
- i
);
231 List_swap_with_(self
, i
, j
);
235 void *List_removeLast(List
*self
)
237 void *item
= List_at_(self
, self
->size
- 1);
242 List_compactIfNeeded(self
);