/* */
/* */
/* */
-/* (C) 2000-2001 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
-/* EMail: uz@cc65.org */
+/* (C) 2000-2011, Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
+void CollGrow (Collection* C, unsigned Size)
+/* Grow the collection C so it is able to hold Size items without a resize
+ * being necessary. This can be called for performance reasons if the number
+ * of items to be placed in the collection is known in advance.
+ */
+{
+ void** NewItems;
+
+ /* Ignore the call if the collection is already large enough */
+ if (Size <= C->Size) {
+ return;
+ }
+
+ /* Grow the collection */
+ C->Size = Size;
+ NewItems = xmalloc (C->Size * sizeof (void*));
+ memcpy (NewItems, C->Items, C->Count * sizeof (void*));
+ xfree (C->Items);
+ C->Items = NewItems;
+}
+
+
+
void CollInsert (Collection* C, void* Item, unsigned Index)
/* Insert the data at the given position in the collection */
{
/* Grow the array if necessary */
if (C->Count >= C->Size) {
/* Must grow */
- void** NewItems;
- if (C->Size > 0) {
- C->Size *= 2;
- } else {
- C->Size = 8;
- }
- NewItems = xmalloc (C->Size * sizeof (void*));
- memcpy (NewItems, C->Items, C->Count * sizeof (void*));
- xfree (C->Items);
- C->Items = NewItems;
+ CollGrow (C, (C->Size == 0)? 4 : C->Size * 2);
}
/* Move the existing elements if needed */
{
/* Insert the item at the end of the current list */
CollInsert (C, Item, C->Count);
-}
+}
#endif
#if !defined(HAVE_INLINE)
-void* CollAt (Collection* C, unsigned Index)
+void* CollAt (const Collection* C, unsigned Index)
/* Return the item at the given index */
{
/* Check the index */
+void CollReplaceExpand (Collection* C, void* Item, unsigned Index)
+/* If Index is a valid index for the collection, replace the item at this
+ * position by the one passed. If the collection is too small, expand it,
+ * filling unused pointers with NULL, then add the new item at the given
+ * position.
+ */
+{
+ if (Index < C->Count) {
+ /* Collection is already large enough */
+ C->Items[Index] = Item;
+ } else {
+ /* Must expand the collection */
+ unsigned Size = C->Size;
+ if (Size == 0) {
+ Size = 4;
+ }
+ while (Index >= Size) {
+ Size *= 2;
+ }
+ CollGrow (C, Size);
+
+ /* Fill up unused slots with NULL */
+ while (C->Count < Index) {
+ C->Items[C->Count++] = 0;
+ }
+
+ /* Fill in the item */
+ C->Items[C->Count++] = Item;
+ }
+}
+
+
+
void CollMove (Collection* C, unsigned OldIndex, unsigned NewIndex)
/* Move an item from one position in the collection to another. OldIndex
* is the current position of the item, NewIndex is the new index after
+void CollTransfer (Collection* Dest, const Collection* Source)
+/* Transfer all items from Source to Dest. Anything already in Dest is left
+ * untouched. The items in Source are not changed and are therefore in both
+ * Collections on return.
+ */
+{
+ /* Be sure there's enough room in Dest */
+ CollGrow (Dest, Dest->Count + Source->Count);
+
+ /* Copy the items */
+ memcpy (Dest->Items + Dest->Count,
+ Source->Items,
+ Source->Count * sizeof (Source->Items[0]));
+
+ /* Bump the counter */
+ Dest->Count += Source->Count;
+}
+
+
+
void CollSort (Collection* C,
int (*Compare) (void*, const void*, const void*),
void* Data)