mirror of
https://github.com/gryf/wmaker.git
synced 2026-02-02 14:15:46 +01:00
Finished the WMArray class
This commit is contained in:
@@ -14,6 +14,7 @@ changes since wmaker 0.62.1:
|
||||
- restructured the directory tree. Added Documentation, Examples and Tests
|
||||
subdirectories
|
||||
- removed WMArrayBag and reorganized WMTreeBag to be WMBag.
|
||||
- added WMArray class.
|
||||
|
||||
|
||||
changes since wmaker 0.62.0:
|
||||
|
||||
@@ -26,14 +26,25 @@ EXTRA_DIST = BUGS
|
||||
libWINGs_a_SOURCES = \
|
||||
WINGs.h \
|
||||
WINGsP.h \
|
||||
array.c \
|
||||
bagtree.c \
|
||||
configuration.c \
|
||||
connection.c \
|
||||
data.c \
|
||||
dragdestination.c \
|
||||
dragsource.c \
|
||||
error.c \
|
||||
findfile.c \
|
||||
fontmanager.c \
|
||||
hashtable.c \
|
||||
host.c \
|
||||
international.c \
|
||||
memory.c \
|
||||
notification.c \
|
||||
selection.c \
|
||||
string.c \
|
||||
userdefaults.c \
|
||||
usleep.c \
|
||||
wapplication.c \
|
||||
wappresource.c \
|
||||
wballoon.c \
|
||||
@@ -64,38 +75,29 @@ libWINGs_a_SOURCES = \
|
||||
wtabview.c \
|
||||
wtext.c \
|
||||
wtextfield.c \
|
||||
wwindow.c \
|
||||
wview.c \
|
||||
error.c \
|
||||
findfile.c \
|
||||
bagtree.c \
|
||||
connection.c \
|
||||
data.c \
|
||||
hashtable.c \
|
||||
host.c \
|
||||
memory.c \
|
||||
string.c \
|
||||
usleep.c
|
||||
wwindow.c
|
||||
|
||||
|
||||
libWUtil_a_SOURCES = \
|
||||
WINGs.h \
|
||||
WINGsP.h \
|
||||
array.c \
|
||||
bagtree.c \
|
||||
connection.c \
|
||||
data.c \
|
||||
host.c \
|
||||
international.c \
|
||||
notification.c \
|
||||
userdefaults.c \
|
||||
wapplication.c \
|
||||
wutil.c \
|
||||
error.c \
|
||||
findfile.c \
|
||||
hashtable.c \
|
||||
host.c \
|
||||
international.c \
|
||||
memory.c \
|
||||
notification.c \
|
||||
string.c \
|
||||
usleep.c
|
||||
userdefaults.c \
|
||||
usleep.c \
|
||||
wapplication.c \
|
||||
wutil.c
|
||||
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/wrlib -I$(top_srcdir)/src \
|
||||
|
||||
132
WINGs/WUtil.h
132
WINGs/WUtil.h
@@ -112,7 +112,8 @@ typedef 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;
|
||||
|
||||
|
||||
#if 0
|
||||
struct W_Bag {
|
||||
void *data;
|
||||
|
||||
void (*destructor)(void *item);
|
||||
|
||||
W_BagFunctions func;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
typedef struct {
|
||||
char character; /* the escape character */
|
||||
@@ -317,21 +306,84 @@ extern const WMHashTableCallbacks WMStringPointerHashCallbacks;
|
||||
|
||||
/*......................................................................*/
|
||||
|
||||
|
||||
/*
|
||||
* Array bags use an array to store the elements.
|
||||
* Item indexes may be any integer number.
|
||||
*
|
||||
* WMArray use an array to store the elements.
|
||||
* Item indexes may be only positive integer numbers.
|
||||
* The array cannot contain holes in it.
|
||||
*
|
||||
* Pros:
|
||||
* Fast [O(1)] access to elements
|
||||
* Fast [O(1)] push/pop
|
||||
*
|
||||
*
|
||||
* Cons:
|
||||
* A little slower [O(n)] for insertion/deletion of elements that
|
||||
* 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.
|
||||
* Item indexes may be any integer number.
|
||||
@@ -353,29 +405,29 @@ WMBag* WMCreateTreeBag(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 */
|
||||
int WMInsertInBag(WMBag *self, int index, void *item);
|
||||
int WMInsertInBag(WMBag *bag, int index, void *item);
|
||||
|
||||
/* this is slow */
|
||||
/* erase will remove the element from the bag,
|
||||
* 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
|
||||
* 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)
|
||||
|
||||
@@ -384,29 +436,29 @@ void* WMReplaceInBag(WMBag *self, int index, void *item);
|
||||
* > 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);
|
||||
|
||||
|
||||
265
WINGs/array.c
265
WINGs/array.c
@@ -19,10 +19,10 @@
|
||||
#define RESIZE_INCREMENT 8
|
||||
|
||||
|
||||
typedef struct {
|
||||
typedef struct W_Array {
|
||||
void **items; /* the array data */
|
||||
unsigned int length; /* # of items in array */
|
||||
unsigned int allocSize; /* allocated size of array */
|
||||
unsigned itemCount; /* # of items in array */
|
||||
unsigned allocSize; /* allocated size of array */
|
||||
void (*destructor)(void *item); /* the destructor to free elements */
|
||||
} W_Array;
|
||||
|
||||
@@ -47,7 +47,7 @@ WMCreateArrayWithDestructor(unsigned initialSize, void (*destructor)(void*))
|
||||
|
||||
array->items = wmalloc(sizeof(void*) * initialSize);
|
||||
|
||||
array->length = 0;
|
||||
array->itemCount = 0;
|
||||
array->allocSize = initialSize;
|
||||
array->destructor = destructor;
|
||||
|
||||
@@ -59,12 +59,13 @@ void
|
||||
WMEmptyArray(WMArray *array)
|
||||
{
|
||||
if (array->destructor) {
|
||||
while (array->length-- > 0) {
|
||||
array->destructor(array->items[array->length]);
|
||||
while (array->itemCount > 0) {
|
||||
array->itemCount--;
|
||||
array->destructor(array->items[array->itemCount]);
|
||||
}
|
||||
}
|
||||
/*memset(array->items, 0, array->length * sizeof(void*));*/
|
||||
array->length = 0;
|
||||
/*memset(array->items, 0, array->itemCount * sizeof(void*));*/
|
||||
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*
|
||||
WMReplaceInArray(WMArray *array, unsigned int index, void *data)
|
||||
WMReplaceInArray(WMArray *array, unsigned index, void *item)
|
||||
{
|
||||
void *old;
|
||||
|
||||
wassertrv(index > array->length, 0);
|
||||
wassertrv(index > array->itemCount, 0);
|
||||
|
||||
if (index == array->length) {
|
||||
WMArrayAppend(array, data);
|
||||
if (index == array->itemCount) {
|
||||
WMAddToArray(array, item);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
old = array->items[index];
|
||||
array->items[index] = data;
|
||||
array->items[index] = item;
|
||||
|
||||
return old;
|
||||
}
|
||||
|
||||
|
||||
void*
|
||||
WMGetArrayElement(WMArray *array, unsigned int index)
|
||||
static void
|
||||
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 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*
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
WMIndexForArrayElement(WMArray *array, void *data)
|
||||
WMFindInArray(WMArray *array, int (*match)(void*, void*), void *cdata)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < array->length; i++)
|
||||
if (array->items[i] == data)
|
||||
return i;
|
||||
if (match!=NULL) {
|
||||
for (i = 0; i < array->itemCount; 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user