X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fcommon%2Fcoll.c;h=0fa0d152e717683134d015f89c9c41097b5dcdcf;hb=74108cd74fc3ca3ad4f69b743233fa79791106b9;hp=a5eaac527794011405bc076be82d7f80803b664d;hpb=de7da529f05047509119f730d400c9753e3b2332;p=cc65 diff --git a/src/common/coll.c b/src/common/coll.c index a5eaac527..0fa0d152e 100644 --- a/src/common/coll.c +++ b/src/common/coll.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (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 */ @@ -108,6 +108,29 @@ void FreeCollection (Collection* C) +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 */ { @@ -117,16 +140,7 @@ void CollInsert (Collection* C, void* Item, unsigned Index) /* 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 */ @@ -147,13 +161,13 @@ void CollAppend (Collection* C, void* Item) { /* 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 */ @@ -292,6 +306,39 @@ void CollReplace (Collection* C, void* Item, unsigned 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 @@ -424,6 +471,26 @@ static void QuickSort (Collection* C, int Lo, int Hi, +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)