1
0
mirror of https://github.com/gryf/wmaker.git synced 2026-01-09 07:14:18 +01:00

Finished the WMArray class

This commit is contained in:
dan
2000-09-20 00:30:45 +00:00
parent 468f578345
commit c1a77f233f
4 changed files with 287 additions and 149 deletions

View File

@@ -14,6 +14,7 @@ changes since wmaker 0.62.1:
- restructured the directory tree. Added Documentation, Examples and Tests - restructured the directory tree. Added Documentation, Examples and Tests
subdirectories subdirectories
- removed WMArrayBag and reorganized WMTreeBag to be WMBag. - removed WMArrayBag and reorganized WMTreeBag to be WMBag.
- added WMArray class.
changes since wmaker 0.62.0: changes since wmaker 0.62.0:

View File

@@ -26,14 +26,25 @@ EXTRA_DIST = BUGS
libWINGs_a_SOURCES = \ libWINGs_a_SOURCES = \
WINGs.h \ WINGs.h \
WINGsP.h \ WINGsP.h \
array.c \
bagtree.c \
configuration.c \ configuration.c \
connection.c \
data.c \
dragdestination.c \ dragdestination.c \
dragsource.c \ dragsource.c \
error.c \
findfile.c \
fontmanager.c \ fontmanager.c \
hashtable.c \
host.c \
international.c \ international.c \
memory.c \
notification.c \ notification.c \
selection.c \ selection.c \
string.c \
userdefaults.c \ userdefaults.c \
usleep.c \
wapplication.c \ wapplication.c \
wappresource.c \ wappresource.c \
wballoon.c \ wballoon.c \
@@ -64,38 +75,29 @@ libWINGs_a_SOURCES = \
wtabview.c \ wtabview.c \
wtext.c \ wtext.c \
wtextfield.c \ wtextfield.c \
wwindow.c \
wview.c \ wview.c \
error.c \ wwindow.c
findfile.c \
bagtree.c \
connection.c \
data.c \
hashtable.c \
host.c \
memory.c \
string.c \
usleep.c
libWUtil_a_SOURCES = \ libWUtil_a_SOURCES = \
WINGs.h \ WINGs.h \
WINGsP.h \ WINGsP.h \
array.c \
bagtree.c \ bagtree.c \
connection.c \ connection.c \
data.c \ data.c \
host.c \
international.c \
notification.c \
userdefaults.c \
wapplication.c \
wutil.c \
error.c \ error.c \
findfile.c \ findfile.c \
hashtable.c \ hashtable.c \
host.c \
international.c \
memory.c \ memory.c \
notification.c \
string.c \ string.c \
usleep.c userdefaults.c \
usleep.c \
wapplication.c \
wutil.c
INCLUDES = -I$(top_srcdir)/wrlib -I$(top_srcdir)/src \ INCLUDES = -I$(top_srcdir)/wrlib -I$(top_srcdir)/src \

View File

@@ -112,7 +112,8 @@ typedef enum {
enum { enum {
WBNotFound = INT_MIN /* element was not found in bag */ WBNotFound = INT_MIN, /* element was not found in bag */
WANotFound = -1 /* element was not found in array */
}; };
@@ -162,18 +163,6 @@ typedef struct {
typedef void *WMBagIterator; typedef void *WMBagIterator;
#if 0
struct W_Bag {
void *data;
void (*destructor)(void *item);
W_BagFunctions func;
};
#endif
#if 0 #if 0
typedef struct { typedef struct {
char character; /* the escape character */ char character; /* the escape character */
@@ -317,10 +306,10 @@ extern const WMHashTableCallbacks WMStringPointerHashCallbacks;
/*......................................................................*/ /*......................................................................*/
/* /*
* Array bags use an array to store the elements. * WMArray use an array to store the elements.
* Item indexes may be any integer number. * Item indexes may be only positive integer numbers.
* The array cannot contain holes in it.
* *
* Pros: * Pros:
* Fast [O(1)] access to elements * Fast [O(1)] access to elements
@@ -329,9 +318,72 @@ extern const WMHashTableCallbacks WMStringPointerHashCallbacks;
* Cons: * Cons:
* A little slower [O(n)] for insertion/deletion of elements that * A little slower [O(n)] for insertion/deletion of elements that
* aren't in the end * aren't in the end
* Element indexes with large difference will cause large holes
*/ */
WMArray* WMCreateArray(unsigned initialSize);
WMArray* WMCreateArrayWithDestructor(unsigned initialSize,
void (*destructor)(void*));
void WMEmptyArray(WMArray *array);
void WMFreeArray(WMArray *array);
unsigned WMGetArrayItemCount(WMArray *array);
/* appends other to array. other remains unchanged */
int WMAppendArray(WMArray *array, WMArray *other);
/* add will place the element at the end of the array */
int WMAddToArray(WMArray *array, void *item);
#define WMPushInArray(array, item) WMAddToArray(array, item)
/* insert will increment the index of elements after it by 1 */
int WMInsertInArray(WMArray *array, unsigned index, void *item);
/* replace and set will return the old item WITHOUT calling the
* destructor on it even if its available. Free the returned item yourself.
*/
void* WMReplaceInArray(WMArray *array, unsigned index, void *item);
#define WMSetInArray(array, index, item) WMReplaceInArray(array, index, item)
/* delete and remove will remove the elements and cause the elements
* after them to decrement their indexes by 1. Also will call the
* destructor on the deleted element if there's one available.
*/
int WMDeleteFromArray(WMArray *array, unsigned index);
int WMRemoveFromArray(WMArray *array, void *item);
void* WMGetFromArray(WMArray *array, unsigned index);
#define WMGetFirstInArray(array, item) WMFindInArray(array, NULL, item)
/* pop will return the last element from the array, also removing it
* from the array. The destructor is NOT called, even if available.
* Free the returned element if needed by yourself
*/
void* WMPopFromArray(WMArray *array);
int WMFindInArray(WMArray *array, int (*match)(void*, void*), void *cdata);
unsigned WMCountInArray(WMArray *array, void *item);
/* comparer must return:
* < 0 if a < b
* > 0 if a > b
* = 0 if a = b
*/
int WMSortArray(WMArray *array, int (*comparer)(const void*, const void*));
void WMMapArray(WMArray *array, void (*function)(void*, void*), void *data);
/*..........................................................................*/
/* /*
* Tree bags use a red-black tree for storage. * Tree bags use a red-black tree for storage.
* Item indexes may be any integer number. * Item indexes may be any integer number.
@@ -353,29 +405,29 @@ WMBag* WMCreateTreeBag(void);
WMBag* WMCreateTreeBagWithDestructor(void (*destructor)(void*)); WMBag* WMCreateTreeBagWithDestructor(void (*destructor)(void*));
int WMGetBagItemCount(WMBag *self); int WMGetBagItemCount(WMBag *bag);
int WMAppendBag(WMBag *self, WMBag *bag); int WMAppendBag(WMBag *bag, WMBag *other);
int WMPutInBag(WMBag *self, void *item); int WMPutInBag(WMBag *bag, void *item);
/* insert will increment the index of elements after it by 1 */ /* insert will increment the index of elements after it by 1 */
int WMInsertInBag(WMBag *self, int index, void *item); int WMInsertInBag(WMBag *bag, int index, void *item);
/* this is slow */ /* this is slow */
/* erase will remove the element from the bag, /* erase will remove the element from the bag,
* but will keep the index of the other elements unchanged */ * but will keep the index of the other elements unchanged */
int WMEraseFromBag(WMBag *self, int index); int WMEraseFromBag(WMBag *bag, int index);
/* delete and remove will remove the elements and cause the elements /* delete and remove will remove the elements and cause the elements
* after them to decrement their indexes by 1 */ * after them to decrement their indexes by 1 */
int WMRemoveFromBag(WMBag *self, void *item); int WMDeleteFromBag(WMBag *bag, int index);
int WMDeleteFromBag(WMBag *self, int index); int WMRemoveFromBag(WMBag *bag, void *item);
void* WMGetFromBag(WMBag *self, int index); void* WMGetFromBag(WMBag *bag, int index);
void* WMReplaceInBag(WMBag *self, int index, void *item); void* WMReplaceInBag(WMBag *bag, int index, void *item);
#define WMSetInBag(bag, index, item) WMReplaceInBag(bag, index, item) #define WMSetInBag(bag, index, item) WMReplaceInBag(bag, index, item)
@@ -384,29 +436,29 @@ void* WMReplaceInBag(WMBag *self, int index, void *item);
* > 0 if a > b * > 0 if a > b
* = 0 if a = b * = 0 if a = b
*/ */
int WMSortBag(WMBag *self, int (*comparer)(const void*, const void*)); int WMSortBag(WMBag *bag, int (*comparer)(const void*, const void*));
void WMEmptyBag(WMBag *self); void WMEmptyBag(WMBag *bag);
void WMFreeBag(WMBag *self); void WMFreeBag(WMBag *bag);
void WMMapBag(WMBag *self, void (*function)(void*, void*), void *data); void WMMapBag(WMBag *bag, void (*function)(void*, void*), void *data);
int WMGetFirstInBag(WMBag *self, void *item); int WMGetFirstInBag(WMBag *bag, void *item);
int WMCountInBag(WMBag *self, void *item); int WMCountInBag(WMBag *bag, void *item);
int WMFindInBag(WMBag *self, int (*match)(void*,void*), void *cdata); int WMFindInBag(WMBag *bag, int (*match)(void*,void*), void *cdata);
void* WMBagFirst(WMBag *self, WMBagIterator *ptr); void* WMBagFirst(WMBag *bag, WMBagIterator *ptr);
void* WMBagLast(WMBag *self, WMBagIterator *ptr); void* WMBagLast(WMBag *bag, WMBagIterator *ptr);
void* WMBagNext(WMBag *self, WMBagIterator *ptr); void* WMBagNext(WMBag *bag, WMBagIterator *ptr);
void* WMBagPrevious(WMBag *self, WMBagIterator *ptr); void* WMBagPrevious(WMBag *bag, WMBagIterator *ptr);
void* WMBagIteratorAtIndex(WMBag *self, int index, WMBagIterator *ptr); void* WMBagIteratorAtIndex(WMBag *bag, int index, WMBagIterator *ptr);
int WMBagIndexForIterator(WMBag *bag, WMBagIterator ptr); int WMBagIndexForIterator(WMBag *bag, WMBagIterator ptr);

View File

@@ -19,10 +19,10 @@
#define RESIZE_INCREMENT 8 #define RESIZE_INCREMENT 8
typedef struct { typedef struct W_Array {
void **items; /* the array data */ void **items; /* the array data */
unsigned int length; /* # of items in array */ unsigned itemCount; /* # of items in array */
unsigned int allocSize; /* allocated size of array */ unsigned allocSize; /* allocated size of array */
void (*destructor)(void *item); /* the destructor to free elements */ void (*destructor)(void *item); /* the destructor to free elements */
} W_Array; } W_Array;
@@ -47,7 +47,7 @@ WMCreateArrayWithDestructor(unsigned initialSize, void (*destructor)(void*))
array->items = wmalloc(sizeof(void*) * initialSize); array->items = wmalloc(sizeof(void*) * initialSize);
array->length = 0; array->itemCount = 0;
array->allocSize = initialSize; array->allocSize = initialSize;
array->destructor = destructor; array->destructor = destructor;
@@ -59,12 +59,13 @@ void
WMEmptyArray(WMArray *array) WMEmptyArray(WMArray *array)
{ {
if (array->destructor) { if (array->destructor) {
while (array->length-- > 0) { while (array->itemCount > 0) {
array->destructor(array->items[array->length]); array->itemCount--;
array->destructor(array->items[array->itemCount]);
} }
} }
/*memset(array->items, 0, array->length * sizeof(void*));*/ /*memset(array->items, 0, array->itemCount * sizeof(void*));*/
array->length = 0; array->itemCount = 0;
} }
@@ -77,123 +78,205 @@ WMFreeArray(WMArray *array)
} }
unsigned
WMGetArrayItemCount(WMArray *array)
{
return array->itemCount;
}
int
WMAppendArray(WMArray *array, WMArray *other)
{
if (other->itemCount == 0)
return 1;
if (array->itemCount + other->itemCount > array->allocSize) {
array->allocSize += other->allocSize;
array->items = wrealloc(array->items, sizeof(void*)*array->allocSize);
}
memcpy(array->items+array->itemCount, other->items,
sizeof(void*)*other->itemCount);
array->itemCount += other->itemCount;
return 1;
}
int
WMAddToArray(WMArray *array, void *item)
{
if (array->itemCount >= array->allocSize) {
array->allocSize += RESIZE_INCREMENT;
array->items = wrealloc(array->items, sizeof(void*)*array->allocSize);
}
array->items[array->itemCount] = item;
array->itemCount++;
return 1;
}
int
WMInsertInArray(WMArray *array, unsigned index, void *item)
{
wassertrv(index <= array->itemCount, 0);
if (array->itemCount >= array->allocSize) {
array->allocSize += RESIZE_INCREMENT;
array->items = wrealloc(array->items, sizeof(void*)*array->allocSize);
}
if (index < array->itemCount) {
memmove(array->items+index+1, array->items+index,
sizeof(void*)*(array->itemCount-index));
}
array->items[index] = item;
array->itemCount++;
return 1;
}
void* void*
WMReplaceInArray(WMArray *array, unsigned int index, void *data) WMReplaceInArray(WMArray *array, unsigned index, void *item)
{ {
void *old; void *old;
wassertrv(index > array->length, 0); wassertrv(index > array->itemCount, 0);
if (index == array->length) { if (index == array->itemCount) {
WMArrayAppend(array, data); WMAddToArray(array, item);
return NULL; return NULL;
} }
old = array->items[index]; old = array->items[index];
array->items[index] = data; array->items[index] = item;
return old; return old;
} }
void* static void
WMGetArrayElement(WMArray *array, unsigned int index) deleteFromArray(WMArray *array, unsigned index)
{ {
if (index >= array->length) /*wassertr(index < array->itemCount);*/
if (index < array->itemCount-1) {
memmove(array->items+index, array->items+index+1,
sizeof(void*)*(array->itemCount-index-1));
}
array->itemCount--;
}
int
WMDeleteFromArray(WMArray *array, unsigned index)
{
if (index >= array->itemCount)
return 0;
if (array->destructor) {
array->destructor(array->items[index]);
}
deleteFromArray(array, index);
return 1;
}
int
WMRemoveFromArray(WMArray *array, void *item)
{
unsigned i;
for (i = 0; i < array->itemCount; i++) {
if (array->items[i] == item) {
return WMDeleteFromArray(array, i);
}
}
return 0;
}
void*
WMGetFromArray(WMArray *array, unsigned index)
{
if (index >= array->itemCount)
return NULL; return NULL;
return array->items[index]; return array->items[index];
} }
#if 0
int
WMAppendToArray(WMArray *array, void *data)
{
if (array->length >= array->allocSize) {
array->allocSize += RESIZE_INCREMENT;
array->items = wrealloc(array->items, sizeof(void*)*array->allocSize);
}
array->items[array->length++] = data;
return 1;
}
#endif
int
WMInsertInArray(WMArray *array, unsigned index, void *data)
{
wassertrv(index <= array->length, 0);
if (array->length >= array->allocSize) {
array->allocSize += RESIZE_INCREMENT;
array->items = wrealloc(array->items, sizeof(void*)*array->allocSize);
}
if (index < array->length)
memmove(array->items+index+1, array->items+index,
sizeof(void*)*(array->length-index));
array->items[index] = data;
array->length++;
return 1;
}
int
WMAppendToArray(WMArray *array, void *data)
{
return WMInsertInArray(array, array->length, data);
}
static void
removeFromArray(WMArray *array, unsigned index)
{
/*wassertr(index < array->length);*/
memmove(array->items+index, array->items+index+1,
sizeof(void*)*(array->length-index-1));
array->length--;
}
void
WMDeleteFromArray(WMArray *array, unsigned index)
{
wassertr(index < array->length);
if (array->destructor) {
array->destructor(array->items[index]);
}
removeFromArray(array, index);
}
void* void*
WMArrayPop(WMArray *array) WMPopFromArray(WMArray *array)
{ {
void *last = array->items[length-1]; void *last = array->items[array->itemCount-1];
removeFromArray(array, array->length-1); deleteFromArray(array, array->itemCount-1);
return last; return last;
} }
int int
WMIndexForArrayElement(WMArray *array, void *data) WMFindInArray(WMArray *array, int (*match)(void*, void*), void *cdata)
{ {
unsigned i; unsigned i;
for (i = 0; i < array->length; i++) if (match!=NULL) {
if (array->items[i] == data) for (i = 0; i < array->itemCount; i++) {
return i; if ((*match)(array->items[i], cdata))
return i;
}
} else {
for (i = 0; i < array->itemCount; i++) {
if (array->items[i] == cdata)
return i;
}
}
return -1; return WANotFound;
}
unsigned
WMCountInArray(WMArray *array, void *item)
{
unsigned i, count;
for (i=0, count=0; i<array->itemCount; i++) {
if (array->items[i] == item)
count++;
}
return count;
}
int
WMSortArray(WMArray *array, int (*comparer)(const void*, const void*))
{
qsort(array->items, array->itemCount, sizeof(void*), comparer);
return 1;
}
void
WMMapArray(WMArray *array, void (*function)(void*, void*), void *data)
{
unsigned i;
for (i=0; i<array->itemCount; i++) {
(*function)(array->items[i], data);
}
} }