ISC license https://opensource.org/licenses/ISC
-Copyright (C) 2013-2018 Benjamin Auder
+Copyright (C) 2013-2021 Benjamin Auder
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
## Installation
- make [src]
- make install
+ make [src]
+ make install
'src' is Makefile default target.
## Example
- Vector* v = vector_new(int);
- vector_push(v, 32);
- vector_push(v, 42);
- int a; vector_get(v, 1, a); //a now contains 42
- vector_set(v, 0, 0); //v[0] now contains 0
- vector_destroy(v);
+ Vector* v = vector_new(int);
+ vector_push(v, 32);
+ vector_push(v, 42);
+ int a; vector_get(v, 1, a); //a now contains 42
+ vector_set(v, 0, 0); //v[0] now contains 0
+ vector_destroy(v);
More examples in the unit tests under test/ folder.
# identify the project. Note that if you do not use Doxywizard you need
# to put quotes around the project name if it contains spaces.
-PROJECT_NAME = "cds"
+PROJECT_NAME = "cgds"
# The PROJECT_NUMBER tag can be used to enter a project or revision number.
# This could be handy for archiving the generated documentation or
# if some version control system is used.
-PROJECT_NUMBER = 0.1.0
+PROJECT_NUMBER = 1.0.0
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer
# a quick idea about the purpose of the project. Keep the description short.
-PROJECT_BRIEF = "Generic data structures library in C"
+PROJECT_BRIEF = "C Generic Data Structures library"
# With the PROJECT_LOGO tag one can specify an logo or icon that is
# included in the documentation. The maximum height of the logo should not
-all: latex/refman.pdf
+all: html latex
-latex/refman.pdf:
+html:
doxygen Doxyfile
+
+latex: html
cd latex && pdflatex refman.tex && pdflatex refman.tex && cd ..
clean:
rm -rf html latex
-.PHONY: latex/refman.pdf clean
+.PHONY: latex html clean
BufferTop* _buffertop_new(size_t dataSize, UInt capacity, OrderType bType, UInt arity)
{
- BufferTop* bufferTop = (BufferTop*) safe_malloc(sizeof (BufferTop));
- bufferTop->capacity = capacity;
- bufferTop->bType = bType; //redondant, but facilitate understanding
- // WARNING: heap must have opposite type: "smallest" element first
- bufferTop->heap = _heap_new(dataSize, (bType == MAX_T ? MIN_T : MAX_T), arity);
- return bufferTop;
+ BufferTop* bufferTop = (BufferTop*) safe_malloc(sizeof (BufferTop));
+ bufferTop->capacity = capacity;
+ bufferTop->bType = bType; //redondant, but facilitate understanding
+ // WARNING: heap must have opposite type: "smallest" element first
+ bufferTop->heap = _heap_new(dataSize, (bType == MAX_T ? MIN_T : MAX_T), arity);
+ return bufferTop;
}
BufferTop* buffertop_copy(BufferTop* bufferTop)
{
- BufferTop* bufferTopCopy = _buffertop_new(
- bufferTop->heap->dataSize, bufferTop->capacity,
- bufferTop->heap->hType, bufferTop->heap->arity);
- heap_destroy(bufferTopCopy->heap); //TODO: bad style...
- bufferTopCopy->heap = heap_copy(bufferTop->heap);
- return bufferTopCopy;
+ BufferTop* bufferTopCopy = _buffertop_new(
+ bufferTop->heap->dataSize, bufferTop->capacity,
+ bufferTop->heap->hType, bufferTop->heap->arity);
+ heap_destroy(bufferTopCopy->heap); //TODO: bad style...
+ bufferTopCopy->heap = heap_copy(bufferTop->heap);
+ return bufferTopCopy;
}
List* buffertop_2list(BufferTop* bufferTop)
{
- // Copy the buffer, and then use the copy to build the list
- BufferTop* bufferTopCopy = buffertop_copy(bufferTop);
- List* bufferInList = _list_new(bufferTop->heap->array->dataSize);
- while (!buffertop_empty(bufferTopCopy))
- {
- void* topItem = buffertop_first_raw(bufferTopCopy)->item;
- // NOTE: list_insert_front(), to reverse (wrong) items order
- // ==> in the returned list, top element is at head.
- _list_insert_front(bufferInList, topItem);
- buffertop_pop(bufferTopCopy);
- }
- buffertop_destroy(bufferTopCopy);
- return bufferInList;
+ // Copy the buffer, and then use the copy to build the list
+ BufferTop* bufferTopCopy = buffertop_copy(bufferTop);
+ List* bufferInList = _list_new(bufferTop->heap->array->dataSize);
+ while (!buffertop_empty(bufferTopCopy))
+ {
+ void* topItem = buffertop_first_raw(bufferTopCopy)->item;
+ // NOTE: list_insert_front(), to reverse (wrong) items order
+ // ==> in the returned list, top element is at head.
+ _list_insert_front(bufferInList, topItem);
+ buffertop_pop(bufferTopCopy);
+ }
+ buffertop_destroy(bufferTopCopy);
+ return bufferInList;
}
bool buffertop_empty(BufferTop* bufferTop)
{
- return (heap_size(bufferTop->heap) == 0);
+ return (heap_size(bufferTop->heap) == 0);
}
UInt buffertop_size(BufferTop* bufferTop)
{
- return heap_size(bufferTop->heap);
+ return heap_size(bufferTop->heap);
}
void _buffertop_tryadd(BufferTop* bufferTop, void* item, Real value)
{
- if (heap_size(bufferTop->heap) >= bufferTop->capacity &&
- ((bufferTop->bType == MIN_T &&
- value >= ((ItemValue*) (bufferTop->heap->array->datas[0]))->value)
- ||
- (bufferTop->bType == MAX_T &&
- value <= ((ItemValue*) (bufferTop->heap->array->datas[0]))->value)))
- {
- // shortcut : if value "worse" than top->value and buffer is full, skip
- return;
- }
+ if (heap_size(bufferTop->heap) >= bufferTop->capacity &&
+ ((bufferTop->bType == MIN_T &&
+ value >= ((ItemValue*) (bufferTop->heap->array->datas[0]))->value)
+ ||
+ (bufferTop->bType == MAX_T &&
+ value <= ((ItemValue*) (bufferTop->heap->array->datas[0]))->value)))
+ {
+ // shortcut : if value "worse" than top->value and buffer is full, skip
+ return;
+ }
- // insertion somewhere in the item-values heap
- _heap_insert(bufferTop->heap, item, value);
+ // insertion somewhere in the item-values heap
+ _heap_insert(bufferTop->heap, item, value);
- if (heap_size(bufferTop->heap) > bufferTop->capacity)
- // we must remove current root
- heap_pop(bufferTop->heap);
+ if (heap_size(bufferTop->heap) > bufferTop->capacity)
+ // we must remove current root
+ heap_pop(bufferTop->heap);
}
ItemValue* buffertop_first_raw(BufferTop* bufferTop)
{
- return heap_top_raw(bufferTop->heap);
+ return heap_top_raw(bufferTop->heap);
}
void buffertop_pop(BufferTop* bufferTop)
{
- heap_pop(bufferTop->heap);
+ heap_pop(bufferTop->heap);
}
void buffertop_clear(BufferTop* bufferTop)
{
- heap_clear(bufferTop->heap);
+ heap_clear(bufferTop->heap);
}
void buffertop_destroy(BufferTop* bufferTop)
{
- heap_destroy(bufferTop->heap);
- safe_free(bufferTop);
+ heap_destroy(bufferTop->heap);
+ safe_free(bufferTop);
}
* @brief Data structure to store top (MAX or MIN) elements in a buffer.
*/
typedef struct BufferTop {
- UInt capacity; ///< Buffer capacity (in items count).
- OrderType bType; ///< Type of buffer: keep max or min items (MAX_T or MIN_T).
- Heap* heap; ///< Item-ValueS are internally organized into a heap.
+ UInt capacity; ///< Buffer capacity (in items count).
+ OrderType bType; ///< Type of buffer: keep max or min items (MAX_T or MIN_T).
+ Heap* heap; ///< Item-ValueS are internally organized into a heap.
} BufferTop;
/**
* @brief Return an allocated and initialized buffer.
*/
BufferTop* _buffertop_new(
- size_t dataSize, ///< Size in bytes of a buffer element.
- UInt capacity, ///< Maximum number of elements that the buffer can contain.
- OrderType bType, ///< Type of buffer: keep max or min items (MAX_T or MIN_T).
- UInt arity ///< Arity of the wrapped heap: any integer >=2.
+ size_t dataSize, ///< Size in bytes of a buffer element.
+ UInt capacity, ///< Maximum number of elements that the buffer can contain.
+ OrderType bType, ///< Type of buffer: keep max or min items (MAX_T or MIN_T).
+ UInt arity ///< Arity of the wrapped heap: any integer >=2.
);
/**
* @param bType type of buffer: keep max or min items (MAX_T or MIN_T).
* @param arity Arity of the wrapped heap: any integer >=2.
*
- * Usage: BufferTop* buffertop_new(\
- * <Type> type, UInt capacity, OrderTypebType, UInt arity)
+ * Usage: BufferTop* buffertop_new(<Type> type, UInt capacity, OrderTypebType, UInt arity)
*/
#define buffertop_new(type, capacity, bType, arity) \
- _buffertop_new(sizeof(type), capacity, bType, arity)
+{ \
+ _buffertop_new(sizeof(type), capacity, bType, arity); \
+}
/**
* @brief Copy constructor (shallow copy, ok for basic types).
*/
BufferTop* buffertop_copy(
- BufferTop* bufferTop ///< "this" pointer.
+ BufferTop* bufferTop ///< "this" pointer.
);
/**
* @brief Turn the buffer into a list to scan its content linearly.
*/
List* buffertop_2list(
- BufferTop* bufferTop ///< "this" pointer.
+ BufferTop* bufferTop ///< "this" pointer.
);
/**
* @brief Check if the buffer is empty.
*/
bool buffertop_empty(
- BufferTop* bufferTop ///< "this" pointer.
+ BufferTop* bufferTop ///< "this" pointer.
);
/**
* @brief Return the size of current buffer (<= capacity).
*/
UInt buffertop_size(
- BufferTop* bufferTop ///< "this" pointer.
+ BufferTop* bufferTop ///< "this" pointer.
);
/**
* @brief (Try to) add an item-value in the buffer.
*/
void _buffertop_tryadd(
- BufferTop* bufferTop, ///< "this" pointer.
- void* item, ///< Pointer to an item of type as defined in the constructor.
- Real value ///< Value associated with the item.
+ BufferTop* bufferTop, ///< "this" pointer.
+ void* item, ///< Pointer to an item of type as defined in the constructor.
+ Real value ///< Value associated with the item.
);
/**
*/
#define buffertop_tryadd(bufferTop, item, value) \
{ \
- typeof((item)) tmp = item; \
- _buffertop_tryadd(bufferTop, &tmp, value); \
+ typeof((item)) tmp = item; \
+ _buffertop_tryadd(bufferTop, &tmp, value); \
}
/**
* @brief Return the top ("worst among best") ItemValue inside current buffer.
*/
ItemValue* buffertop_first_raw(
- BufferTop* bufferTop ///< "this" pointer.
+ BufferTop* bufferTop ///< "this" pointer.
);
/**
*/
#define buffertop_first(bufferTop, item_) \
{ \
- void* pItem = buffertop_first_raw(bufferTop)->item; \
- item_ = *((typeof(&item_))pItem); \
+ void* pItem = buffertop_first_raw(bufferTop)->item; \
+ item_ = *((typeof(&item_))pItem); \
}
/**
* @brief Remove the top ("worst among best") item-value inside the buffer.
*/
void buffertop_pop(
- BufferTop* bufferTop ///< "this" pointer.
+ BufferTop* bufferTop ///< "this" pointer.
);
/**
* @brief Clear the entire buffer.
*/
void buffertop_clear(
- BufferTop* bufferTop ///< "this" pointer.
+ BufferTop* bufferTop ///< "this" pointer.
);
/**
* @brief Destroy the buffer: clear it, and free 'bufferTop' pointer.
*/
void buffertop_destroy(
- BufferTop* bufferTop ///< "this" pointer.
+ BufferTop* bufferTop ///< "this" pointer.
);
#endif
void _hashtable_init(HashTable* hashTable, size_t dataSize, size_t hashSize)
{
- hashTable->hashSize = hashSize;
+ hashTable->hashSize = hashSize;
hashTable->dataSize = dataSize;
- hashTable->head = safe_malloc(hashSize * sizeof(HashCell*));
- for (UInt i = 0; i < hashSize; i++)
+ hashTable->head = safe_malloc(hashSize * sizeof(HashCell*));
+ for (UInt i = 0; i < hashSize; i++)
hashTable->head[i] = NULL;
hashTable->size = 0;
}
HashTable* _hashtable_new(size_t dataSize, size_t hashSize)
{
- HashTable* hashTable = (HashTable*) safe_malloc(sizeof (HashTable));
- _hashtable_init(hashTable, dataSize, hashSize);
- return hashTable;
+ HashTable* hashTable = (HashTable*) safe_malloc(sizeof (HashTable));
+ _hashtable_init(hashTable, dataSize, hashSize);
+ return hashTable;
}
HashTable* hashtable_copy(HashTable* hashTable)
{
- HashTable* hashTableCopy =
+ HashTable* hashTableCopy =
_hashtable_new(hashTable->dataSize, hashTable->hashSize);
- hashTableCopy->size = hashTable->size;
+ hashTableCopy->size = hashTable->size;
for (UInt i = 0; i < hashTable->hashSize; i++)
- {
+ {
HashCell *cell = hashTable->head[i],
*cellCopy = hashTableCopy->head[i],
*prev = NULL;
{
// cellCopy == NULL (from empty list)
cellCopy = (HashCell*) safe_malloc(sizeof(HashCell*));
- cellCopy->key = (char*) safe_malloc(strlen(cell->key) + 1);
+ cellCopy->key = (char*) safe_malloc(strlen(cell->key) + 1);
strcpy(cellCopy->key, cell->key);
- cellCopy->data = safe_malloc(hashTable->dataSize);
- memcpy(cellCopy->data, cell->data, hashTable->dataSize);
+ cellCopy->data = safe_malloc(hashTable->dataSize);
+ memcpy(cellCopy->data, cell->data, hashTable->dataSize);
if (prev == NULL) hashTableCopy->head[i] = cellCopy;
else prev->next = cellCopy;
prev = cellCopy;
cell = cell->next;
}
if (cellCopy != NULL) cellCopy->next = NULL;
- }
- return hashTableCopy;
+ }
+ return hashTableCopy;
}
bool hashtable_empty(HashTable* hashTable)
{
- return (hashTable->size == 0);
+ return (hashTable->size == 0);
}
UInt hashtable_size(HashTable* hashTable)
{
- return hashTable->size;
+ return hashTable->size;
}
// Function (string) key --> (integer) hash [internal usage]
void hashtable_clear(HashTable* hashTable)
{
- for (UInt i = 0; i < hashTable->hashSize; i++)
+ for (UInt i = 0; i < hashTable->hashSize; i++)
{
HashCell* cell = hashTable->head[i];
while (cell != NULL)
}
hashTable->head[i] = NULL;
}
- hashTable->size = 0;
+ hashTable->size = 0;
}
void hashtable_destroy(HashTable* hashTable)
{
- hashtable_clear(hashTable);
- safe_free(hashTable->head);
+ hashtable_clear(hashTable);
+ safe_free(hashTable->head);
safe_free(hashTable);
}
* @brief Cell of a dictionary.
*/
typedef struct HashCell {
- char* key; ///< Key (as a string).
+ char* key; ///< Key (as a string).
void* data; ///< Generic data contained in this cell.
- struct HashCell* next; ///< Pointer to next cell in the list.
+ struct HashCell* next; ///< Pointer to next cell in the list.
} HashCell;
/**
*/
typedef struct HashTable {
UInt size; ///< Count elements in the dictionary.
- size_t dataSize; ///< Size of a dict cell element in bytes.
+ size_t dataSize; ///< Size of a dict cell element in bytes.
size_t hashSize; ///< (Maximum) Number of stored hash keys.
- HashCell** head; ///< Pointers to the first cell in a list.
+ HashCell** head; ///< Pointers to the first cell in a list.
} HashTable;
/**
* @brief Initialize an empty dictionary.
*/
void _hashtable_init(
- HashTable* hashTable, ///< "this" pointer.
- size_t dataSize, ///< Size in bytes of a dictionary element.
+ HashTable* hashTable, ///< "this" pointer.
+ size_t dataSize, ///< Size in bytes of a dictionary element.
size_t hashSize ///< (Maximum) Number of stored hash keys.
);
* @brief Return an allocated and initialized dictionary.
*/
HashTable* _hashtable_new(
- size_t dataSize, ///< Size in bytes of a dictionary element.
+ size_t dataSize, ///< Size in bytes of a dictionary element.
size_t hashSize ///< (Maximum) Number of stored hash keys.
);
* Usage: HashTable* hashtable_new(<Type> type, UInt hash_size)
*/
#define hashtable_new(type, hsize) \
- _hashtable_new(sizeof(type), hsize)
+{ \
+ _hashtable_new(sizeof(type), hsize); \
+}
/**
* @brief Copy constructor (shallow copy, ok for basic types).
*/
HashTable* hashtable_copy(
- HashTable* hashTable ///< "this" pointer.
+ HashTable* hashTable ///< "this" pointer.
);
/**
* @brief Check if the dictionary is empty.
*/
bool hashtable_empty(
- HashTable* hastTable ///< "this" pointer.
+ HashTable* hastTable ///< "this" pointer.
);
/**
* @brief Return current size.
*/
UInt hashtable_size(
- HashTable* hastTable ///< "this" pointer.
+ HashTable* hastTable ///< "this" pointer.
);
/**
* @brief Lookup element of given key.
*/
void* _hashtable_get(
- HashTable* hashTable, ///< "this" pointer.
- char* key ///< Key of the element to retrieve.
+ HashTable* hashTable, ///< "this" pointer.
+ char* key ///< Key of the element to retrieve.
);
/**
*/
#define hashtable_get(hashTable, key, data) \
{ \
- void* pData = _hashtable_get(hashTable, key); \
- data = *((typeof(&data))pData); \
+ void* pData = _hashtable_get(hashTable, key); \
+ data = *((typeof(&data))pData); \
}
/**
* @brief Add the entry (key, value) to dictionary.
*/
void _hashtable_set(
- HashTable* hashTable, ///< "this" pointer.
- char* key, ///< Key of the element to add or modify.
- void* data ///< Pointer to new data at given key.
+ HashTable* hashTable, ///< "this" pointer.
+ char* key, ///< Key of the element to add or modify.
+ void* data ///< Pointer to new data at given key.
);
/**
*/
#define hashtable_set(hashTable, key, data) \
{ \
- typeof((data)) tmp = data; \
- _hashtable_set(hashTable, key, &tmp); \
+ typeof((data)) tmp = data; \
+ _hashtable_set(hashTable, key, &tmp); \
}
/**
* @brief Remove the given key (+ associated value).
*/
void hashtable_delete(
- HashTable* hashTable, ///< "this" pointer.
+ HashTable* hashTable, ///< "this" pointer.
char* key ///< Key of the element to delete.
);
* @brief Clear the entire dictionary.
*/
void hashtable_clear(
- HashTable* hashTable ///< "this" pointer.
+ HashTable* hashTable ///< "this" pointer.
);
/**
* @brief Destroy the dictionary: clear it, and free hashes array.
*/
void hashtable_destroy(
- HashTable* hashTable ///< "this" pointer.
+ HashTable* hashTable ///< "this" pointer.
);
#endif
Heap* _heap_new(size_t dataSize, OrderType hType, UInt arity)
{
- Heap* heap = (Heap*)safe_malloc(sizeof(Heap));
- heap->arity = arity;
- heap->hType = hType;
- heap->dataSize = dataSize;
- heap->array = _vector_new(sizeof(ItemValue));
- return heap;
+ Heap* heap = (Heap*)safe_malloc(sizeof(Heap));
+ heap->arity = arity;
+ heap->hType = hType;
+ heap->dataSize = dataSize;
+ heap->array = _vector_new(sizeof(ItemValue));
+ return heap;
}
Heap* heap_copy(Heap* heap)
{
- Heap* heapCopy = _heap_new(heap->dataSize, heap->hType, heap->arity);
- // HACK: vector_copy is not enough,
+ Heap* heapCopy = _heap_new(heap->dataSize, heap->hType, heap->arity);
+ // HACK: vector_copy is not enough,
// since we also have to allocate ItemValue(->item)
- heapCopy->array->size = heap->array->size;
- heapCopy->array->capacity = heap->array->capacity;
- heapCopy->array->datas =
+ heapCopy->array->size = heap->array->size;
+ heapCopy->array->capacity = heap->array->capacity;
+ heapCopy->array->datas =
(void**)safe_malloc(heap->array->capacity*sizeof(void*));
- for (UInt i=0; i<heap->array->size; i++)
- {
- heapCopy->array->datas[i] = safe_malloc(sizeof(ItemValue));
- ItemValue itemValueCopy = (ItemValue){
- .item=safe_malloc(heap->dataSize),
- .value=((ItemValue*)(heap->array->datas[i]))->value};
- memcpy(
+ for (UInt i=0; i<heap->array->size; i++)
+ {
+ heapCopy->array->datas[i] = safe_malloc(sizeof(ItemValue));
+ ItemValue itemValueCopy = (ItemValue){
+ .item=safe_malloc(heap->dataSize),
+ .value=((ItemValue*)(heap->array->datas[i]))->value};
+ memcpy(
itemValueCopy.item,
((ItemValue*)(heap->array->datas[i]))->item,
heap->dataSize);
- memcpy(heapCopy->array->datas[i], &itemValueCopy, sizeof(ItemValue));
- }
- return heapCopy;
+ memcpy(heapCopy->array->datas[i], &itemValueCopy, sizeof(ItemValue));
+ }
+ return heapCopy;
}
bool heap_empty(Heap* heap)
{
- return vector_empty(heap->array);
+ return vector_empty(heap->array);
}
UInt heap_size(Heap* heap)
{
- return vector_size(heap->array);
+ return vector_size(heap->array);
}
// NOTE: [perf] in two following methods, full heap[k] exchanges are
void _heap_bubble_up(Heap* heap, UInt startIndex)
{
- UInt currentIndex = startIndex;
- ItemValue* startItemValue = heap->array->datas[startIndex];
- while (true)
- {
- // get parent
- UInt nextIndex = currentIndex / heap->arity;
- Real nextValue = ((ItemValue*)(heap->array->datas[nextIndex]))->value;
- // compare to parent (if applicable)
- if (currentIndex == 0 ||
- (heap->hType == MIN_T && startItemValue->value >= nextValue) ||
- (heap->hType == MAX_T && startItemValue->value <= nextValue))
- {
- // moving element has landed: apply final affectation
- heap->array->datas[currentIndex] = startItemValue;
- break;
- }
- // move one level up: the parent goes one level down
- heap->array->datas[currentIndex] = heap->array->datas[nextIndex];
- currentIndex = nextIndex;
- }
+ UInt currentIndex = startIndex;
+ ItemValue* startItemValue = heap->array->datas[startIndex];
+ while (true)
+ {
+ // get parent
+ UInt nextIndex = currentIndex / heap->arity;
+ Real nextValue = ((ItemValue*)(heap->array->datas[nextIndex]))->value;
+ // compare to parent (if applicable)
+ if (currentIndex == 0 ||
+ (heap->hType == MIN_T && startItemValue->value >= nextValue) ||
+ (heap->hType == MAX_T && startItemValue->value <= nextValue))
+ {
+ // moving element has landed: apply final affectation
+ heap->array->datas[currentIndex] = startItemValue;
+ break;
+ }
+ // move one level up: the parent goes one level down
+ heap->array->datas[currentIndex] = heap->array->datas[nextIndex];
+ currentIndex = nextIndex;
+ }
}
void _heap_bubble_down(Heap* heap, UInt startIndex)
{
- UInt currentIndex = startIndex;
- ItemValue* startItemValue = heap->array->datas[startIndex];
- while (true)
- {
- if (currentIndex * heap->arity >= heap->array->size)
- {
- // moving element has landed (in a leaf): apply final affectation
- heap->array->datas[currentIndex] = startItemValue;
- break;
- }
- // find top child (min or max)
- UInt topChildIndex;
- Real topChildValue = (heap->hType == MIN_T ? INFINITY : -INFINITY);
- for (Int i=0; i<heap->arity; i++)
- {
- UInt childIndex = i + currentIndex * heap->arity;
- if (childIndex >= heap->array->size)
- break;
- Real childValue = ((ItemValue*)(heap->array->datas[childIndex]))->value;
- if ((heap->hType == MIN_T && childValue < topChildValue) ||
- (heap->hType == MAX_T && childValue > topChildValue))
- {
- topChildIndex = childIndex;
- topChildValue = childValue;
- }
- }
- // compare to top child
- if ((heap->hType == MIN_T && startItemValue->value > topChildValue) ||
- (heap->hType == MAX_T && startItemValue->value < topChildValue))
- {
- // move one level down: the child goes one level up
- heap->array->datas[currentIndex] = heap->array->datas[topChildIndex];
- }
- else
- {
- // moving element has landed: apply final affectation
- heap->array->datas[currentIndex] = startItemValue;
- break;
- }
- currentIndex = topChildIndex;
- }
+ UInt currentIndex = startIndex;
+ ItemValue* startItemValue = heap->array->datas[startIndex];
+ while (true)
+ {
+ if (currentIndex * heap->arity >= heap->array->size)
+ {
+ // moving element has landed (in a leaf): apply final affectation
+ heap->array->datas[currentIndex] = startItemValue;
+ break;
+ }
+ // find top child (min or max)
+ UInt topChildIndex;
+ Real topChildValue = (heap->hType == MIN_T ? INFINITY : -INFINITY);
+ for (Int i=0; i<heap->arity; i++)
+ {
+ UInt childIndex = i + currentIndex * heap->arity;
+ if (childIndex >= heap->array->size)
+ break;
+ Real childValue = ((ItemValue*)(heap->array->datas[childIndex]))->value;
+ if ((heap->hType == MIN_T && childValue < topChildValue) ||
+ (heap->hType == MAX_T && childValue > topChildValue))
+ {
+ topChildIndex = childIndex;
+ topChildValue = childValue;
+ }
+ }
+ // compare to top child
+ if ((heap->hType == MIN_T && startItemValue->value > topChildValue) ||
+ (heap->hType == MAX_T && startItemValue->value < topChildValue))
+ {
+ // move one level down: the child goes one level up
+ heap->array->datas[currentIndex] = heap->array->datas[topChildIndex];
+ }
+ else
+ {
+ // moving element has landed: apply final affectation
+ heap->array->datas[currentIndex] = startItemValue;
+ break;
+ }
+ currentIndex = topChildIndex;
+ }
}
void _heap_insert(Heap* heap, void* item, Real value)
{
- ItemValue itemValue =
+ ItemValue itemValue =
(ItemValue){.item=safe_malloc(heap->dataSize), .value=value};
- memcpy(itemValue.item, item, heap->dataSize);
- _vector_push(heap->array, &itemValue);
- _heap_bubble_up(heap, heap->array->size-1);
+ memcpy(itemValue.item, item, heap->dataSize);
+ _vector_push(heap->array, &itemValue);
+ _heap_bubble_up(heap, heap->array->size-1);
}
void _heap_modify(Heap* heap, UInt index, Real newValue)
{
- double oldValue = ((ItemValue*)(heap->array->datas[index]))->value;
- ((ItemValue*)(heap->array->datas[index]))->value = newValue;
- if ((heap->hType == MIN_T && newValue > oldValue) ||
- (heap->hType == MAX_T && newValue < oldValue))
- {
- _heap_bubble_down(heap, index);
- }
- else
- _heap_bubble_up(heap, index);
+ double oldValue = ((ItemValue*)(heap->array->datas[index]))->value;
+ ((ItemValue*)(heap->array->datas[index]))->value = newValue;
+ if ((heap->hType == MIN_T && newValue > oldValue) ||
+ (heap->hType == MAX_T && newValue < oldValue))
+ {
+ _heap_bubble_down(heap, index);
+ }
+ else
+ _heap_bubble_up(heap, index);
}
void _heap_remove(Heap* heap, UInt index)
{
- safe_free(((ItemValue*)(heap->array->datas[index]))->item);
- ItemValue* tmp = heap->array->datas[index];
- heap->array->datas[index] = heap->array->datas[heap_size(heap)-1];
- heap->array->datas[heap_size(heap)-1] = tmp;
- vector_pop(heap->array);
- if (heap->array->size > 0)
- _heap_bubble_down(heap, index);
+ safe_free(((ItemValue*)(heap->array->datas[index]))->item);
+ ItemValue* tmp = heap->array->datas[index];
+ heap->array->datas[index] = heap->array->datas[heap_size(heap)-1];
+ heap->array->datas[heap_size(heap)-1] = tmp;
+ vector_pop(heap->array);
+ if (heap->array->size > 0)
+ _heap_bubble_down(heap, index);
}
ItemValue* heap_top_raw(Heap* heap)
{
- return (ItemValue*)(heap->array->datas[0]);
+ return (ItemValue*)(heap->array->datas[0]);
}
void heap_pop(Heap* heap)
{
- _heap_remove(heap, 0);
+ _heap_remove(heap, 0);
}
void heap_clear(Heap* heap)
{
- for (UInt i = 0; i < heap->array->size; i++)
- {
- // Extra memory releases which wouldn't be done in vector_clear()
- safe_free(((ItemValue*)(heap->array->datas[i]))->item);
- //safe_free((ItemValue*)heap->array->datas[i]);
- }
- vector_clear(heap->array);
+ for (UInt i = 0; i < heap->array->size; i++)
+ {
+ // Extra memory releases which wouldn't be done in vector_clear()
+ safe_free(((ItemValue*)(heap->array->datas[i]))->item);
+ //safe_free((ItemValue*)heap->array->datas[i]);
+ }
+ vector_clear(heap->array);
}
void heap_destroy(Heap* heap)
{
- heap_clear(heap);
- safe_free(heap->array);
- safe_free(heap);
+ heap_clear(heap);
+ safe_free(heap->array);
+ safe_free(heap);
}
* @brief Generic d-ary heap.
*/
typedef struct Heap {
- size_t dataSize; ///< Size of a heap item in bytes.
- OrderType hType; ///< Type of heap: max first (MAX_T) or min first (MIN_T).
- UInt arity; ///< Arity of the underlying tree.
- Vector* array; ///< Vector of ItemValue* (internal representation).
+ size_t dataSize; ///< Size of a heap item in bytes.
+ OrderType hType; ///< Type of heap: max first (MAX_T) or min first (MIN_T).
+ UInt arity; ///< Arity of the underlying tree.
+ Vector* array; ///< Vector of ItemValue* (internal representation).
} Heap;
/**
* @brief Return an allocated and initialized heap.
*/
Heap* _heap_new(
- size_t dataSize, ///< Size in bytes of a heap element.
- OrderType hType, ///< Type of heap: max first (MAX_T) or min first (MIN_T).
- UInt arity ///< Arity of the underlying tree.
+ size_t dataSize, ///< Size in bytes of a heap element.
+ OrderType hType, ///< Type of heap: max first (MAX_T) or min first (MIN_T).
+ UInt arity ///< Arity of the underlying tree.
);
/**
* Usage: Heap* heap_new(<Type> type, OrderType hType, UInt arity)
*/
#define heap_new(type, hType, arity) \
- _heap_new(sizeof(type), hType, arity)
+{ \
+ _heap_new(sizeof(type), hType, arity); \
+}
/**
* @brief Copy constructor (shallow copy, ok for basic types).
*/
Heap* heap_copy(
- Heap* heap ///< "this" pointer.
+ Heap* heap ///< "this" pointer.
);
/**
* @brief Check if the heap is empty.
*/
bool heap_empty(
- Heap* heap ///< "this" pointer.
+ Heap* heap ///< "this" pointer.
);
/**
* @brief Return the size of current heap.
*/
UInt heap_size(
- Heap* heap ///< "this" pointer.
+ Heap* heap ///< "this" pointer.
);
/**
* in O(log(n)) operations.
*/
void _heap_bubble_up(
- Heap* heap, ///< "this" pointer.
- UInt startIndex ///< Index to bubble up.
+ Heap* heap, ///< "this" pointer.
+ UInt startIndex ///< Index to bubble up.
);
/**
* in O(log(n)) operations.
*/
void _heap_bubble_down(
- Heap* heap, ///< "this" pointer.
- UInt startIndex ///< Index to bubble down.
+ Heap* heap, ///< "this" pointer.
+ UInt startIndex ///< Index to bubble down.
);
/**
* @brief Insert a pair (item,value) inside the heap.
*/
void _heap_insert(
- Heap* heap, ///< "this" pointer.
- void* item, ///< Pointer to an item of type as defined in the constructor.
- Real value ///< Value associated with the item.
+ Heap* heap, ///< "this" pointer.
+ void* item, ///< Pointer to an item of type as defined in the constructor.
+ Real value ///< Value associated with the item.
);
/**
*/
#define heap_insert(heap, item, value) \
{ \
- typeof((item)) tmp = item; \
- _heap_insert(heap, &tmp, value); \
+ typeof((item)) tmp = item; \
+ _heap_insert(heap, &tmp, value); \
}
/**
* @brief Change the value of an item at a given index.
*/
void _heap_modify(
- Heap* heap, ///< "this" pointer.
- UInt index, ///< Index of the item to modify.
- Real newValue ///< New value for the item.
+ Heap* heap, ///< "this" pointer.
+ UInt index, ///< Index of the item to modify.
+ Real newValue ///< New value for the item.
);
/**
* @note If several similar items are present, only the first is affected.
*
* Usage: void heap_modify(Heap* heap, void item_, Real newValue)
+ *
* WARNING: does not work if items are not basic type nor pointers.
*/
#define heap_modify(heap, item_, newValue) \
{ \
- UInt index = 0; \
- typeof((item_)) item__ = item_; \
- for (; index<heap->array->size; index++) \
- { \
- void* pItem = ((ItemValue*)(heap->array->datas[index]))->item; \
- if (*((typeof(&item__))pItem) == item__) break; \
- } \
- _heap_modify(heap, index, newValue); \
+ UInt index = 0; \
+ typeof((item_)) item__ = item_; \
+ for (; index<heap->array->size; index++) \
+ { \
+ void* pItem = ((ItemValue*)(heap->array->datas[index]))->item; \
+ if (*((typeof(&item__))pItem) == item__) break; \
+ } \
+ _heap_modify(heap, index, newValue); \
}
/**
* @brief Remove an item-value at a given index.
*/
void _heap_remove(
- Heap* heap, ///< "this" pointer.
- UInt index ///< Index of the item to remove.
+ Heap* heap, ///< "this" pointer.
+ UInt index ///< Index of the item to remove.
);
/**
* @note If several similar items are present, only the first is deleted.
*
* Usage: void heap_remove(Heap* heap, void item_)
+ *
* WARNING: does not work if items are not basic type nor pointers.
*/
#define heap_remove(heap, item_) \
{ \
- UInt index = 0; \
- typeof((item_)) item__ = item_; \
- for (; index<heap->array->size; index++) \
- { \
- void* pItem = ((ItemValue*)(heap->array->datas[index]))->item; \
- if (*((typeof(&item__))pItem) == item__) break; \
- } \
- _heap_remove(heap, index); \
+ UInt index = 0; \
+ typeof((item_)) item__ = item_; \
+ for (; index<heap->array->size; index++) \
+ { \
+ void* pItem = ((ItemValue*)(heap->array->datas[index]))->item; \
+ if (*((typeof(&item__))pItem) == item__) break; \
+ } \
+ _heap_remove(heap, index); \
}
/**
* @brief Return what is at the beginning of the heap.
*/
ItemValue* heap_top_raw(
- Heap* heap ///< "this" pointer.
+ Heap* heap ///< "this" pointer.
);
/**
*/
#define heap_top(heap, item_) \
{ \
- void* pItem = heap_top_raw(heap)->item; \
- item_ = *((typeof(&item_))pItem); \
+ void* pItem = heap_top_raw(heap)->item; \
+ item_ = *((typeof(&item_))pItem); \
}
/**
* @brief Remove the top of the heap.
*/
void heap_pop(
- Heap* heap ///< "this" pointer.
+ Heap* heap ///< "this" pointer.
);
/**
* @brief Clear the entire heap.
*/
void heap_clear(
- Heap* heap ///< "this" pointer.
+ Heap* heap ///< "this" pointer.
);
/**
* @brief Destroy the heap: clear it, and free 'heap' pointer.
*/
void heap_destroy(
- Heap* heap ///< "this" pointer.
+ Heap* heap ///< "this" pointer.
);
#endif
void _list_init(List* list, size_t dataSize)
{
- list->size = 0;
- list->dataSize = dataSize;
- list->head = NULL;
- list->tail = NULL;
+ list->size = 0;
+ list->dataSize = dataSize;
+ list->head = NULL;
+ list->tail = NULL;
}
List* _list_new(size_t dataSize)
{
- List* list = (List*) safe_malloc(sizeof (List));
- _list_init(list, dataSize);
- return list;
+ List* list = (List*) safe_malloc(sizeof (List));
+ _list_init(list, dataSize);
+ return list;
}
List* list_copy(List* list)
{
- List* listCopy = _list_new(list->dataSize);
- ListCell* listCell = list->head;
- while (listCell != NULL)
- {
- _list_insert_back(listCopy, listCell->data);
- listCell = listCell->next;
- }
- return listCopy;
+ List* listCopy = _list_new(list->dataSize);
+ ListCell* listCell = list->head;
+ while (listCell != NULL)
+ {
+ _list_insert_back(listCopy, listCell->data);
+ listCell = listCell->next;
+ }
+ return listCopy;
}
bool list_empty(List* list)
{
- return (list->size == 0);
+ return (list->size == 0);
}
UInt list_size(List* list)
{
- return list->size;
+ return list->size;
}
void* _list_get(ListCell* listCell)
{
- return listCell->data;
+ return listCell->data;
}
void _list_set(List* list, ListCell* listCell, void* data)
{
- memcpy(listCell->data, data, list->dataSize);
+ memcpy(listCell->data, data, list->dataSize);
}
void _list_insert_first_element(List* list, void* data)
{
- ListCell* newListCell = (ListCell*) safe_malloc(sizeof (ListCell));
- newListCell->data = safe_malloc(list->dataSize);
- memcpy(newListCell->data, data, list->dataSize);
- newListCell->prev = NULL;
- newListCell->next = NULL;
- list->head = newListCell;
- list->tail = newListCell;
- list->size = 1;
+ ListCell* newListCell = (ListCell*) safe_malloc(sizeof (ListCell));
+ newListCell->data = safe_malloc(list->dataSize);
+ memcpy(newListCell->data, data, list->dataSize);
+ newListCell->prev = NULL;
+ newListCell->next = NULL;
+ list->head = newListCell;
+ list->tail = newListCell;
+ list->size = 1;
}
void _list_insert_before(List* list, ListCell* listCell, void* data)
{
- ListCell* newListCell = (ListCell*) safe_malloc(sizeof (ListCell));
- newListCell->data = safe_malloc(list->dataSize);
- memcpy(newListCell->data, data, list->dataSize);
- newListCell->prev = listCell->prev;
- newListCell->next = listCell;
- if (listCell->prev != NULL)
- listCell->prev->next = newListCell;
- else
- list->head = newListCell;
- listCell->prev = newListCell;
- list->size++;
+ ListCell* newListCell = (ListCell*) safe_malloc(sizeof (ListCell));
+ newListCell->data = safe_malloc(list->dataSize);
+ memcpy(newListCell->data, data, list->dataSize);
+ newListCell->prev = listCell->prev;
+ newListCell->next = listCell;
+ if (listCell->prev != NULL)
+ listCell->prev->next = newListCell;
+ else
+ list->head = newListCell;
+ listCell->prev = newListCell;
+ list->size++;
}
void _list_insert_after(List* list, ListCell* listCell, void* data)
{
- ListCell* newListCell = (ListCell*) safe_malloc(sizeof (ListCell));
- newListCell->data = safe_malloc(list->dataSize);
- memcpy(newListCell->data, data, list->dataSize);
- newListCell->prev = listCell;
- newListCell->next = listCell->next;
- if (listCell->next != NULL)
- listCell->next->prev = newListCell;
- else
- list->tail = newListCell;
- listCell->next = newListCell;
- list->size++;
+ ListCell* newListCell = (ListCell*) safe_malloc(sizeof (ListCell));
+ newListCell->data = safe_malloc(list->dataSize);
+ memcpy(newListCell->data, data, list->dataSize);
+ newListCell->prev = listCell;
+ newListCell->next = listCell->next;
+ if (listCell->next != NULL)
+ listCell->next->prev = newListCell;
+ else
+ list->tail = newListCell;
+ listCell->next = newListCell;
+ list->size++;
}
void _list_insert_front(List* list, void* data)
{
- if (list->head != NULL)
- _list_insert_before(list, list->head, data);
- else
- _list_insert_first_element(list, data);
+ if (list->head != NULL)
+ _list_insert_before(list, list->head, data);
+ else
+ _list_insert_first_element(list, data);
}
void _list_insert_back(List* list, void* data)
{
- if (list->tail != NULL)
- _list_insert_after(list, list->tail, data);
- else
- _list_insert_first_element(list, data);
+ if (list->tail != NULL)
+ _list_insert_after(list, list->tail, data);
+ else
+ _list_insert_first_element(list, data);
}
void list_remove(List* list, ListCell* listCell)
{
- if (listCell->prev != NULL)
- listCell->prev->next = listCell->next;
- else
- list->head = listCell->next;
- if (listCell->next != NULL)
- listCell->next->prev = listCell->prev;
- else
- list->tail = listCell->prev;
- safe_free(listCell->data);
- safe_free(listCell);
- list->size--;
+ if (listCell->prev != NULL)
+ listCell->prev->next = listCell->next;
+ else
+ list->head = listCell->next;
+ if (listCell->next != NULL)
+ listCell->next->prev = listCell->prev;
+ else
+ list->tail = listCell->prev;
+ safe_free(listCell->data);
+ safe_free(listCell);
+ list->size--;
}
void list_remove_front(List* list)
{
- list_remove(list, list->head);
+ list_remove(list, list->head);
}
void list_remove_back(List* list)
{
- list_remove(list, list->tail);
+ list_remove(list, list->tail);
}
void list_clear(List* list)
{
- ListCell* current = list->head;
- while (current != NULL)
- {
- safe_free(current->data);
- ListCell* nextListCell = current->next;
- safe_free(current);
- current = nextListCell;
- }
- _list_init(list, list->dataSize);
+ ListCell* current = list->head;
+ while (current != NULL)
+ {
+ safe_free(current->data);
+ ListCell* nextListCell = current->next;
+ safe_free(current);
+ current = nextListCell;
+ }
+ _list_init(list, list->dataSize);
}
void list_destroy(List* list)
{
- list_clear(list);
- safe_free(list);
+ list_clear(list);
+ safe_free(list);
}
////////////////////
ListIterator* list_get_iterator(List* list)
{
- ListIterator* listI = (ListIterator*) safe_malloc(sizeof (ListIterator));
- listI->list = list;
- listI->current = NULL;
- listI_reset_head(listI);
- return listI;
+ ListIterator* listI = (ListIterator*) safe_malloc(sizeof (ListIterator));
+ listI->list = list;
+ listI->current = NULL;
+ listI_reset_head(listI);
+ return listI;
}
void listI_reset_head(ListIterator* listI)
{
- listI->current = listI->list->head;
+ listI->current = listI->list->head;
}
void listI_reset_tail(ListIterator* listI)
{
- listI->current = listI->list->tail;
+ listI->current = listI->list->tail;
}
bool listI_has_data(ListIterator* listI)
{
- return (listI->current != NULL);
+ return (listI->current != NULL);
}
void listI_remove(ListIterator* listI, Direction direction)
{
- ListCell* toTrash = listI->current;
- switch (direction)
- {
- case FORWARD:
- listI->current = listI->current->next;
- break;
- case BACKWARD:
- listI->current = listI->current->prev;
- break;
- }
- list_remove(listI->list, toTrash);
+ ListCell* toTrash = listI->current;
+ switch (direction)
+ {
+ case FORWARD:
+ listI->current = listI->current->next;
+ break;
+ case BACKWARD:
+ listI->current = listI->current->prev;
+ break;
+ }
+ list_remove(listI->list, toTrash);
}
void listI_move_next(ListIterator* listI)
{
- if (listI->current != NULL)
- listI->current = listI->current->next;
+ if (listI->current != NULL)
+ listI->current = listI->current->next;
}
void listI_move_prev(ListIterator* listI)
{
- if (listI->current != NULL)
- listI->current = listI->current->prev;
+ if (listI->current != NULL)
+ listI->current = listI->current->prev;
}
void listI_destroy(ListIterator* listI)
{
- safe_free(listI);
+ safe_free(listI);
}
* @brief Cell of a double-linked list.
*/
typedef struct ListCell {
- void* data; ///< Generic data contained in this cell.
- struct ListCell* prev; ///< Pointer to previous cell in the list.
- struct ListCell* next; ///< Pointer to next cell in the list.
+ void* data; ///< Generic data contained in this cell.
+ struct ListCell* prev; ///< Pointer to previous cell in the list.
+ struct ListCell* next; ///< Pointer to next cell in the list.
} ListCell;
/**
* @brief Double-linked list data structure.
*/
typedef struct List {
- UInt size; ///< Count elements in the list.
- size_t dataSize; ///< Size of a list cell element in bytes.
- ListCell* head; ///< Pointer to the first cell in the list.
- ListCell* tail; ///< Pointer to the last cell in the list.
+ UInt size; ///< Count elements in the list.
+ size_t dataSize; ///< Size of a list cell element in bytes.
+ ListCell* head; ///< Pointer to the first cell in the list.
+ ListCell* tail; ///< Pointer to the last cell in the list.
} List;
/**
* @brief Initialize an empty list.
*/
void _list_init(
- List* list, ///< "this" pointer.
- size_t dataSize ///< Size of a list cell elements in bytes.
+ List* list, ///< "this" pointer.
+ size_t dataSize ///< Size of a list cell elements in bytes.
);
/**
* @param dataSize Size in bytes of a list element.
*/
List* _list_new(
- size_t dataSize ///< Size of a list cell elements in bytes.
+ size_t dataSize ///< Size of a list cell elements in bytes.
);
/**
* Usage: List* list_new(<Type> type)
*/
#define list_new(type) \
- _list_new(sizeof(type))
+{ \
+ _list_new(sizeof(type)); \
+}
/**
* @brief Copy constructor (shallow copy, ok for basic types).
*/
List* list_copy(
- List* list ///< "this" pointer.
+ List* list ///< "this" pointer.
);
/**
* @brief Check if the list is empty.
*/
bool list_empty(
- List* list ///< "this" pointer.
+ List* list ///< "this" pointer.
);
/**
* @brief return the size of current list.
*/
UInt list_size(
- List* list ///< "this" pointer.
+ List* list ///< "this" pointer.
);
/**
* @brief Get data at the given list cell argument.
*/
void* _list_get(
- ListCell* listCell ///< Pointer to a cell inside "this" list.
+ ListCell* listCell ///< Pointer to a cell inside "this" list.
);
/**
*/
#define list_get(listCell, data) \
{ \
- void* pData = _list_get(listCell); \
- data = *((typeof(&data))pData); \
+ void* pData = _list_get(listCell); \
+ data = *((typeof(&data))pData); \
}
/**
* @brief Set data at the given list cell argument.
*/
void _list_set(
- List* list, ///< "this" pointer.
- ListCell* listCell, ///< Pointer to a cell inside "this" list.
- void* data ///< Pointer to data to be set.
+ List* list, ///< "this" pointer.
+ ListCell* listCell, ///< Pointer to a cell inside "this" list.
+ void* data ///< Pointer to data to be set.
);
/**
*/
#define list_set(list, listCell, data) \
{ \
- typeof((data)) tmp = data; \
- _list_set(list, listCell, &tmp); \
+ typeof((data)) tmp = data; \
+ _list_set(list, listCell, &tmp); \
}
/**
* @brief Add data to the list when list is empty.
*/
void _list_insert_first_element(
- List* list, ///< "this" pointer.
- void* data ///< Pointer to data to be added
+ List* list, ///< "this" pointer.
+ void* data ///< Pointer to data to be added
);
/**
* @brief Add data before list cell argument.
*/
void _list_insert_before(
- List* list, ///< "this" pointer.
- ListCell* listCell, ///< Pointer to a cell inside "this" list.
- void* data ///< Pointer to data to be added.
+ List* list, ///< "this" pointer.
+ ListCell* listCell, ///< Pointer to a cell inside "this" list.
+ void* data ///< Pointer to data to be added.
);
/**
*/
#define list_insert_before(list, listCell, data) \
{ \
- typeof((data)) tmp = data; \
- _list_insert_before(list, listCell, &tmp); \
+ typeof((data)) tmp = data; \
+ _list_insert_before(list, listCell, &tmp); \
}
/**
* @brief Add data after list cell argument.
*/
void _list_insert_after(
- List* list, ///< "this" pointer.
- ListCell* listCell, ///< Pointer to a cell inside "this" list.
- void* data ///< Pointer to data to be inserted.
+ List* list, ///< "this" pointer.
+ ListCell* listCell, ///< Pointer to a cell inside "this" list.
+ void* data ///< Pointer to data to be inserted.
);
/**
*/
#define list_insert_after(list, listCell, data) \
{ \
- typeof((data)) tmp = data; \
- _list_insert_after(list, listCell, &tmp); \
+ typeof((data)) tmp = data; \
+ _list_insert_after(list, listCell, &tmp); \
}
/**
* @brief Add data at the beginning of the list.
*/
void _list_insert_front(
- List* list, ///< "this" pointer.
- void* data ///< Pointer to data to be inserted.
+ List* list, ///< "this" pointer.
+ void* data ///< Pointer to data to be inserted.
);
/**
*/
#define list_insert_front(list, data) \
{ \
- typeof((data)) tmp = data; \
- _list_insert_front(list, &tmp); \
+ typeof((data)) tmp = data; \
+ _list_insert_front(list, &tmp); \
}
/**
* @brief Add data at the end of the list.
*/
void _list_insert_back(
- List* list, ///< "this" pointer.
- void* data ///< Pointer to data to be inserted.
+ List* list, ///< "this" pointer.
+ void* data ///< Pointer to data to be inserted.
);
/**
*/
#define list_insert_back(list, data) \
{ \
- typeof((data)) tmp = data; \
- _list_insert_back(list, &tmp); \
+ typeof((data)) tmp = data; \
+ _list_insert_back(list, &tmp); \
}
/**
* @brief Remove data at position given by 'listCell'.
*/
void list_remove(
- List* list, ///< "this" pointer.
- ListCell* listCell ///< Pointer to a cell inside "this" list.
+ List* list, ///< "this" pointer.
+ ListCell* listCell ///< Pointer to a cell inside "this" list.
);
/**
* @brief Remove data at the beginning of the list.
*/
void list_remove_front(
- List* list ///< "this" pointer.
+ List* list ///< "this" pointer.
);
/**
* @brief Remove data at the end of the list.
*/
void list_remove_back(
- List* list ///< "this" pointer.
+ List* list ///< "this" pointer.
);
/**
* @brief Clear the entire list.
*/
void list_clear(
- List* list ///< "this" pointer.
+ List* list ///< "this" pointer.
);
/**
* @brief Destroy the list: clear it, and free 'list' pointer.
*/
void list_destroy(
- List* list ///< "this" pointer.
+ List* list ///< "this" pointer.
);
////////////////////
* @brief Iterator on a double-linked list.
*/
typedef struct ListIterator {
- List* list; ///< The list to be iterate.
- ListCell* current; ///< The current iterated list cell.
+ List* list; ///< The list to be iterate.
+ ListCell* current; ///< The current iterated list cell.
} ListIterator;
/**
* @brief Obtain an iterator object, starting at list beginning.
*/
ListIterator* list_get_iterator(
- List* list ///< Pointer to the list to be iterated over.
+ List* list ///< Pointer to the list to be iterated over.
);
/**
* @brief (Re)set current position inside list to head.
*/
void listI_reset_head(
- ListIterator* listI ///< "this" pointer.
+ ListIterator* listI ///< "this" pointer.
);
/**
* @brief (Re)set current position inside list to tail.
*/
void listI_reset_tail(
- ListIterator* listI ///< "this" pointer.
+ ListIterator* listI ///< "this" pointer.
);
/**
* @brief Tell if there is some data at the current index.
*/
bool listI_has_data(
- ListIterator* listI ///< "this" pointer.
+ ListIterator* listI ///< "this" pointer.
);
/**
* Usage: void listI_get(ListIterator* listI, void data)
*/
#define listI_get(listI, data) \
- list_get(listI->current, data)
+ list_get(listI->current, data)
/**
* @brief Set data at the current iterator position.
* Usage: void listI_set(ListIterator* listI, void data);
*/
#define listI_set(listI, data) \
- list_set(listI->list, listI->current, data)
+ list_set(listI->list, listI->current, data)
/**
* @brief Add data before current list cell.
* Usage: void listI_insert_before(ListIteratorI* listI, void data)
*/
#define listI_insert_before(listI, data) \
- list_insert_before(listI->list, listI->current, data)
+ list_insert_before(listI->list, listI->current, data)
/**
* @brief Add data after current list cell.
* Usage: void listI_insert_after(ListIteratorI* listI, void data)
*/
#define listI_insert_after(listI, data) \
- list_insert_after(listI->list, listI->current, data)
+ list_insert_after(listI->list, listI->current, data)
/**
* @brief Type to encode a direction (forward / backward).
*/
typedef enum {
- BACKWARD = -1, ///< Move toward head.
- FORWARD = 1 ///< Move toward tail.
+ BACKWARD = -1, ///< Move toward head.
+ FORWARD = 1 ///< Move toward tail.
} Direction;
/**
* @brief Remove data at the current iterator position.
*/
void listI_remove(
- ListIterator* listI, ///< "this" pointer.
- Direction direction ///< Indicate the position of iterator after removal.
+ ListIterator* listI, ///< "this" pointer.
+ Direction direction ///< Indicate the position of iterator after removal.
);
/**
* @brief Move current iterator position forward (toward tail).
*/
void listI_move_next(
- ListIterator* listI ///< "this" pointer.
+ ListIterator* listI ///< "this" pointer.
);
/**
* @brief Move current iterator position backward (toward head).
*/
void listI_move_prev(
- ListIterator* listI ///< "this" pointer.
+ ListIterator* listI ///< "this" pointer.
);
/**
* @brief Free memory allocated for the iterator.
*/
void listI_destroy(
- ListIterator* listI ///< "this" pointer.
+ ListIterator* listI ///< "this" pointer.
);
#endif
PriorityQueue* _priorityqueue_new(size_t dataSize, OrderType pType, UInt arity)
{
- PriorityQueue* priorityQueue =
+ PriorityQueue* priorityQueue =
(PriorityQueue*) safe_malloc(sizeof (PriorityQueue));
- Heap* heap = _heap_new(dataSize, pType, arity);
- priorityQueue->heap = heap;
- return priorityQueue;
+ Heap* heap = _heap_new(dataSize, pType, arity);
+ priorityQueue->heap = heap;
+ return priorityQueue;
}
PriorityQueue* priorityqueue_copy(PriorityQueue* priorityQueue)
{
- PriorityQueue* priorityQueueCopy = _priorityqueue_new(
- priorityQueue->heap->array->dataSize,
- priorityQueue->heap->hType, priorityQueue->heap->arity);
- heap_destroy(priorityQueueCopy->heap); //TODO: bad style...
- priorityQueueCopy->heap = heap_copy(priorityQueue->heap);
- return priorityQueueCopy;
+ PriorityQueue* priorityQueueCopy = _priorityqueue_new(
+ priorityQueue->heap->array->dataSize,
+ priorityQueue->heap->hType, priorityQueue->heap->arity);
+ heap_destroy(priorityQueueCopy->heap); //TODO: bad style...
+ priorityQueueCopy->heap = heap_copy(priorityQueue->heap);
+ return priorityQueueCopy;
}
bool priorityqueue_empty(PriorityQueue* priorityQueue)
{
- return heap_empty(priorityQueue->heap);
+ return heap_empty(priorityQueue->heap);
}
UInt priorityqueue_size(PriorityQueue* priorityQueue)
{
- return heap_size(priorityQueue->heap);
+ return heap_size(priorityQueue->heap);
}
ItemValue* priorityqueue_peek_raw(PriorityQueue* priorityQueue)
{
- return heap_top_raw(priorityQueue->heap);
+ return heap_top_raw(priorityQueue->heap);
}
void priorityqueue_pop(PriorityQueue* priorityQueue)
{
- heap_pop(priorityQueue->heap);
+ heap_pop(priorityQueue->heap);
}
void priorityqueue_clear(PriorityQueue* priorityQueue)
{
- heap_clear(priorityQueue->heap);
+ heap_clear(priorityQueue->heap);
}
void priorityqueue_destroy(PriorityQueue* priorityQueue)
{
- heap_destroy(priorityQueue->heap);
- safe_free(priorityQueue);
+ heap_destroy(priorityQueue->heap);
+ safe_free(priorityQueue);
}
* @brief Priority queue data structure (wrapper around Heap).
*/
typedef struct PriorityQueue {
- Heap* heap; ///< Internal heap.
+ Heap* heap; ///< Internal heap.
} PriorityQueue;
/**
* @brief Return an allocated and initialized Queue.
*/
PriorityQueue* _priorityqueue_new(
- size_t dataSize, ///< Size in bytes of a priority queue element.
- OrderType pType, ///< Type of priority queue: max or min first (MAX_T or MIN_T).
- UInt arity ///< Arity of the wrapped heap: any integer >=2.
+ size_t dataSize, ///< Size in bytes of a priority queue element.
+ OrderType pType, ///< Type of priority queue: max or min first (MAX_T or MIN_T).
+ UInt arity ///< Arity of the wrapped heap: any integer >=2.
);
/**
* @param pType type of priority queue: max or min first (MAX_T or MIN_T).
* @param arity Arity of the wrapped heap: any integer >=2.
*
- * Usage: PriorityQueue* priorityqueue_new(\
- * <Type> type, OrderType pType, UInt arity)
+ * Usage: PriorityQueue* priorityqueue_new(<Type> type, OrderType pType, UInt arity)
*/
#define priorityqueue_new(type, pType, arity) \
- _priorityqueue_new(sizeof(type), pType, arity)
+{ \
+ _priorityqueue_new(sizeof(type), pType, arity); \
+}
/**
* @brief Copy constructor (shallow copy, ok for basic types).
*/
PriorityQueue* priorityqueue_copy(
- PriorityQueue* priorityQueue ///< "this" pointer.
+ PriorityQueue* priorityQueue ///< "this" pointer.
);
/**
* @brief Check if the priority queue is empty.
*/
bool priorityqueue_empty(
- PriorityQueue* priorityQueue ///< "this" pointer.
+ PriorityQueue* priorityQueue ///< "this" pointer.
);
/**
* @brief Return the size of current priority queue.
*/
UInt priorityqueue_size(
- PriorityQueue* priorityQueue ///< "this" pointer.
+ PriorityQueue* priorityQueue ///< "this" pointer.
);
/**
* @param item Item to be added.
* @param priority Priority of the added item.
*
- * Usage: void priorityqueue_insert(\
- * PriorityQueue* priorityQueue, void item, Real priority)
+ * Usage: void priorityqueue_insert(PriorityQueue* priorityQueue, void item, Real priority)
*/
#define priorityqueue_insert(priorityQueue, item, priority) \
- heap_insert(priorityQueue->heap, item, priority)
+ heap_insert(priorityQueue->heap, item, priority)
/**
* @brief Change the priority of an item in the queue.
* @param newPriority New priority of the modified item.
* @note If several similar items are present, only the first is affected.
*
- * Usage: void priorityqueue_set_priority(\
- * PriorityQueue* priorityQueue, void item, Real newPriority)
+ * Usage: void priorityqueue_set_priority(PriorityQueue* priorityQueue, void item, Real newPriority)
*/
#define priorityqueue_set(priorityQueue, item, newPriority) \
- heap_modify(priorityQueue->heap, item, newPriority)
+ heap_modify(priorityQueue->heap, item, newPriority)
/**
* @brief Remove an item in the queue.
* Usage: void priorityqueue_remove(PriorityQueue* priorityQueue, void item)
*/
#define priorityqueue_remove(priorityQueue, item) \
- heap_remove(priorityQueue->heap, item)
+ heap_remove(priorityQueue->heap, item)
/**
* @brief Return what is at the beginning of the queue.
* @return An ItemValue* 'iv' with iv->item = data, and iv->value its priority.
*/
ItemValue* priorityqueue_peek_raw(
- PriorityQueue* priorityQueue ///< "this" pointer.
+ PriorityQueue* priorityQueue ///< "this" pointer.
);
/**
* Usage: void priorityqueue_peek(PriorityQueue* priorityQueue, void item)
*/
#define priorityqueue_peek(priorityQueue, item) \
- heap_top(priorityQueue->heap, item)
+ heap_top(priorityQueue->heap, item)
/**
* @brief Remove the top element in the queue.
*/
void priorityqueue_pop(
- PriorityQueue* priorityQueue ///< "this" pointer.
+ PriorityQueue* priorityQueue ///< "this" pointer.
);
/**
* @brief Clear the entire queue.
*/
void priorityqueue_clear(
- PriorityQueue* priorityQueue ///< "this" pointer.
+ PriorityQueue* priorityQueue ///< "this" pointer.
);
/**
* @brief Destroy the queue: clear it and free 'priorityQueue' memory.
*/
void priorityqueue_destroy(
- PriorityQueue* priorityQueue ///< "this" pointer.
+ PriorityQueue* priorityQueue ///< "this" pointer.
);
#endif
void _queue_init(Queue* queue, size_t dataSize)
{
- queue->dataSize = dataSize;
- _list_init(queue->list, dataSize);
+ queue->dataSize = dataSize;
+ _list_init(queue->list, dataSize);
}
Queue* _queue_new(size_t dataSize)
{
- Queue* queue = (Queue*) safe_malloc(sizeof (Queue));
- queue->list = _list_new(dataSize);
- _queue_init(queue, dataSize);
- return queue;
+ Queue* queue = (Queue*) safe_malloc(sizeof (Queue));
+ queue->list = _list_new(dataSize);
+ _queue_init(queue, dataSize);
+ return queue;
}
Queue* queue_copy(Queue* queue)
{
- Queue* queueCopy = (Queue*) safe_malloc(sizeof (Queue));
- queueCopy->dataSize = queue->dataSize;
- List* listCopy = list_copy(queue->list);
- queueCopy->list = listCopy;
- return queueCopy;
+ Queue* queueCopy = (Queue*) safe_malloc(sizeof (Queue));
+ queueCopy->dataSize = queue->dataSize;
+ List* listCopy = list_copy(queue->list);
+ queueCopy->list = listCopy;
+ return queueCopy;
}
bool queue_empty(Queue* queue)
{
- return list_empty(queue->list);
+ return list_empty(queue->list);
}
UInt queue_size(Queue* queue)
{
- return list_size(queue->list);
+ return list_size(queue->list);
}
void _queue_push(Queue* queue, void* data)
{
- _list_insert_back(queue->list, data);
+ _list_insert_back(queue->list, data);
}
void* _queue_peek(Queue* queue)
{
- return _list_get(queue->list->head);
+ return _list_get(queue->list->head);
}
void queue_pop(Queue* queue)
{
- list_remove_front(queue->list);
+ list_remove_front(queue->list);
}
void queue_clear(Queue* queue)
{
- list_clear(queue->list);
+ list_clear(queue->list);
}
void queue_destroy(Queue* queue)
{
- list_destroy(queue->list);
- safe_free(queue);
+ list_destroy(queue->list);
+ safe_free(queue);
}
* @param dataSize Size in bytes of a queue element.
*/
typedef struct Queue {
- size_t dataSize; ///< Size in bytes of a queue element.
- List* list; ///< Internal list representation
+ size_t dataSize; ///< Size in bytes of a queue element.
+ List* list; ///< Internal list representation
} Queue;
/**
* @param dataSize Size in bytes of a queue element.
*/
void _queue_init(
- Queue* queue, ///< "this" pointer.
- size_t dataSize ///< Size in bytes of a queue element.
+ Queue* queue, ///< "this" pointer.
+ size_t dataSize ///< Size in bytes of a queue element.
);
/**
* @brief Return an allocated and initialized queue.
*/
Queue* _queue_new(
- size_t dataSize ///< Size in bytes of a queue element.
+ size_t dataSize ///< Size in bytes of a queue element.
);
/**
* Usage: Queue* queue_new(<Type> type)
*/
#define queue_new(type) \
- _queue_new(sizeof(type))
+{ \
+ _queue_new(sizeof(type)); \
+}
/**
* @brief Copy constructor (shallow copy, ok for basic types).
*/
Queue* queue_copy(
- Queue* queue ///< "this" pointer.
+ Queue* queue ///< "this" pointer.
);
/**
* @brief Check if the queue is empty.
*/
bool queue_empty(
- Queue* queue ///< "this" pointer.
+ Queue* queue ///< "this" pointer.
);
/**
* @brief Return size of the current queue.
*/
UInt queue_size(
- Queue* queue ///< "this" pointer.
+ Queue* queue ///< "this" pointer.
);
/**
* @brief Add something at the end of the queue.
*/
void _queue_push(
- Queue* queue, ///< "this" pointer.
- void* data ///< Data to be pushed.
+ Queue* queue, ///< "this" pointer.
+ void* data ///< Data to be pushed.
);
/**
*/
#define queue_push(queue, data) \
{ \
- typeof((data)) tmp = data; \
- _queue_push(queue, &tmp); \
+ typeof((data)) tmp = data; \
+ _queue_push(queue, &tmp); \
}
/**
* @brief Return what is at the beginning of the queue.
*/
void* _queue_peek(
- Queue* queue ///< "this" pointer.
+ Queue* queue ///< "this" pointer.
);
/**
*/
#define queue_peek(queue, data) \
{ \
- void* pData = _queue_peek(queue); \
- data = *((typeof(&data))pData); \
+ void* pData = _queue_peek(queue); \
+ data = *((typeof(&data))pData); \
}
/**
* @brief Remove the beginning of the queue.
*/
void queue_pop(
- Queue* queue ///< "this" pointer.
+ Queue* queue ///< "this" pointer.
);
/**
* @brief Clear the entire queue.
*/
void queue_clear(
- Queue* queue ///< "this" pointer.
+ Queue* queue ///< "this" pointer.
);
/**
* @brief Destroy the queue: clear it, and free 'queue' pointer.
*/
void queue_destroy(
- Queue* queue ///< "this" pointer.
+ Queue* queue ///< "this" pointer.
);
#endif
void _stack_init(Stack* stack, size_t dataSize)
{
- stack->dataSize = dataSize;
- _vector_init(stack->array, dataSize);
+ stack->dataSize = dataSize;
+ _vector_init(stack->array, dataSize);
}
Stack* _stack_new(size_t dataSize)
{
- Stack* stack = (Stack*) safe_malloc(sizeof (Stack));
- stack->array = _vector_new(dataSize);
- _stack_init(stack, dataSize);
- return stack;
+ Stack* stack = (Stack*) safe_malloc(sizeof (Stack));
+ stack->array = _vector_new(dataSize);
+ _stack_init(stack, dataSize);
+ return stack;
}
Stack* stack_copy(Stack* stack)
{
- Stack* stackCopy = (Stack*) safe_malloc(sizeof (Stack));
- stackCopy->dataSize = stack->dataSize;
- Vector* arrayCopy = vector_copy(stack->array);
- stackCopy->array = arrayCopy;
- return stackCopy;
+ Stack* stackCopy = (Stack*) safe_malloc(sizeof (Stack));
+ stackCopy->dataSize = stack->dataSize;
+ Vector* arrayCopy = vector_copy(stack->array);
+ stackCopy->array = arrayCopy;
+ return stackCopy;
}
bool stack_empty(Stack* stack)
{
- return vector_empty(stack->array);
+ return vector_empty(stack->array);
}
UInt stack_size(Stack* stack)
{
- return vector_size(stack->array);
+ return vector_size(stack->array);
}
void _stack_push(Stack* stack, void* data)
{
- _vector_push(stack->array, data);
+ _vector_push(stack->array, data);
}
void* _stack_top(Stack* stack)
{
- return _vector_get(stack->array, vector_size(stack->array)-1);
+ return _vector_get(stack->array, vector_size(stack->array)-1);
}
void stack_pop(Stack* stack)
{
- vector_pop(stack->array);
+ vector_pop(stack->array);
}
void stack_clear(Stack* stack)
{
- vector_clear(stack->array);
+ vector_clear(stack->array);
}
void stack_destroy(Stack* stack)
{
- vector_destroy(stack->array);
- safe_free(stack);
+ vector_destroy(stack->array);
+ safe_free(stack);
}
* @brief Stack containing generic data.
*/
typedef struct Stack {
- size_t dataSize; ///< Size in bytes of a stack element.
- Vector* array; ///< Internal data structure: resizeable array.
+ size_t dataSize; ///< Size in bytes of a stack element.
+ Vector* array; ///< Internal data structure: resizeable array.
} Stack;
/**
* @brief Initialize an empty stack.
*/
void _stack_init(
- Stack* stack, ///< "this" pointer.
- size_t dataSize ///< Size in bytes of a stack element.
+ Stack* stack, ///< "this" pointer.
+ size_t dataSize ///< Size in bytes of a stack element.
);
/**
* @brief Return an allocated and initialized stack.
*/
Stack* _stack_new(
- size_t dataSize ///< Size in bytes of a stack element.
+ size_t dataSize ///< Size in bytes of a stack element.
);
/**
* Usage: Stack* stack_new(<Type> type)
*/
#define stack_new(type) \
- _stack_new(sizeof(type))
+{ \
+ _stack_new(sizeof(type)); \
+}
/**
* @brief Copy constructor (shallow copy, ok for basic types).
*/
Stack* stack_copy(
- Stack* stack ///< "this" pointer.
+ Stack* stack ///< "this" pointer.
);
/**
* @brief Check if the stack is empty.
*/
bool stack_empty(
- Stack* stack ///< "this" pointer.
+ Stack* stack ///< "this" pointer.
);
/**
* @brief Return size of the current stack.
*/
UInt stack_size(
- Stack* stack ///< "this" pointer.
+ Stack* stack ///< "this" pointer.
);
/**
* @brief Add something on top of the stack.
*/
void _stack_push(
- Stack* stack, ///< "this" pointer.
- void* data ///< Data to be added.
+ Stack* stack, ///< "this" pointer.
+ void* data ///< Data to be added.
);
/**
*/
#define stack_push(stack, data) \
{ \
- typeof((data)) tmp = data; \
- _stack_push(stack,&tmp); \
+ typeof((data)) tmp = data; \
+ _stack_push(stack,&tmp); \
}
/**
* @brief Return what is on top of the stack.
*/
void* _stack_top(
- Stack* stack ///< "this" pointer.
+ Stack* stack ///< "this" pointer.
);
/**
*/
#define stack_top(stack, data) \
{ \
- void* pData = _stack_top(stack); \
- data = *((typeof(&data))pData); \
+ void* pData = _stack_top(stack); \
+ data = *((typeof(&data))pData); \
}
/**
* @brief Remove the top of the stack.
*/
void stack_pop(
- Stack* stack ///< "this" pointer.
+ Stack* stack ///< "this" pointer.
);
/**
* @brief Clear the entire stack.
*/
void stack_clear(
- Stack* stack ///< "this" pointer.
+ Stack* stack ///< "this" pointer.
);
/**
* @brief Destroy the stack: clear it, and free 'stack' pointer.
*/
void stack_destroy(
- Stack* stack ///< "this" pointer.
+ Stack* stack ///< "this" pointer.
);
#endif
void _tree_init(Tree* tree, size_t dataSize)
{
- tree->root = NULL;
- tree->dataSize = dataSize;
- tree->size = 0;
+ tree->root = NULL;
+ tree->dataSize = dataSize;
+ tree->size = 0;
}
Tree* _tree_new(size_t dataSize)
{
- Tree* tree = (Tree*) safe_malloc(sizeof (Tree));
- _tree_init(tree, dataSize);
- return tree;
+ Tree* tree = (Tree*) safe_malloc(sizeof (Tree));
+ _tree_init(tree, dataSize);
+ return tree;
}
Tree* tree_copy(Tree* tree)
{
- Tree* treeCopy = _tree_new(tree->dataSize);
- if (tree->root == NULL)
- return treeCopy;
- _tree_set_root(treeCopy, tree->root->data);
+ Tree* treeCopy = _tree_new(tree->dataSize);
+ if (tree->root == NULL)
+ return treeCopy;
+ _tree_set_root(treeCopy, tree->root->data);
- // Now parallel run on both trees (manual breadth-first walk)
- TreeNode* treeNode = tree->root;
- TreeNode* treeNodeCopy = treeCopy->root;
- while (treeNode != NULL)
- {
- // process current children
- TreeNode* child = treeNode->firstChild;
- while (child != NULL)
- {
- _tree_add_child(treeCopy, treeNodeCopy, child->data);
- child = child->next;
- }
+ // Now parallel run on both trees (manual breadth-first walk)
+ TreeNode* treeNode = tree->root;
+ TreeNode* treeNodeCopy = treeCopy->root;
+ while (treeNode != NULL)
+ {
+ // process current children
+ TreeNode* child = treeNode->firstChild;
+ while (child != NULL)
+ {
+ _tree_add_child(treeCopy, treeNodeCopy, child->data);
+ child = child->next;
+ }
- // try to go to next sibling (NOTE: already added as child of parent)
- if (treeNode->next != NULL)
- {
- treeNode = treeNode->next;
- treeNodeCopy = treeNodeCopy->next;
- continue;
- }
+ // try to go to next sibling (NOTE: already added as child of parent)
+ if (treeNode->next != NULL)
+ {
+ treeNode = treeNode->next;
+ treeNodeCopy = treeNodeCopy->next;
+ continue;
+ }
- // try to go to next "cousin" on same level
- if (treeNode->parent != NULL && treeNode->parent->next != NULL)
- {
- TreeNode* treeNodeParent = treeNode->parent->next;
- TreeNode* treeNodeParentCopy = treeNodeCopy->parent->next;
- while (treeNodeParent != NULL && tree_is_leaf(treeNodeParent))
- {
- treeNodeParent = treeNodeParent->next;
- treeNodeParentCopy = treeNodeParentCopy->next;
- }
- if (treeNodeParent != NULL)
- {
- treeNode = treeNodeParent->firstChild;
- treeNodeCopy = treeNodeParentCopy->firstChild;
- continue;
- }
- }
+ // try to go to next "cousin" on same level
+ if (treeNode->parent != NULL && treeNode->parent->next != NULL)
+ {
+ TreeNode* treeNodeParent = treeNode->parent->next;
+ TreeNode* treeNodeParentCopy = treeNodeCopy->parent->next;
+ while (treeNodeParent != NULL && tree_is_leaf(treeNodeParent))
+ {
+ treeNodeParent = treeNodeParent->next;
+ treeNodeParentCopy = treeNodeParentCopy->next;
+ }
+ if (treeNodeParent != NULL)
+ {
+ treeNode = treeNodeParent->firstChild;
+ treeNodeCopy = treeNodeParentCopy->firstChild;
+ continue;
+ }
+ }
- // try to go to next level, and move treeNodeCopy accordingly
- while (treeNode->prev != NULL)
- {
- treeNode = treeNode->prev;
- treeNodeCopy = treeNodeCopy->prev;
- }
- while (treeNode != NULL && tree_is_leaf(treeNode))
- {
- treeNode = treeNode->next;
- treeNodeCopy = treeNodeCopy->next;
- }
- if (treeNode != NULL)
- {
- treeNode = treeNode->firstChild;
- treeNodeCopy = treeNodeCopy->firstChild;
- }
- }
- return treeCopy;
+ // try to go to next level, and move treeNodeCopy accordingly
+ while (treeNode->prev != NULL)
+ {
+ treeNode = treeNode->prev;
+ treeNodeCopy = treeNodeCopy->prev;
+ }
+ while (treeNode != NULL && tree_is_leaf(treeNode))
+ {
+ treeNode = treeNode->next;
+ treeNodeCopy = treeNodeCopy->next;
+ }
+ if (treeNode != NULL)
+ {
+ treeNode = treeNode->firstChild;
+ treeNodeCopy = treeNodeCopy->firstChild;
+ }
+ }
+ return treeCopy;
}
bool tree_empty(Tree* tree)
{
- return (tree->root == NULL);
+ return (tree->root == NULL);
}
UInt tree_size(Tree* tree)
{
- return tree->size;
+ return tree->size;
}
UInt _tree_height_rekursiv(TreeNode* treeNode)
{
- if (tree_is_leaf(treeNode))
- return 1;
- TreeNode* child = treeNode->firstChild;
- UInt maxHeightChild = 0;
- while (child != NULL)
- {
- UInt heightChild = _tree_height_rekursiv(child);
- if (heightChild > maxHeightChild)
- maxHeightChild = heightChild;
- child = child->next;
- }
- return 1 + maxHeightChild;
+ if (tree_is_leaf(treeNode))
+ return 1;
+ TreeNode* child = treeNode->firstChild;
+ UInt maxHeightChild = 0;
+ while (child != NULL)
+ {
+ UInt heightChild = _tree_height_rekursiv(child);
+ if (heightChild > maxHeightChild)
+ maxHeightChild = heightChild;
+ child = child->next;
+ }
+ return 1 + maxHeightChild;
}
UInt tree_height(Tree* tree)
{
- if (tree_empty(tree))
- return 0;
- return _tree_height_rekursiv(tree->root);
+ if (tree_empty(tree))
+ return 0;
+ return _tree_height_rekursiv(tree->root);
}
bool tree_is_leaf(TreeNode* treeNode)
{
- return (treeNode->firstChild == NULL);
+ return (treeNode->firstChild == NULL);
}
void _tree_set_root(Tree* tree, void* data)
{
- tree->root = (TreeNode*) safe_malloc(sizeof (TreeNode));
- tree->root->data = safe_malloc(tree->dataSize);
- memcpy(tree->root->data, data, tree->dataSize);
- tree->root->parent = NULL;
- tree->root->firstChild = NULL;
- tree->root->lastChild = NULL;
- tree->root->prev = NULL;
- tree->root->next = NULL;
- tree->size = 1;
+ tree->root = (TreeNode*) safe_malloc(sizeof (TreeNode));
+ tree->root->data = safe_malloc(tree->dataSize);
+ memcpy(tree->root->data, data, tree->dataSize);
+ tree->root->parent = NULL;
+ tree->root->firstChild = NULL;
+ tree->root->lastChild = NULL;
+ tree->root->prev = NULL;
+ tree->root->next = NULL;
+ tree->size = 1;
}
void* _tree_get(TreeNode* treeNode)
{
- return treeNode->data;
+ return treeNode->data;
}
void _tree_set(Tree* tree, TreeNode* treeNode, void* data)
{
- memcpy(treeNode->data, data, tree->dataSize);
+ memcpy(treeNode->data, data, tree->dataSize);
}
void _tree_add_child(Tree* tree, TreeNode* treeNode, void* data)
{
- TreeNode* newChildNode = (TreeNode*) safe_malloc(sizeof (TreeNode));
- newChildNode->data = safe_malloc(tree->dataSize);
- memcpy(newChildNode->data, data, tree->dataSize);
- newChildNode->next = NULL;
- if (treeNode->lastChild != NULL)
- treeNode->lastChild->next = newChildNode;
- newChildNode->prev = treeNode->lastChild;
- treeNode->lastChild = newChildNode;
- if (treeNode->firstChild == NULL)
- treeNode->firstChild = newChildNode;
- newChildNode->parent = treeNode;
- newChildNode->firstChild = NULL;
- newChildNode->lastChild = NULL;
- tree->size++;
+ TreeNode* newChildNode = (TreeNode*) safe_malloc(sizeof (TreeNode));
+ newChildNode->data = safe_malloc(tree->dataSize);
+ memcpy(newChildNode->data, data, tree->dataSize);
+ newChildNode->next = NULL;
+ if (treeNode->lastChild != NULL)
+ treeNode->lastChild->next = newChildNode;
+ newChildNode->prev = treeNode->lastChild;
+ treeNode->lastChild = newChildNode;
+ if (treeNode->firstChild == NULL)
+ treeNode->firstChild = newChildNode;
+ newChildNode->parent = treeNode;
+ newChildNode->firstChild = NULL;
+ newChildNode->lastChild = NULL;
+ tree->size++;
}
void _tree_add_sibling(Tree* tree, TreeNode* treeNode, void* data)
{
- TreeNode* newSiblingNode = (TreeNode*) safe_malloc(sizeof (TreeNode));
- newSiblingNode->data = safe_malloc(tree->dataSize);
- memcpy(newSiblingNode->data, data, tree->dataSize);
- newSiblingNode->next = treeNode->next;
- if (treeNode->next != NULL)
- treeNode->next->prev = newSiblingNode;
- newSiblingNode->prev = treeNode;
- treeNode->next = newSiblingNode;
- newSiblingNode->parent = treeNode->parent;
- newSiblingNode->firstChild = NULL;
- newSiblingNode->lastChild = NULL;
- tree->size++;
+ TreeNode* newSiblingNode = (TreeNode*) safe_malloc(sizeof (TreeNode));
+ newSiblingNode->data = safe_malloc(tree->dataSize);
+ memcpy(newSiblingNode->data, data, tree->dataSize);
+ newSiblingNode->next = treeNode->next;
+ if (treeNode->next != NULL)
+ treeNode->next->prev = newSiblingNode;
+ newSiblingNode->prev = treeNode;
+ treeNode->next = newSiblingNode;
+ newSiblingNode->parent = treeNode->parent;
+ newSiblingNode->firstChild = NULL;
+ newSiblingNode->lastChild = NULL;
+ tree->size++;
}
void _tree_remove_rekursiv(Tree* tree, TreeNode* treeNode)
{
- TreeNode* child = treeNode->firstChild;
- while (child != NULL)
- {
- TreeNode* nextChild = child->next;
- _tree_remove_rekursiv(tree, child);
- child = nextChild;
- }
- safe_free(treeNode->data);
- safe_free(treeNode);
- tree->size--;
+ TreeNode* child = treeNode->firstChild;
+ while (child != NULL)
+ {
+ TreeNode* nextChild = child->next;
+ _tree_remove_rekursiv(tree, child);
+ child = nextChild;
+ }
+ safe_free(treeNode->data);
+ safe_free(treeNode);
+ tree->size--;
}
void tree_remove(Tree* tree, TreeNode* treeNode)
{
- if (treeNode->parent != NULL)
- {
- if (treeNode->prev == NULL)
- treeNode->parent->firstChild = treeNode->next;
- if (treeNode->next == NULL)
- treeNode->parent->lastChild = treeNode->prev;
- }
- if (treeNode->next != NULL)
- treeNode->next->prev = treeNode->prev;
- if (treeNode->prev != NULL)
- treeNode->prev->next = treeNode->next;
- _tree_remove_rekursiv(tree, treeNode);
+ if (treeNode->parent != NULL)
+ {
+ if (treeNode->prev == NULL)
+ treeNode->parent->firstChild = treeNode->next;
+ if (treeNode->next == NULL)
+ treeNode->parent->lastChild = treeNode->prev;
+ }
+ if (treeNode->next != NULL)
+ treeNode->next->prev = treeNode->prev;
+ if (treeNode->prev != NULL)
+ treeNode->prev->next = treeNode->next;
+ _tree_remove_rekursiv(tree, treeNode);
}
void tree_rm_childs(Tree* tree, TreeNode* treeNode)
{
- TreeNode* child = treeNode->firstChild;
- while (child != NULL)
- {
- TreeNode* nextChild = child->next;
- _tree_remove_rekursiv(tree, child);
- child = nextChild;
- }
- treeNode->firstChild = NULL;
- treeNode->lastChild = NULL;
+ TreeNode* child = treeNode->firstChild;
+ while (child != NULL)
+ {
+ TreeNode* nextChild = child->next;
+ _tree_remove_rekursiv(tree, child);
+ child = nextChild;
+ }
+ treeNode->firstChild = NULL;
+ treeNode->lastChild = NULL;
}
void tree_clear(Tree* tree)
{
- if (tree->root != NULL)
- _tree_remove_rekursiv(tree, tree->root);
- _tree_init(tree, tree->dataSize);
+ if (tree->root != NULL)
+ _tree_remove_rekursiv(tree, tree->root);
+ _tree_init(tree, tree->dataSize);
}
void tree_destroy(Tree* tree)
{
- if (tree->root != NULL)
- tree_clear(tree);
- safe_free(tree);
+ if (tree->root != NULL)
+ tree_clear(tree);
+ safe_free(tree);
}
////////////////////
TreeIterator* tree_get_iterator(Tree* tree, TreeIteratorMode mode)
{
- TreeIterator* treeI = (TreeIterator*) safe_malloc(sizeof (TreeIterator));
- treeI->tree = tree;
- treeI->mode = mode;
- treeI_reset(treeI);
- return treeI;
+ TreeIterator* treeI = (TreeIterator*) safe_malloc(sizeof (TreeIterator));
+ treeI->tree = tree;
+ treeI->mode = mode;
+ treeI_reset(treeI);
+ return treeI;
}
void treeI_reset(TreeIterator* treeI)
{
- treeI->current = treeI->tree->root;
+ treeI->current = treeI->tree->root;
}
bool treeI_has_data(TreeIterator* treeI)
{
- return (treeI->current != NULL);
+ return (treeI->current != NULL);
}
TreeNode* treeI_get_raw(TreeIterator* treeI)
{
- return treeI->current;
+ return treeI->current;
}
void treeI_move_next(TreeIterator* treeI)
{
- TreeIteratorMode mode = treeI->mode;
- switch (mode)
- {
- case IN_DEPTH:
- if (!tree_is_leaf(treeI->current))
- {
- // easy case: just descend deeper in the tree
- treeI->current = treeI->current->firstChild;
- return;
- }
- // leaf: while no next sibling is available, move up
- while (treeI->current != NULL && treeI->current->next == NULL)
- treeI->current = treeI->current->parent;
- if (treeI->current != NULL)
- // run goes on from next sibling
- treeI->current = treeI->current->next;
- break;
- case IN_BREADTH:
- if (treeI->current->next != NULL)
- {
- // easy case : just move to the next sibling
- treeI->current = treeI->current->next;
- return;
- }
- // try to go to next "cousin" on same level
- if (treeI->current->parent != NULL && treeI->current->parent->next != NULL)
- {
- TreeNode* treeNodeParent = treeI->current->parent->next;
- while (treeNodeParent != NULL && tree_is_leaf(treeNodeParent))
- treeNodeParent = treeNodeParent->next;
- if (treeNodeParent != NULL)
- {
- treeI->current = treeNodeParent->firstChild;
- return;
- }
- }
- // try to go to next level
- while (treeI->current->prev != NULL)
- treeI->current = treeI->current->prev;
- while (treeI->current != NULL && tree_is_leaf(treeI->current))
- treeI->current = treeI->current->next;
- if (treeI->current != NULL)
- treeI->current = treeI->current->firstChild;
- break;
- }
+ TreeIteratorMode mode = treeI->mode;
+ switch (mode)
+ {
+ case IN_DEPTH:
+ if (!tree_is_leaf(treeI->current))
+ {
+ // easy case: just descend deeper in the tree
+ treeI->current = treeI->current->firstChild;
+ return;
+ }
+ // leaf: while no next sibling is available, move up
+ while (treeI->current != NULL && treeI->current->next == NULL)
+ treeI->current = treeI->current->parent;
+ if (treeI->current != NULL)
+ // run goes on from next sibling
+ treeI->current = treeI->current->next;
+ break;
+ case IN_BREADTH:
+ if (treeI->current->next != NULL)
+ {
+ // easy case : just move to the next sibling
+ treeI->current = treeI->current->next;
+ return;
+ }
+ // try to go to next "cousin" on same level
+ if (treeI->current->parent != NULL && treeI->current->parent->next != NULL)
+ {
+ TreeNode* treeNodeParent = treeI->current->parent->next;
+ while (treeNodeParent != NULL && tree_is_leaf(treeNodeParent))
+ treeNodeParent = treeNodeParent->next;
+ if (treeNodeParent != NULL)
+ {
+ treeI->current = treeNodeParent->firstChild;
+ return;
+ }
+ }
+ // try to go to next level
+ while (treeI->current->prev != NULL)
+ treeI->current = treeI->current->prev;
+ while (treeI->current != NULL && tree_is_leaf(treeI->current))
+ treeI->current = treeI->current->next;
+ if (treeI->current != NULL)
+ treeI->current = treeI->current->firstChild;
+ break;
+ }
}
void treeI_destroy(TreeIterator* treeI)
{
- safe_free(treeI);
+ safe_free(treeI);
}
* @brief Tree node, containing some generic data.
*/
typedef struct TreeNode {
- void* data; ///< Generic data contained in this node.
- struct TreeNode* parent; ///< Pointer to parent node (NULL if node is root).
- struct TreeNode* firstChild; ///< Pointer to the first child (if any).
- struct TreeNode* lastChild; ///< Pointer to the last child (if any).
- struct TreeNode* prev; ///< Pointer to the previous sibling (on the left).
- struct TreeNode* next; ///< Pointer to the next sibling (on the right).
+ void* data; ///< Generic data contained in this node.
+ struct TreeNode* parent; ///< Pointer to parent node (NULL if node is root).
+ struct TreeNode* firstChild; ///< Pointer to the first child (if any).
+ struct TreeNode* lastChild; ///< Pointer to the last child (if any).
+ struct TreeNode* prev; ///< Pointer to the previous sibling (on the left).
+ struct TreeNode* next; ///< Pointer to the next sibling (on the right).
} TreeNode;
/**
* @brief Generic multi-ary tree.
*/
typedef struct Tree {
- TreeNode* root; ///< Root node of the tree.
- size_t dataSize; ///< Size of *data at a tree node, in bytes.
- UInt size; ///< Count nodes in the tree.
+ TreeNode* root; ///< Root node of the tree.
+ size_t dataSize; ///< Size of *data at a tree node, in bytes.
+ UInt size; ///< Count nodes in the tree.
} Tree;
/**
* @brief Initialize an empty tree.
*/
void _tree_init(
- Tree* tree, ///< "this" pointer.
- size_t dataSize ///< Size in bytes of a tree element.
+ Tree* tree, ///< "this" pointer.
+ size_t dataSize ///< Size in bytes of a tree element.
);
/**
* @brief Return an allocated and initialized tree.
*/
Tree* _tree_new(
- size_t dataSize ///< Size in bytes of a tree node element.
+ size_t dataSize ///< Size in bytes of a tree node element.
);
/**
* Usage: Tree* tree_new(<Type> type)
*/
#define tree_new(type) \
- _tree_new(sizeof(type))
+{ \
+ _tree_new(sizeof(type)); \
+}
/**
* @brief Copy constructor (shallow copy, ok for basic types).
*/
Tree* tree_copy(
- Tree* tree ///< "this" pointer.
+ Tree* tree ///< "this" pointer.
);
/**
* @brief Check if the tree is empty.
*/
bool tree_empty(
- Tree* tree ///< "this" pointer.
+ Tree* tree ///< "this" pointer.
);
/**
* @brief return current size of the tree (counting nodes).
*/
UInt tree_size(
- Tree* tree ///< "this" pointer.
+ Tree* tree ///< "this" pointer.
);
/**
* @brief Auxiliary function to get tree height.
*/
UInt _tree_height_rekursiv(
- TreeNode* treeNode ///< Pointer to a node in the "this" tree.
+ TreeNode* treeNode ///< Pointer to a node in the "this" tree.
);
/**
* @brief Return tree height (max depth from root to leaves).
*/
UInt tree_height(
- Tree* tree ///< "this" pointer.
+ Tree* tree ///< "this" pointer.
);
/**
* @brief Check if a sub-tree is a leaf (without children).
*/
bool tree_is_leaf(
- TreeNode* treeNode ///< Pointer to a node in the "this" tree.
+ TreeNode* treeNode ///< Pointer to a node in the "this" tree.
);
/**
* @brief Initialize tree root when the tree is empty.
*/
void _tree_set_root(
- Tree* tree, ///< "this" pointer.
- void* data ///< Pointer to data to be assigned.
+ Tree* tree, ///< "this" pointer.
+ void* data ///< Pointer to data to be assigned.
);
/**
*/
#define tree_set_root(tree, data) \
{ \
- typeof((data)) tmp = data; \
- _tree_set_root(tree, &tmp); \
+ typeof((data)) tmp = data; \
+ _tree_set_root(tree, &tmp); \
}
/**
* @brief Return data contained in a given tree node.
*/
void* _tree_get(
- TreeNode* treeNode ///< Pointer to a node in the "this" tree.
+ TreeNode* treeNode ///< Pointer to a node in the "this" tree.
);
/**
*/
#define tree_get(treeNode, data) \
{ \
- void* pData = _tree_get(treeNode); \
- data = *((typeof(&data))pData); \
+ void* pData = _tree_get(treeNode); \
+ data = *((typeof(&data))pData); \
}
/**
* @brief Set (alter) data at tree node passed as argument.
*/
void _tree_set(
- Tree* tree, ///< "this" pointer.
- TreeNode* treeNode, ///< Pointer to a node in the "this" tree.
- void* data ///< Pointer to data to be assigned.
+ Tree* tree, ///< "this" pointer.
+ TreeNode* treeNode, ///< Pointer to a node in the "this" tree.
+ void* data ///< Pointer to data to be assigned.
);
/**
*/
#define tree_set(tree, treeNode, data) \
{ \
- typeof((data)) tmp = data; \
- _tree_set(tree,treeNode,&tmp); \
+ typeof((data)) tmp = data; \
+ _tree_set(tree,treeNode,&tmp); \
}
/**
* @brief Add a child to current node children.
*/
void _tree_add_child(
- Tree* tree, ///< "this" pointer.
- TreeNode* treeNode, ///< Pointer to a node in the "this" tree.
- void* data ///< Pointer to data to be added.
+ Tree* tree, ///< "this" pointer.
+ TreeNode* treeNode, ///< Pointer to a node in the "this" tree.
+ void* data ///< Pointer to data to be added.
);
/**
*/
#define tree_add_child(tree,treeNode,data) \
{ \
- typeof((data)) tmp = data; \
- _tree_add_child(tree,treeNode,&tmp); \
+ typeof((data)) tmp = data; \
+ _tree_add_child(tree,treeNode,&tmp); \
}
/**
* @brief Add a sibling to current node (after it on the right).
*/
void _tree_add_sibling(
- Tree* tree, ///< "this" pointer.
- TreeNode* treeNode, ///< Pointer to a node in the "this" tree.
- void* data ///< Pointer to data to be added.
+ Tree* tree, ///< "this" pointer.
+ TreeNode* treeNode, ///< Pointer to a node in the "this" tree.
+ void* data ///< Pointer to data to be added.
);
/**
*/
#define tree_add_sibling(tree, treeNode, data) \
{ \
- typeof((data)) tmp = data; \
- _tree_add_sibling(tree, treeNode, &tmp); \
+ typeof((data)) tmp = data; \
+ _tree_add_sibling(tree, treeNode, &tmp); \
}
/**
* @brief Auxiliary to remove a subtree.
*/
void _tree_remove_rekursiv(
- Tree* tree, ///< "this" pointer.
- TreeNode* treeNode ///< Pointer to a node in the "this" tree.
+ Tree* tree, ///< "this" pointer.
+ TreeNode* treeNode ///< Pointer to a node in the "this" tree.
);
/**
* @brief Remove the whole subtree rooted at 'treeNode'.
*/
void tree_remove(
- Tree* tree, ///< "this" pointer.
- TreeNode* treeNode ///< Pointer to a node in the "this" tree.
+ Tree* tree, ///< "this" pointer.
+ TreeNode* treeNode ///< Pointer to a node in the "this" tree.
);
/**
* @brief Remove children of the tree node given as argument.
*/
void tree_rm_childs(
- Tree* tree, ///< "this" pointer.
- TreeNode* treeNode ///< Pointer to a node in the "this" tree.
+ Tree* tree, ///< "this" pointer.
+ TreeNode* treeNode ///< Pointer to a node in the "this" tree.
);
/**
* @brief Clear the entire tree.
*/
void tree_clear(
- Tree* tree ///< "this" pointer.
+ Tree* tree ///< "this" pointer.
);
/**
* @brief Destroy the tree: clear it, and free 'tree' pointer.
*/
void tree_destroy(
- Tree* tree ///< "this" pointer.
+ Tree* tree ///< "this" pointer.
);
//***************
* @brief Type of tree search: depth first or breadth first walk.
*/
typedef enum TreeIteratorMode {
- IN_DEPTH = 0, ///< Depth first.
- IN_BREADTH = 1 ///< Breadth first.
+ IN_DEPTH = 0, ///< Depth first.
+ IN_BREADTH = 1 ///< Breadth first.
} TreeIteratorMode;
/**
* @brief Iterator on a tree object.
*/
typedef struct TreeIterator {
- Tree* tree; ///< Pointer to the tree to iterate over.
- TreeNode* current; ///< Current iterator position.
- TreeIteratorMode mode; ///< Mode of iteration (in depth or in breadth).
+ Tree* tree; ///< Pointer to the tree to iterate over.
+ TreeNode* current; ///< Current iterator position.
+ TreeIteratorMode mode; ///< Mode of iteration (in depth or in breadth).
} TreeIterator;
/**
* @brief Obtain an iterator object, starting at tree root.
*/
TreeIterator* tree_get_iterator(
- Tree* tree, ///< Pointer to the tree to iterate over.
- TreeIteratorMode mode ///< Mode of iteration (in depth or in breadth).
+ Tree* tree, ///< Pointer to the tree to iterate over.
+ TreeIteratorMode mode ///< Mode of iteration (in depth or in breadth).
);
/**
* @brief (Re)set current position inside tree to root.
*/
void treeI_reset(
- TreeIterator* treeI ///< "this" pointer.
+ TreeIterator* treeI ///< "this" pointer.
);
/**
* @brief Tell if there is some data at the current index.
*/
bool treeI_has_data(
- TreeIterator* treeI ///< "this" pointer.
+ TreeIterator* treeI ///< "this" pointer.
);
/**
* @brief Return current tree node.
*/
TreeNode* treeI_get_raw(
- TreeIterator* treeI ///< "this" pointer.
+ TreeIterator* treeI ///< "this" pointer.
);
/**
* Usage: void treeI_get(TreeIterator* treeI, void data)
*/
#define treeI_get(treeI, data) \
- tree_get(treeI->current, data)
+ tree_get(treeI->current, data)
/**
* @brief Set (alter) data at current tree node.
* Usage: void treeI_set(TreeIterator* treeI, void data)
*/
#define treeI_set(treeI, data) \
- tree_set(treeI->tree, treeI->current, data)
+ tree_set(treeI->tree, treeI->current, data)
/**
* @brief Move current iterator position forward (toward leaves).
*/
void treeI_move_next(
- TreeIterator* treeI ///< "this" pointer.
+ TreeIterator* treeI ///< "this" pointer.
);
/**
* @brief Free memory allocated for the iterator.
*/
void treeI_destroy(
- TreeIterator* treeI ///< "this" pointer.
+ TreeIterator* treeI ///< "this" pointer.
);
#endif
void _vector_init(Vector* vector, size_t dataSize)
{
- vector->datas = NULL;
- vector->dataSize = dataSize;
- vector->size = 0;
- vector->capacity = 0;
+ vector->datas = NULL;
+ vector->dataSize = dataSize;
+ vector->size = 0;
+ vector->capacity = 0;
}
Vector* _vector_new(size_t dataSize)
{
- Vector* vector = (Vector*) safe_malloc(sizeof (Vector));
- _vector_init(vector, dataSize);
- return vector;
+ Vector* vector = (Vector*) safe_malloc(sizeof (Vector));
+ _vector_init(vector, dataSize);
+ return vector;
}
Vector* vector_copy(Vector* vector)
{
- Vector* vectorCopy = _vector_new(vector->dataSize);
- vectorCopy->size = vector->size;
- vectorCopy->capacity = vector->capacity;
- vectorCopy->datas = (void**) safe_malloc(vector->capacity * sizeof (void*));
- for (UInt i = 0; i < vector->size; i++)
- {
- vectorCopy->datas[i] = safe_malloc(vector->dataSize);
- memcpy(vectorCopy->datas[i], vector->datas[i], vector->dataSize);
- }
- return vectorCopy;
+ Vector* vectorCopy = _vector_new(vector->dataSize);
+ vectorCopy->size = vector->size;
+ vectorCopy->capacity = vector->capacity;
+ vectorCopy->datas = (void**) safe_malloc(vector->capacity * sizeof (void*));
+ for (UInt i = 0; i < vector->size; i++)
+ {
+ vectorCopy->datas[i] = safe_malloc(vector->dataSize);
+ memcpy(vectorCopy->datas[i], vector->datas[i], vector->dataSize);
+ }
+ return vectorCopy;
}
bool vector_empty(Vector* vector)
{
- return (vector->size == 0);
+ return (vector->size == 0);
}
UInt vector_size(Vector* vector)
{
- return vector->size;
+ return vector->size;
}
void _vector_realloc(Vector* vector, UInt newCapacity)
{
- void** rellocatedDatas = (void**) safe_malloc(newCapacity * sizeof (void*));
- for (UInt i = 0; i < vector->size; i++)
- {
- rellocatedDatas[i] = (void*) safe_malloc(vector->dataSize);
- memcpy(rellocatedDatas[i], vector->datas[i], vector->dataSize);
- safe_free(vector->datas[i]);
- }
- safe_free(vector->datas);
- vector->datas = rellocatedDatas;
- vector->capacity = newCapacity;
+ void** rellocatedDatas = (void**) safe_malloc(newCapacity * sizeof (void*));
+ for (UInt i = 0; i < vector->size; i++)
+ {
+ rellocatedDatas[i] = (void*) safe_malloc(vector->dataSize);
+ memcpy(rellocatedDatas[i], vector->datas[i], vector->dataSize);
+ safe_free(vector->datas[i]);
+ }
+ safe_free(vector->datas);
+ vector->datas = rellocatedDatas;
+ vector->capacity = newCapacity;
}
void _vector_push(Vector* vector, void* data)
{
- void* pData = safe_malloc(vector->dataSize);
- memcpy(pData, data, vector->dataSize);
- if (vector->size >= vector->capacity)
- {
- UInt increasedCapacity = vector->capacity > 0 ? 2 * vector->capacity : 1;
- _vector_realloc(vector, increasedCapacity);
- }
- vector->datas[vector->size] = pData;
- vector->size++;
+ void* pData = safe_malloc(vector->dataSize);
+ memcpy(pData, data, vector->dataSize);
+ if (vector->size >= vector->capacity)
+ {
+ UInt increasedCapacity = vector->capacity > 0 ? 2 * vector->capacity : 1;
+ _vector_realloc(vector, increasedCapacity);
+ }
+ vector->datas[vector->size] = pData;
+ vector->size++;
}
void vector_pop(Vector* vector)
{
- safe_free(vector->datas[vector_size(vector) - 1]);
- vector->size--;
- if (vector_size(vector) <= (vector->capacity >> 1))
- _vector_realloc(vector, vector->capacity >> 1);
+ safe_free(vector->datas[vector_size(vector) - 1]);
+ vector->size--;
+ if (vector_size(vector) <= (vector->capacity >> 1))
+ _vector_realloc(vector, vector->capacity >> 1);
}
void* _vector_get(Vector* vector, UInt index)
{
- return vector->datas[index];
+ return vector->datas[index];
}
void _vector_set(Vector* vector, UInt index, void* data)
{
- memcpy(vector->datas[index], data, vector->dataSize);
+ memcpy(vector->datas[index], data, vector->dataSize);
}
void vector_clear(Vector* vector)
{
- for (UInt i = 0; i < vector->size; i++)
- safe_free(vector->datas[i]);
- safe_free(vector->datas);
- _vector_init(vector, vector->dataSize);
+ for (UInt i = 0; i < vector->size; i++)
+ safe_free(vector->datas[i]);
+ safe_free(vector->datas);
+ _vector_init(vector, vector->dataSize);
}
void vector_destroy(Vector* vector)
{
- vector_clear(vector);
- safe_free(vector);
+ vector_clear(vector);
+ safe_free(vector);
}
////////////////////
VectorIterator* vector_get_iterator(Vector* vector)
{
- VectorIterator* vectorI =
+ VectorIterator* vectorI =
(VectorIterator*) safe_malloc(sizeof (VectorIterator));
- vectorI->vector = vector;
- vectorI_reset_begin(vectorI);
- return vectorI;
+ vectorI->vector = vector;
+ vectorI_reset_begin(vectorI);
+ return vectorI;
}
void vectorI_reset_begin(VectorIterator* vectorI)
{
- vectorI->current = vectorI->vector->datas;
+ vectorI->current = vectorI->vector->datas;
}
void vectorI_reset_end(VectorIterator* vectorI)
{
- vectorI->current = vectorI->vector->datas + vectorI->vector->size - 1;
+ vectorI->current = vectorI->vector->datas + vectorI->vector->size - 1;
}
bool vectorI_has_data(VectorIterator* vectorI)
{
- return (vectorI->current >= vectorI->vector->datas &&
- vectorI->current < vectorI->vector->datas + vectorI->vector->size);
+ return (vectorI->current >= vectorI->vector->datas &&
+ vectorI->current < vectorI->vector->datas + vectorI->vector->size);
}
void* _vectorI_get(VectorIterator* vectorI)
{
- return *(vectorI->current);
+ return *(vectorI->current);
}
void _vectorI_set(VectorIterator* vectorI, void* data)
{
- *(vectorI->current) = data;
+ *(vectorI->current) = data;
}
void vectorI_move_next(VectorIterator* vectorI)
{
- vectorI->current++;
+ vectorI->current++;
}
void vectorI_move_prev(VectorIterator* vectorI)
{
- vectorI->current--;
+ vectorI->current--;
}
void vectorI_destroy(VectorIterator* vectorI)
{
- safe_free(vectorI);
+ safe_free(vectorI);
}
* @brief Generic resizable array.
*/
typedef struct Vector {
- void** datas; ///< Data array of fixed length (reallocated if needed).
- size_t dataSize; ///< Size in bytes of a vector element.
- UInt size; ///< Count elements in the vector.
- UInt capacity; ///< Current maximal capacity; always larger than size.
+ void** datas; ///< Data array of fixed length (reallocated if needed).
+ size_t dataSize; ///< Size in bytes of a vector element.
+ UInt size; ///< Count elements in the vector.
+ UInt capacity; ///< Current maximal capacity; always larger than size.
} Vector;
/**
* @brief Initialize an empty vector.
*/
void _vector_init(
- Vector* vector, ///< "this" pointer.
- size_t dataSize ///< Size in bytes of a vector element.
+ Vector* vector, ///< "this" pointer.
+ size_t dataSize ///< Size in bytes of a vector element.
);
/**
* @brief Return an allocated and initialized vector.
*/
Vector* _vector_new(
- size_t dataSize ///< Size in bytes of a vector element.
+ size_t dataSize ///< Size in bytes of a vector element.
);
/**
* Usage: Vector* vector_new(<Type> type)
*/
#define vector_new(type) \
- _vector_new(sizeof(type))
+{ \
+ _vector_new(sizeof(type)); \
+}
/**
* @brief Copy constructor (shallow copy, ok for basic types).
*/
Vector* vector_copy(
- Vector* vector ///< "this" pointer.
+ Vector* vector ///< "this" pointer.
);
/**
* @brief Check if the vector is empty.
*/
bool vector_empty(
- Vector* vector ///< "this" pointer.
+ Vector* vector ///< "this" pointer.
);
/**
* @brief Return current size.
*/
UInt vector_size(
- Vector* vector ///< "this" pointer.
+ Vector* vector ///< "this" pointer.
);
/**
* @brief Reallocate internal array.
*/
void _vector_realloc(
- Vector* vector, ///< "this" pointer.
- UInt newCapacity ///< New capacity of the vector (in number of elements).
+ Vector* vector, ///< "this" pointer.
+ UInt newCapacity ///< New capacity of the vector (in number of elements).
);
/**
* @brief Add data at the end.
*/
void _vector_push(
- Vector* vector, ///< "this" pointer.
- void* data ///< Data to be added.
+ Vector* vector, ///< "this" pointer.
+ void* data ///< Data to be added.
);
/**
*/
#define vector_push(vector, data) \
{ \
- typeof((data)) tmp = data; \
- _vector_push(vector,&tmp); \
+ typeof((data)) tmp = data; \
+ _vector_push(vector,&tmp); \
}
/**
* @brief Remove the last pushed element.
*/
void vector_pop(
- Vector* vector ///< "this" pointer.
+ Vector* vector ///< "this" pointer.
);
/**
* @brief Get the element at given index.
*/
void* _vector_get(
- Vector* vector, ///< "this" pointer.
- UInt index ///< Index of the element to retrieve.
+ Vector* vector, ///< "this" pointer.
+ UInt index ///< Index of the element to retrieve.
);
/**
*/
#define vector_get(vector, index, data) \
{ \
- void* pData = _vector_get(vector,index); \
- data = *((typeof(&data))pData); \
+ void* pData = _vector_get(vector,index); \
+ data = *((typeof(&data))pData); \
}
/**
* @brief Set the element at given index.
*/
void _vector_set(
- Vector* vector, ///< "this" pointer.
- UInt index, ///< Index of the element to be modified.
- void* data ///< Pointer to new data at given index.
+ Vector* vector, ///< "this" pointer.
+ UInt index, ///< Index of the element to be modified.
+ void* data ///< Pointer to new data at given index.
);
/**
*/
#define vector_set(vector, index, data) \
{ \
- typeof((data)) tmp = data; \
- _vector_set(vector,index,&tmp); \
+ typeof((data)) tmp = data; \
+ _vector_set(vector,index,&tmp); \
}
/**
* @brief Clear the entire vector.
*/
void vector_clear(
- Vector* vector ///< "this" pointer.
+ Vector* vector ///< "this" pointer.
);
/**
* @brief Destroy the vector: clear it, and free 'vector' pointer.
*/
void vector_destroy(
- Vector* vector ///< "this" pointer.
+ Vector* vector ///< "this" pointer.
);
//***************
* @brief Iterator on a generic vector.
*/
typedef struct VectorIterator {
- Vector* vector; ///< Vector to be iterated.
- void** current; ///< Current vector element.
+ Vector* vector; ///< Vector to be iterated.
+ void** current; ///< Current vector element.
} VectorIterator;
/**
* @brief Obtain an iterator object, starting at vector beginning (index 0).
*/
VectorIterator* vector_get_iterator(
- Vector* vector ///< Pointer to the vector to iterate over.
+ Vector* vector ///< Pointer to the vector to iterate over.
);
/**
* @brief (Re)set current position inside vector to beginning (0).
*/
void vectorI_reset_begin(
- VectorIterator* vectorI ///< "this" pointer.
+ VectorIterator* vectorI ///< "this" pointer.
);
/**
* @brief (Re)set current position inside vector to end (vector->size-1).
*/
void vectorI_reset_end(
- VectorIterator* vectorI ///< "this" pointer.
+ VectorIterator* vectorI ///< "this" pointer.
);
/**
* @brief Tell if there is some data at the current index.
*/
bool vectorI_has_data(
- VectorIterator* vectorI ///< "this" pointer.
+ VectorIterator* vectorI ///< "this" pointer.
);
/**
* @brief Get data contained at the current index.
*/
void* _vectorI_get(
- VectorIterator* vectorI ///< "this" pointer.
+ VectorIterator* vectorI ///< "this" pointer.
);
/**
*/
#define vectorI_get(vectorI, data) \
{ \
- void* pData = _vectorI_get(vectorI); \
- data = *((typeof(&data))pData); \
+ void* pData = _vectorI_get(vectorI); \
+ data = *((typeof(&data))pData); \
}
/**
* @brief Set the element at current index.
*/
void _vectorI_set(
- VectorIterator* vectorI, ///< "this" pointer.
- void* data ///< Data to be assigned.
+ VectorIterator* vectorI, ///< "this" pointer.
+ void* data ///< Data to be assigned.
);
/**
*/
#define vectorI_set(vectorI, data) \
{ \
- typeof((data)) tmp = data; \
- _vectorI_set(vectorI,&tmp); \
+ typeof((data)) tmp = data; \
+ _vectorI_set(vectorI,&tmp); \
}
/**
* @brief Move current iterator position forward (toward last index).
*/
void vectorI_move_next(
- VectorIterator* vectorI ///< "this" pointer.
+ VectorIterator* vectorI ///< "this" pointer.
);
/**
* @brief Move current iterator position backward (toward first index).
*/
void vectorI_move_prev(
- VectorIterator* vectorI ///< "this" pointer.
+ VectorIterator* vectorI ///< "this" pointer.
);
/**
* @brief Free memory allocated for the iterator.
*/
void vectorI_destroy(
- VectorIterator* vectorI ///< "this" pointer.
+ VectorIterator* vectorI ///< "this" pointer.
);
#endif
void* safe_malloc(size_t size)
{
- void* res = malloc(size);
- if (res == NULL)
- {
- fprintf(stderr, "Error: unable to allocate memory\n");
- exit(EXIT_FAILURE);
- }
- return res;
+ void* res = malloc(size);
+ if (res == NULL)
+ {
+ fprintf(stderr, "Error: unable to allocate memory\n");
+ exit(EXIT_FAILURE);
+ }
+ return res;
}
void* safe_calloc(size_t count, size_t size)
{
- void* res = calloc(count, size);
- if (res == NULL)
- {
- fprintf(stderr, "Error: unable to allocate memory\n");
- exit(EXIT_FAILURE);
- }
- return res;
+ void* res = calloc(count, size);
+ if (res == NULL)
+ {
+ fprintf(stderr, "Error: unable to allocate memory\n");
+ exit(EXIT_FAILURE);
+ }
+ return res;
}
void* safe_realloc(void* ptr, size_t size)
{
- void* res = realloc(ptr, size);
- if (res == NULL)
- {
- fprintf(stderr, "Error: unable to reallocate memory\n");
- exit(EXIT_FAILURE);
- }
- return res;
+ void* res = realloc(ptr, size);
+ if (res == NULL)
+ {
+ fprintf(stderr, "Error: unable to reallocate memory\n");
+ exit(EXIT_FAILURE);
+ }
+ return res;
}
void safe_free(void* ptr)
{
- if (ptr != NULL)
- free(ptr);
+ if (ptr != NULL)
+ free(ptr);
}
* @return A pointer to the newly allocated area; exit program if fail.
*/
void* safe_malloc(
- size_t size ///< Size of the block to allocate, in bytes.
+ size_t size ///< Size of the block to allocate, in bytes.
);
/**
* @return A pointer to the newly allocated area; exit program if fail.
*/
void* safe_calloc(
- size_t count, ///< Number of elements to allocate.
- size_t size ///< Size of the element to allocate, in bytes.
+ size_t count, ///< Number of elements to allocate.
+ size_t size ///< Size of the element to allocate, in bytes.
);
/**
* @return A pointer to the newly allocated area; exit program if fail.
*/
void* safe_realloc(
- void* ptr, ///< Pointer on the area to be relocated.
- size_t size ///< Size of the block to reallocate, in bytes.
+ void* ptr, ///< Pointer on the area to be relocated.
+ size_t size ///< Size of the block to reallocate, in bytes.
);
/**
* @brief Wrapper around stdlib free function.
*/
void safe_free(
- void* ptr ///< Pointer on the area to be destroyed.
+ void* ptr ///< Pointer on the area to be destroyed.
);
#endif
* @brief Enumeration for the type of buffer or heap.
*/
typedef enum {
- MIN_T = 0, ///< Minimum element first.
- MAX_T = 1 ///< Maximum element first.
+ MIN_T = 0, ///< Minimum element first.
+ MAX_T = 1 ///< Maximum element first.
} OrderType;
/**
* @brief Generic item-value type; 'value' may correspond e.g. to distance.
*/
typedef struct ItemValue {
- void* item; ///< Pointer to an item of any type.
- Real value; ///< Value associated with the item.
+ void* item; ///< Pointer to an item of any type.
+ Real value; ///< Value associated with the item.
} ItemValue;
#endif
// types (POD) to be used as items inside our data structures
typedef struct {
- int a;
- double b;
+ int a;
+ double b;
} StructTest1;
typedef struct {
- float a;
- StructTest1* b;
+ float a;
+ StructTest1* b;
} StructTest2;
#endif
#define lu_assert_msg(expr, ...) \
- if (!(expr)) { \
- fprintf(stdout, "Failure in file %s at line %i\n", __FILE__, __LINE__); \
- fprintf(stdout, ## __VA_ARGS__); \
- return; \
- }
+ if (!(expr)) { \
+ fprintf(stdout, "Failure in file %s at line %i\n", __FILE__, __LINE__); \
+ fprintf(stdout, ## __VA_ARGS__); \
+ return; \
+ }
#define lu_assert(expr) \
- lu_assert_msg(expr, "");
+ lu_assert_msg(expr, "");
/* OP may be any comparison operator. */
#define _lu_assert_int(X, OP, Y) do { \
- int _lu_x = (X); \
- int _lu_y = (Y); \
- lu_assert_msg(_lu_x OP _lu_y, \
+ int _lu_x = (X); \
+ int _lu_y = (Y); \
+ lu_assert_msg(_lu_x OP _lu_y, \
"Assertion '"#X#OP#Y"' failed: "#X"==%i, "#Y"==%i\n", \
_lu_x, _lu_y); \
} while (0)
#define lu_assert_int_ge(X, Y) _lu_assert_int(X, >=, Y)
#define _lu_assert_dbl(X, OP, Y) do { \
- double _lu_x = (X); \
- double _lu_y = (Y); \
- lu_assert_msg(_lu_x OP _lu_y, \
+ double _lu_x = (X); \
+ double _lu_y = (Y); \
+ lu_assert_msg(_lu_x OP _lu_y, \
"Assertion '"#X#OP#Y"' failed: "#X"==%g, "#Y"==%g", \
_lu_x, _lu_y); \
} while (0)
t_buffertop_copy();
//file ./t.HashTable.c :
- //t_hashtable_clear();
- //t_hashtable_size();
+ t_hashtable_clear();
+ t_hashtable_size();
t_hashtable_set_remove_basic();
- //t_hashtable_getnull_modify();
- //t_hashtable_copy();
+ t_hashtable_getnull_modify();
+ t_hashtable_copy();
//file ./t.Stack.c :
t_stack_clear();
void t_buffertop_clear()
{
- BufferTop* bt = buffertop_new(int, 10, MIN_T, 2);
+ BufferTop* bt = buffertop_new(int, 10, MIN_T, 2);
- // NOTE: items with same values are supported;
- // since it is unused in this test, we arbitrarily choose 0.0
- buffertop_tryadd(bt, 0, 0.0);
- buffertop_tryadd(bt, 0, 0.0);
- buffertop_tryadd(bt, 0, 0.0);
+ // NOTE: items with same values are supported;
+ // since it is unused in this test, we arbitrarily choose 0.0
+ buffertop_tryadd(bt, 0, 0.0);
+ buffertop_tryadd(bt, 0, 0.0);
+ buffertop_tryadd(bt, 0, 0.0);
- buffertop_clear(bt);
- lu_assert(buffertop_empty(bt));
+ buffertop_clear(bt);
+ lu_assert(buffertop_empty(bt));
- buffertop_destroy(bt);
+ buffertop_destroy(bt);
}
void t_buffertop_size()
{
- BufferTop* bt = buffertop_new(double, 10, MAX_T, 3);
-
- buffertop_tryadd(bt, 0.0, 0.0);
- buffertop_tryadd(bt, 0.0, 0.0);
- buffertop_tryadd(bt, 0.0, 0.0);
- lu_assert_int_eq(buffertop_size(bt), 3);
-
- buffertop_tryadd(bt, 0.0, 0.0);
- buffertop_tryadd(bt, 0.0, 0.0);
- lu_assert_int_eq(buffertop_size(bt), 5);
-
- buffertop_tryadd(bt, 0.0, 0.0);
- buffertop_tryadd(bt, 0.0, 0.0);
- buffertop_tryadd(bt, 0.0, 0.0);
- lu_assert_int_eq(buffertop_size(bt), 8);
- buffertop_destroy(bt);
-
- // Now try to add beyond capacity, with reorganizing
- bt = buffertop_new(double, 3, MAX_T, 2);
- buffertop_tryadd(bt, 0.0, 0.0);
- buffertop_tryadd(bt, 0.0, 1.0);
- buffertop_tryadd(bt, 0.0, 2.0);
- buffertop_tryadd(bt, 0.0, 3.0);
- buffertop_tryadd(bt, 0.0, 4.0);
- buffertop_tryadd(bt, 0.0, 5.0);
- buffertop_tryadd(bt, 0.0, 6.0);
- buffertop_tryadd(bt, 0.0, 7.0);
- lu_assert_int_eq(buffertop_size(bt), 3);
-
- buffertop_clear(bt);
- lu_assert(buffertop_empty(bt));
- buffertop_destroy(bt);
+ BufferTop* bt = buffertop_new(double, 10, MAX_T, 3);
+
+ buffertop_tryadd(bt, 0.0, 0.0);
+ buffertop_tryadd(bt, 0.0, 0.0);
+ buffertop_tryadd(bt, 0.0, 0.0);
+ lu_assert_int_eq(buffertop_size(bt), 3);
+
+ buffertop_tryadd(bt, 0.0, 0.0);
+ buffertop_tryadd(bt, 0.0, 0.0);
+ lu_assert_int_eq(buffertop_size(bt), 5);
+
+ buffertop_tryadd(bt, 0.0, 0.0);
+ buffertop_tryadd(bt, 0.0, 0.0);
+ buffertop_tryadd(bt, 0.0, 0.0);
+ lu_assert_int_eq(buffertop_size(bt), 8);
+ buffertop_destroy(bt);
+
+ // Now try to add beyond capacity, with reorganizing
+ bt = buffertop_new(double, 3, MAX_T, 2);
+ buffertop_tryadd(bt, 0.0, 0.0);
+ buffertop_tryadd(bt, 0.0, 1.0);
+ buffertop_tryadd(bt, 0.0, 2.0);
+ buffertop_tryadd(bt, 0.0, 3.0);
+ buffertop_tryadd(bt, 0.0, 4.0);
+ buffertop_tryadd(bt, 0.0, 5.0);
+ buffertop_tryadd(bt, 0.0, 6.0);
+ buffertop_tryadd(bt, 0.0, 7.0);
+ lu_assert_int_eq(buffertop_size(bt), 3);
+
+ buffertop_clear(bt);
+ lu_assert(buffertop_empty(bt));
+ buffertop_destroy(bt);
}
void t_buffertop_push_pop_basic()
{
- BufferTop* bt = buffertop_new(int, 5, MIN_T, 3);
-
- buffertop_tryadd(bt, 1, 2.0);
- buffertop_tryadd(bt, 2, 6.0);
- buffertop_tryadd(bt, 3, 4.0);
- buffertop_tryadd(bt, 4, 8.0);
- buffertop_tryadd(bt, 5, 3.0);
- buffertop_tryadd(bt, 6, 1.0);
- buffertop_tryadd(bt, 7, 5.0);
- buffertop_tryadd(bt, 8, 7.0);
-
- int a;
- buffertop_first(bt, a);
- lu_assert_int_eq(a, 7); //7 -> 5.0
- buffertop_pop(bt);
- buffertop_first(bt, a);
- lu_assert_int_eq(a, 3); //3 -> 4.0
- buffertop_pop(bt);
- buffertop_first(bt, a);
- lu_assert_int_eq(a, 5); //5 -> 3.0
- buffertop_pop(bt);
- buffertop_first(bt, a);
- lu_assert_int_eq(a, 1); //1 -> 2.0
- buffertop_pop(bt);
- buffertop_first(bt, a);
- lu_assert_int_eq(a, 6); //6 has "highest" priority (1.0, MIN_T)
- buffertop_pop(bt);
-
- lu_assert(buffertop_empty(bt));
- buffertop_destroy(bt);
+ BufferTop* bt = buffertop_new(int, 5, MIN_T, 3);
+
+ buffertop_tryadd(bt, 1, 2.0);
+ buffertop_tryadd(bt, 2, 6.0);
+ buffertop_tryadd(bt, 3, 4.0);
+ buffertop_tryadd(bt, 4, 8.0);
+ buffertop_tryadd(bt, 5, 3.0);
+ buffertop_tryadd(bt, 6, 1.0);
+ buffertop_tryadd(bt, 7, 5.0);
+ buffertop_tryadd(bt, 8, 7.0);
+
+ int a;
+ buffertop_first(bt, a);
+ lu_assert_int_eq(a, 7); //7 -> 5.0
+ buffertop_pop(bt);
+ buffertop_first(bt, a);
+ lu_assert_int_eq(a, 3); //3 -> 4.0
+ buffertop_pop(bt);
+ buffertop_first(bt, a);
+ lu_assert_int_eq(a, 5); //5 -> 3.0
+ buffertop_pop(bt);
+ buffertop_first(bt, a);
+ lu_assert_int_eq(a, 1); //1 -> 2.0
+ buffertop_pop(bt);
+ buffertop_first(bt, a);
+ lu_assert_int_eq(a, 6); //6 has "highest" priority (1.0, MIN_T)
+ buffertop_pop(bt);
+
+ lu_assert(buffertop_empty(bt));
+ buffertop_destroy(bt);
}
void t_buffertop_push_pop_evolved()
{
- int n = 10;
-
- BufferTop* bt = buffertop_new(StructTest1, 5, MAX_T, 2);
- StructTest1* st1 = (StructTest1*) safe_malloc(n * sizeof (StructTest1));
- for (int i = n - 1; i >= 0; i--)
- {
- st1[i].a = i;
- st1[i].b = (double) rand() / RAND_MAX;
- buffertop_tryadd(bt, *(st1 + i), i); //item i has value i
- }
- for (int i = n - buffertop_size(bt); i < n; i++)
- {
- StructTest1 st1Cell;
- buffertop_first(bt, st1Cell);
- lu_assert_int_eq(st1Cell.a, i);
- buffertop_pop(bt);
- }
- safe_free(st1);
- buffertop_destroy(bt);
-
- bt = buffertop_new(StructTest2*, 15, MAX_T, 4);
- StructTest2* st2 = (StructTest2*) safe_malloc(n * sizeof (StructTest2));
- for (int i = n - 1; i >= 0; i--)
- {
- st2[i].a = (float) rand() / RAND_MAX;
- st2[i].b = (StructTest1*) safe_malloc(sizeof (StructTest1));
- st2[i].b->a = i;
- st2[i].b->b = (double) rand() / RAND_MAX;
- // item i has value i+1 if i is even, i-1 if i is odd
- // that is to say, values are 1 0 3 2 5 4 ...
- buffertop_tryadd(bt, st2 + i, i % 2 == 0 ? i + 1 : i - 1);
- }
- for (int i = 0; i < n; i++)
- {
- StructTest2* st2Cell;
- buffertop_first(bt, st2Cell);
- // NOTE: i |--> i%2==0 ? i+1 : i-1 is an involution
- lu_assert_int_eq(st2Cell->b->a, i % 2 == 0 ? i + 1 : i - 1);
- buffertop_pop(bt);
- safe_free(st2Cell->b);
- }
- safe_free(st2);
- buffertop_destroy(bt);
+ int n = 10;
+
+ BufferTop* bt = buffertop_new(StructTest1, 5, MAX_T, 2);
+ StructTest1* st1 = (StructTest1*) safe_malloc(n * sizeof (StructTest1));
+ for (int i = n - 1; i >= 0; i--)
+ {
+ st1[i].a = i;
+ st1[i].b = (double) rand() / RAND_MAX;
+ buffertop_tryadd(bt, *(st1 + i), i); //item i has value i
+ }
+ for (int i = n - buffertop_size(bt); i < n; i++)
+ {
+ StructTest1 st1Cell;
+ buffertop_first(bt, st1Cell);
+ lu_assert_int_eq(st1Cell.a, i);
+ buffertop_pop(bt);
+ }
+ safe_free(st1);
+ buffertop_destroy(bt);
+
+ bt = buffertop_new(StructTest2*, 15, MAX_T, 4);
+ StructTest2* st2 = (StructTest2*) safe_malloc(n * sizeof (StructTest2));
+ for (int i = n - 1; i >= 0; i--)
+ {
+ st2[i].a = (float) rand() / RAND_MAX;
+ st2[i].b = (StructTest1*) safe_malloc(sizeof (StructTest1));
+ st2[i].b->a = i;
+ st2[i].b->b = (double) rand() / RAND_MAX;
+ // item i has value i+1 if i is even, i-1 if i is odd
+ // that is to say, values are 1 0 3 2 5 4 ...
+ buffertop_tryadd(bt, st2 + i, i % 2 == 0 ? i + 1 : i - 1);
+ }
+ for (int i = 0; i < n; i++)
+ {
+ StructTest2* st2Cell;
+ buffertop_first(bt, st2Cell);
+ // NOTE: i |--> i%2==0 ? i+1 : i-1 is an involution
+ lu_assert_int_eq(st2Cell->b->a, i % 2 == 0 ? i + 1 : i - 1);
+ buffertop_pop(bt);
+ safe_free(st2Cell->b);
+ }
+ safe_free(st2);
+ buffertop_destroy(bt);
}
void t_buffertop_copy()
{
- int n = 10;
-
- BufferTop* bt = buffertop_new(int, n, MIN_T, 3);
- for (int i = 0; i < n; i++)
- buffertop_tryadd(bt, rand() % 42, (double) rand() / RAND_MAX);
- BufferTop* btc = buffertop_copy(bt);
-
- lu_assert_int_eq(buffertop_size(bt), buffertop_size(btc));
- int a, b;
- for (int i = 0; i < n; i++)
- {
- buffertop_first(bt, a);
- buffertop_first(btc, b);
- lu_assert_int_eq(a, b);
- buffertop_pop(bt);
- buffertop_pop(btc);
- }
- buffertop_destroy(bt);
- buffertop_destroy(btc);
+ int n = 10;
+
+ BufferTop* bt = buffertop_new(int, n, MIN_T, 3);
+ for (int i = 0; i < n; i++)
+ buffertop_tryadd(bt, rand() % 42, (double) rand() / RAND_MAX);
+ BufferTop* btc = buffertop_copy(bt);
+
+ lu_assert_int_eq(buffertop_size(bt), buffertop_size(btc));
+ int a, b;
+ for (int i = 0; i < n; i++)
+ {
+ buffertop_first(bt, a);
+ buffertop_first(btc, b);
+ lu_assert_int_eq(a, b);
+ buffertop_pop(bt);
+ buffertop_pop(btc);
+ }
+ buffertop_destroy(bt);
+ buffertop_destroy(btc);
}
void t_heap_clear()
{
- Heap* h = heap_new(int, MIN_T, 2);
+ Heap* h = heap_new(int, MIN_T, 2);
- // NOTE: items with same priorities are supported;
- // since it is unused in this test, we arbitrarily choose 0.0
- heap_insert(h, 0, 0.0);
- heap_insert(h, 0, 0.0);
- heap_insert(h, 0, 0.0);
+ // NOTE: items with same priorities are supported;
+ // since it is unused in this test, we arbitrarily choose 0.0
+ heap_insert(h, 0, 0.0);
+ heap_insert(h, 0, 0.0);
+ heap_insert(h, 0, 0.0);
- heap_clear(h);
- lu_assert(heap_empty(h));
+ heap_clear(h);
+ lu_assert(heap_empty(h));
- heap_destroy(h);
+ heap_destroy(h);
}
void t_heap_size()
{
- Heap* h = heap_new(double, MAX_T, 3);
+ Heap* h = heap_new(double, MAX_T, 3);
- heap_insert(h, 0.0, 0.0);
- heap_insert(h, 0.0, 0.0);
- heap_insert(h, 0.0, 0.0);
- lu_assert_int_eq(heap_size(h), 3);
+ heap_insert(h, 0.0, 0.0);
+ heap_insert(h, 0.0, 0.0);
+ heap_insert(h, 0.0, 0.0);
+ lu_assert_int_eq(heap_size(h), 3);
- heap_insert(h, 0.0, 0.0);
- heap_insert(h, 0.0, 0.0);
- lu_assert_int_eq(heap_size(h), 5);
+ heap_insert(h, 0.0, 0.0);
+ heap_insert(h, 0.0, 0.0);
+ lu_assert_int_eq(heap_size(h), 5);
- heap_insert(h, 0.0, 0.0);
- heap_insert(h, 0.0, 0.0);
- heap_insert(h, 0.0, 0.0);
- lu_assert_int_eq(heap_size(h), 8);
+ heap_insert(h, 0.0, 0.0);
+ heap_insert(h, 0.0, 0.0);
+ heap_insert(h, 0.0, 0.0);
+ lu_assert_int_eq(heap_size(h), 8);
- heap_destroy(h);
+ heap_destroy(h);
}
void t_heap_push_pop_basic()
{
- Heap* h = heap_new(int, MIN_T, 3);
-
- heap_insert(h, 1, 1.0);
- heap_insert(h, 2, 3.0);
- heap_insert(h, 3, 2.0);
- heap_insert(h, 4, 4.0);
- heap_insert(h, 5, 0.0);
-
- int a;
- heap_top(h, a);
- lu_assert_int_eq(a, 5); //5 has "highest" priority (0.0, MIN_T)
- heap_pop(h);
- heap_top(h, a);
- lu_assert_int_eq(a, 1); //1 -> 1.0
- heap_pop(h);
- heap_top(h, a);
- lu_assert_int_eq(a, 3); //3 -> 2.0
- heap_pop(h);
- heap_top(h, a);
- lu_assert_int_eq(a, 2); //2 -> 3.0
- heap_pop(h);
- heap_top(h, a);
- lu_assert_int_eq(a, 4); //4 -> 4.0
- heap_pop(h);
- lu_assert(heap_empty(h));
-
- h->hType = MAX_T; //HACK... (why not?)
- heap_insert(h, 1, 1.0);
- heap_insert(h, 2, 3.0);
- heap_insert(h, 3, 2.0);
- heap_insert(h, 4, 4.0);
- heap_insert(h, 5, 7.0);
- heap_insert(h, 6, 5.0);
- heap_insert(h, 7, 6.0);
- heap_remove(h, 4);
- heap_remove(h, 2);
- heap_modify(h, 3, 4.0);
- heap_modify(h, 7, 3.0);
-
- heap_top(h, a);
- lu_assert_int_eq(a, 5); //5 has highest priority (7.0, MAX_T)
- heap_pop(h);
- heap_top(h, a);
- lu_assert_int_eq(a, 6); //6 -> 5.0
- heap_pop(h);
- heap_top(h, a);
- lu_assert_int_eq(a, 3); //3 -> 4.0
- heap_pop(h);
- heap_top(h, a);
- lu_assert_int_eq(a, 7); //7 -> 3.0
- heap_pop(h);
- heap_top(h, a);
- lu_assert_int_eq(a, 1); //1 -> 1.0
- heap_pop(h);
- lu_assert(heap_empty(h));
-
- heap_destroy(h);
+ Heap* h = heap_new(int, MIN_T, 3);
+
+ heap_insert(h, 1, 1.0);
+ heap_insert(h, 2, 3.0);
+ heap_insert(h, 3, 2.0);
+ heap_insert(h, 4, 4.0);
+ heap_insert(h, 5, 0.0);
+
+ int a;
+ heap_top(h, a);
+ lu_assert_int_eq(a, 5); //5 has "highest" priority (0.0, MIN_T)
+ heap_pop(h);
+ heap_top(h, a);
+ lu_assert_int_eq(a, 1); //1 -> 1.0
+ heap_pop(h);
+ heap_top(h, a);
+ lu_assert_int_eq(a, 3); //3 -> 2.0
+ heap_pop(h);
+ heap_top(h, a);
+ lu_assert_int_eq(a, 2); //2 -> 3.0
+ heap_pop(h);
+ heap_top(h, a);
+ lu_assert_int_eq(a, 4); //4 -> 4.0
+ heap_pop(h);
+ lu_assert(heap_empty(h));
+
+ h->hType = MAX_T; //HACK... (why not?)
+ heap_insert(h, 1, 1.0);
+ heap_insert(h, 2, 3.0);
+ heap_insert(h, 3, 2.0);
+ heap_insert(h, 4, 4.0);
+ heap_insert(h, 5, 7.0);
+ heap_insert(h, 6, 5.0);
+ heap_insert(h, 7, 6.0);
+ heap_remove(h, 4);
+ heap_remove(h, 2);
+ heap_modify(h, 3, 4.0);
+ heap_modify(h, 7, 3.0);
+
+ heap_top(h, a);
+ lu_assert_int_eq(a, 5); //5 has highest priority (7.0, MAX_T)
+ heap_pop(h);
+ heap_top(h, a);
+ lu_assert_int_eq(a, 6); //6 -> 5.0
+ heap_pop(h);
+ heap_top(h, a);
+ lu_assert_int_eq(a, 3); //3 -> 4.0
+ heap_pop(h);
+ heap_top(h, a);
+ lu_assert_int_eq(a, 7); //7 -> 3.0
+ heap_pop(h);
+ heap_top(h, a);
+ lu_assert_int_eq(a, 1); //1 -> 1.0
+ heap_pop(h);
+ lu_assert(heap_empty(h));
+
+ heap_destroy(h);
}
void t_heap_push_pop_evolved()
{
- int n = 10;
-
- Heap* h = heap_new(StructTest1, MAX_T, 2);
- StructTest1* st1 = (StructTest1*) safe_malloc(n * sizeof (StructTest1));
- for (int i = n - 1; i >= 0; i--)
- {
- st1[i].a = i;
- st1[i].b = (double) rand() / RAND_MAX;
- heap_insert(h, *(st1 + i), i); //item i has value i
- }
- for (int i = n - 1; i >= 0; i--)
- {
- StructTest1 st1Cell;
- heap_top(h, st1Cell);
- lu_assert_int_eq(st1Cell.a, i);
- heap_pop(h);
- }
- safe_free(st1);
- heap_destroy(h);
-
- h = heap_new(StructTest2*, MAX_T, 4);
- StructTest2* st2 = (StructTest2*) safe_malloc(n * sizeof (StructTest2));
- for (int i = n - 1; i >= 0; i--)
- {
- st2[i].a = (float) rand() / RAND_MAX;
- st2[i].b = (StructTest1*) safe_malloc(sizeof (StructTest1));
- st2[i].b->a = i;
- st2[i].b->b = (double) rand() / RAND_MAX;
- // item i has value i+1 if i is even, i-1 if i is odd
- // that is to say, values are 1 0 3 2 5 4 ...
- heap_insert(h, st2 + i, i % 2 == 0 ? i + 1 : i - 1);
- }
- for (int i = n - 1; i >= 0; i--)
- {
- StructTest2* st2Cell;
- heap_top(h, st2Cell);
- // NOTE: i |--> i%2==0 ? i+1 : i-1 is an involution
- lu_assert_int_eq(st2Cell->b->a, i % 2 == 0 ? i + 1 : i - 1);
- heap_pop(h);
- safe_free(st2Cell->b);
- }
- safe_free(st2);
- heap_destroy(h);
+ int n = 10;
+
+ Heap* h = heap_new(StructTest1, MAX_T, 2);
+ StructTest1* st1 = (StructTest1*) safe_malloc(n * sizeof (StructTest1));
+ for (int i = n - 1; i >= 0; i--)
+ {
+ st1[i].a = i;
+ st1[i].b = (double) rand() / RAND_MAX;
+ heap_insert(h, *(st1 + i), i); //item i has value i
+ }
+ for (int i = n - 1; i >= 0; i--)
+ {
+ StructTest1 st1Cell;
+ heap_top(h, st1Cell);
+ lu_assert_int_eq(st1Cell.a, i);
+ heap_pop(h);
+ }
+ safe_free(st1);
+ heap_destroy(h);
+
+ h = heap_new(StructTest2*, MAX_T, 4);
+ StructTest2* st2 = (StructTest2*) safe_malloc(n * sizeof (StructTest2));
+ for (int i = n - 1; i >= 0; i--)
+ {
+ st2[i].a = (float) rand() / RAND_MAX;
+ st2[i].b = (StructTest1*) safe_malloc(sizeof (StructTest1));
+ st2[i].b->a = i;
+ st2[i].b->b = (double) rand() / RAND_MAX;
+ // item i has value i+1 if i is even, i-1 if i is odd
+ // that is to say, values are 1 0 3 2 5 4 ...
+ heap_insert(h, st2 + i, i % 2 == 0 ? i + 1 : i - 1);
+ }
+ for (int i = n - 1; i >= 0; i--)
+ {
+ StructTest2* st2Cell;
+ heap_top(h, st2Cell);
+ // NOTE: i |--> i%2==0 ? i+1 : i-1 is an involution
+ lu_assert_int_eq(st2Cell->b->a, i % 2 == 0 ? i + 1 : i - 1);
+ heap_pop(h);
+ safe_free(st2Cell->b);
+ }
+ safe_free(st2);
+ heap_destroy(h);
}
void t_heap_copy()
{
- int n = 10;
-
- Heap* h = heap_new(int, MIN_T, 2);
- for (int i = 0; i < n; i++)
- heap_insert(h, rand() % 42, (double) rand() / RAND_MAX);
- Heap* hc = heap_copy(h);
-
- lu_assert_int_eq(heap_size(h), heap_size(hc));
- int a, b;
- for (int i = 0; i < n; i++)
- {
- heap_top(h, a);
- heap_top(hc, b);
- lu_assert_int_eq(a, b);
- heap_pop(h);
- heap_pop(hc);
- }
- heap_destroy(h);
- heap_destroy(hc);
+ int n = 10;
+
+ Heap* h = heap_new(int, MIN_T, 2);
+ for (int i = 0; i < n; i++)
+ heap_insert(h, rand() % 42, (double) rand() / RAND_MAX);
+ Heap* hc = heap_copy(h);
+
+ lu_assert_int_eq(heap_size(h), heap_size(hc));
+ int a, b;
+ for (int i = 0; i < n; i++)
+ {
+ heap_top(h, a);
+ heap_top(hc, b);
+ lu_assert_int_eq(a, b);
+ heap_pop(h);
+ heap_pop(hc);
+ }
+ heap_destroy(h);
+ heap_destroy(hc);
}
void t_list_clear()
{
- List* L = list_new(int);
+ List* L = list_new(int);
- list_insert_front(L, 0);
- list_insert_back(L, 0);
- list_insert_after(L, L->head, 0);
+ list_insert_front(L, 0);
+ list_insert_back(L, 0);
+ list_insert_after(L, L->head, 0);
- list_clear(L);
- lu_assert(list_empty(L));
+ list_clear(L);
+ lu_assert(list_empty(L));
- list_destroy(L);
+ list_destroy(L);
}
void t_list_size()
{
- List* L = list_new(double);
-
- list_insert_front(L, 0.0);
- list_insert_back(L, 0.0);
- list_insert_front(L, 0.0);
- lu_assert_int_eq(list_size(L), 3);
-
- list_insert_back(L, 0.0);
- list_insert_before(L, L->tail, 0.0);
- lu_assert_int_eq(list_size(L), 5);
-
- list_insert_after(L, L->head->next, 0.0);
- list_insert_before(L, L->tail->prev, 0.0);
- list_insert_after(L, L->head, 0.0);
- lu_assert_int_eq(list_size(L), 8);
-
- list_set(L, L->head->next, 42);
- list_remove_front(L);
- int a;
- list_get(L->head, a);
- lu_assert_int_eq(a, 42);
- list_remove(L, L->head->next);
- lu_assert_int_eq(list_size(L), 6);
- list_set(L, L->tail, 32);
- list_remove(L, L->tail->prev);
- list_get(L->tail, a);
- lu_assert_int_eq(a, 32);
- lu_assert_int_eq(list_size(L), 5);
-
- list_destroy(L);
+ List* L = list_new(double);
+
+ list_insert_front(L, 0.0);
+ list_insert_back(L, 0.0);
+ list_insert_front(L, 0.0);
+ lu_assert_int_eq(list_size(L), 3);
+
+ list_insert_back(L, 0.0);
+ list_insert_before(L, L->tail, 0.0);
+ lu_assert_int_eq(list_size(L), 5);
+
+ list_insert_after(L, L->head->next, 0.0);
+ list_insert_before(L, L->tail->prev, 0.0);
+ list_insert_after(L, L->head, 0.0);
+ lu_assert_int_eq(list_size(L), 8);
+
+ list_set(L, L->head->next, 42);
+ list_remove_front(L);
+ int a;
+ list_get(L->head, a);
+ lu_assert_int_eq(a, 42);
+ list_remove(L, L->head->next);
+ lu_assert_int_eq(list_size(L), 6);
+ list_set(L, L->tail, 32);
+ list_remove(L, L->tail->prev);
+ list_get(L->tail, a);
+ lu_assert_int_eq(a, 32);
+ lu_assert_int_eq(list_size(L), 5);
+
+ list_destroy(L);
}
void t_list_push_pop_basic()
{
- int n = 10;
-
- List* L = list_new(double);
- for (int i = 0; i < n; i++) list_insert_back(L, (double) i);
- // iterate and check values
- ListIterator* li = list_get_iterator(L);
- double ckValue = 0.0;
- while (listI_has_data(li))
- {
- double d;
- listI_get(li, d);
- lu_assert_dbl_eq(d, ckValue);
- ckValue += 1.0;
- listI_move_next(li);
- }
-
- // same, from end to beginning
- ckValue = n - 1;
- listI_reset_tail(li);
- while (listI_has_data(li))
- {
- double d;
- listI_get(li, d);
- lu_assert_dbl_eq(d, ckValue);
- ckValue -= 1.0;
- listI_move_prev(li);
- }
- list_destroy(L);
- listI_destroy(li);
+ int n = 10;
+
+ List* L = list_new(double);
+ for (int i = 0; i < n; i++) list_insert_back(L, (double) i);
+ // iterate and check values
+ ListIterator* li = list_get_iterator(L);
+ double ckValue = 0.0;
+ while (listI_has_data(li))
+ {
+ double d;
+ listI_get(li, d);
+ lu_assert_dbl_eq(d, ckValue);
+ ckValue += 1.0;
+ listI_move_next(li);
+ }
+
+ // same, from end to beginning
+ ckValue = n - 1;
+ listI_reset_tail(li);
+ while (listI_has_data(li))
+ {
+ double d;
+ listI_get(li, d);
+ lu_assert_dbl_eq(d, ckValue);
+ ckValue -= 1.0;
+ listI_move_prev(li);
+ }
+ list_destroy(L);
+ listI_destroy(li);
}
void t_list_push_pop_evolved()
{
- int n = 10;
-
- List* L = list_new(StructTest1);
- StructTest1* st1 = (StructTest1*) malloc(n * sizeof (StructTest1));
- for (int i = 0; i < n; i++)
- {
- st1[i].a = rand() % 42;
- st1[i].b = (double) rand() / RAND_MAX;
- list_insert_back(L, *(st1 + i));
- }
- ListCell* lc = L->head;
- for (int i = 0; i < n; i++)
- {
- //another way to access elements
- StructTest1 st1Cell;
- list_get(lc, st1Cell);
- lu_assert_int_eq(st1Cell.a, st1[i].a);
- lu_assert_dbl_eq(st1Cell.b, st1[i].b);
- lc = lc->next;
- }
- safe_free(st1);
- list_destroy(L);
-
- L = list_new(StructTest2*);
- StructTest2* st2 = (StructTest2*) malloc(n * sizeof (StructTest2));
- for (int i = 0; i < n; i++)
- {
- st2[i].a = (float) rand() / RAND_MAX;
- st2[i].b = (StructTest1*) malloc(sizeof (StructTest1));
- st2[i].b->a = rand() % 42;
- st2[i].b->b = (double) rand() / RAND_MAX;
- list_insert_back(L, st2 + i);
- }
- lc = L->head;
- for (int i = 0; i < n; i++)
- {
- StructTest2* st2Cell;
- list_get(lc, st2Cell);
- lu_assert_dbl_eq(st2Cell->a, st2[i].a);
- lu_assert_int_eq(st2Cell->b->a, st2[i].b->a);
- lu_assert_dbl_eq(st2Cell->b->b, st2[i].b->b);
- safe_free(st2Cell->b);
- lc = lc->next;
- }
- safe_free(st2);
- list_destroy(L);
+ int n = 10;
+
+ List* L = list_new(StructTest1);
+ StructTest1* st1 = (StructTest1*) malloc(n * sizeof (StructTest1));
+ for (int i = 0; i < n; i++)
+ {
+ st1[i].a = rand() % 42;
+ st1[i].b = (double) rand() / RAND_MAX;
+ list_insert_back(L, *(st1 + i));
+ }
+ ListCell* lc = L->head;
+ for (int i = 0; i < n; i++)
+ {
+ //another way to access elements
+ StructTest1 st1Cell;
+ list_get(lc, st1Cell);
+ lu_assert_int_eq(st1Cell.a, st1[i].a);
+ lu_assert_dbl_eq(st1Cell.b, st1[i].b);
+ lc = lc->next;
+ }
+ safe_free(st1);
+ list_destroy(L);
+
+ L = list_new(StructTest2*);
+ StructTest2* st2 = (StructTest2*) malloc(n * sizeof (StructTest2));
+ for (int i = 0; i < n; i++)
+ {
+ st2[i].a = (float) rand() / RAND_MAX;
+ st2[i].b = (StructTest1*) malloc(sizeof (StructTest1));
+ st2[i].b->a = rand() % 42;
+ st2[i].b->b = (double) rand() / RAND_MAX;
+ list_insert_back(L, st2 + i);
+ }
+ lc = L->head;
+ for (int i = 0; i < n; i++)
+ {
+ StructTest2* st2Cell;
+ list_get(lc, st2Cell);
+ lu_assert_dbl_eq(st2Cell->a, st2[i].a);
+ lu_assert_int_eq(st2Cell->b->a, st2[i].b->a);
+ lu_assert_dbl_eq(st2Cell->b->b, st2[i].b->b);
+ safe_free(st2Cell->b);
+ lc = lc->next;
+ }
+ safe_free(st2);
+ list_destroy(L);
}
void t_list_copy()
{
- int n = 10;
-
- List* L = list_new(int);
- for (int i = 0; i < n; i++)
- list_insert_front(L, rand() % 42);
- List* Lc = list_copy(L);
-
- lu_assert_int_eq(L->size, Lc->size);
- ListCell* lCell = L->head;
- ListCell* lcCell = Lc->head;
- int a, b;
- for (int i = 0; i < n; i++)
- {
- list_get(lCell, a);
- list_get(lcCell, b);
- lu_assert_int_eq(a, b);
- lCell = lCell->next;
- lcCell = lcCell->next;
- }
- list_destroy(L);
- list_destroy(Lc);
+ int n = 10;
+
+ List* L = list_new(int);
+ for (int i = 0; i < n; i++)
+ list_insert_front(L, rand() % 42);
+ List* Lc = list_copy(L);
+
+ lu_assert_int_eq(L->size, Lc->size);
+ ListCell* lCell = L->head;
+ ListCell* lcCell = Lc->head;
+ int a, b;
+ for (int i = 0; i < n; i++)
+ {
+ list_get(lCell, a);
+ list_get(lcCell, b);
+ lu_assert_int_eq(a, b);
+ lCell = lCell->next;
+ lcCell = lcCell->next;
+ }
+ list_destroy(L);
+ list_destroy(Lc);
}
void t_priorityqueue_clear()
{
- PriorityQueue* pq = priorityqueue_new(int, MIN_T, 2);
+ PriorityQueue* pq = priorityqueue_new(int, MIN_T, 2);
- // NOTE: items with same priorities are supported;
- // since it is unused in this test, we arbitrarily choose 0.0
- priorityqueue_insert(pq, 0, 0.0);
- priorityqueue_insert(pq, 0, 0.0);
- priorityqueue_insert(pq, 0, 0.0);
+ // NOTE: items with same priorities are supported;
+ // since it is unused in this test, we arbitrarily choose 0.0
+ priorityqueue_insert(pq, 0, 0.0);
+ priorityqueue_insert(pq, 0, 0.0);
+ priorityqueue_insert(pq, 0, 0.0);
- priorityqueue_clear(pq);
- lu_assert(priorityqueue_empty(pq));
+ priorityqueue_clear(pq);
+ lu_assert(priorityqueue_empty(pq));
- priorityqueue_destroy(pq);
+ priorityqueue_destroy(pq);
}
void t_priorityqueue_size()
{
- PriorityQueue* pq = priorityqueue_new(double, MAX_T, 3);
+ PriorityQueue* pq = priorityqueue_new(double, MAX_T, 3);
- priorityqueue_insert(pq, 0.0, 0.0);
- priorityqueue_insert(pq, 0.0, 0.0);
- priorityqueue_insert(pq, 0.0, 0.0);
- lu_assert_int_eq(priorityqueue_size(pq), 3);
+ priorityqueue_insert(pq, 0.0, 0.0);
+ priorityqueue_insert(pq, 0.0, 0.0);
+ priorityqueue_insert(pq, 0.0, 0.0);
+ lu_assert_int_eq(priorityqueue_size(pq), 3);
- priorityqueue_insert(pq, 0.0, 0.0);
- priorityqueue_insert(pq, 0.0, 0.0);
- lu_assert_int_eq(priorityqueue_size(pq), 5);
+ priorityqueue_insert(pq, 0.0, 0.0);
+ priorityqueue_insert(pq, 0.0, 0.0);
+ lu_assert_int_eq(priorityqueue_size(pq), 5);
- priorityqueue_insert(pq, 0.0, 0.0);
- priorityqueue_insert(pq, 0.0, 0.0);
- priorityqueue_insert(pq, 0.0, 0.0);
- lu_assert_int_eq(priorityqueue_size(pq), 8);
+ priorityqueue_insert(pq, 0.0, 0.0);
+ priorityqueue_insert(pq, 0.0, 0.0);
+ priorityqueue_insert(pq, 0.0, 0.0);
+ lu_assert_int_eq(priorityqueue_size(pq), 8);
- priorityqueue_destroy(pq);
+ priorityqueue_destroy(pq);
}
void t_priorityqueue_push_pop_basic()
{
- PriorityQueue* pq = priorityqueue_new(int, MIN_T, 3);
-
- priorityqueue_insert(pq, 1, 1.0);
- priorityqueue_insert(pq, 2, 3.0);
- priorityqueue_insert(pq, 3, 2.0);
- priorityqueue_insert(pq, 4, 4.0);
- priorityqueue_insert(pq, 5, 0.0);
-
- int a;
- priorityqueue_peek(pq, a);
- lu_assert_int_eq(a, 5); //5 has "highest" priority (0.0, MIN_T)
- priorityqueue_pop(pq);
- priorityqueue_peek(pq, a);
- lu_assert_int_eq(a, 1); //1 -> 1.0
- priorityqueue_pop(pq);
- priorityqueue_peek(pq, a);
- lu_assert_int_eq(a, 3); //3 -> 2.0
- priorityqueue_pop(pq);
- priorityqueue_peek(pq, a);
- lu_assert_int_eq(a, 2); //2 -> 3.0
- priorityqueue_pop(pq);
- priorityqueue_peek(pq, a);
- lu_assert_int_eq(a, 4); //4 -> 4.0
- priorityqueue_pop(pq);
- lu_assert(priorityqueue_empty(pq));
-
- pq->heap->hType = MAX_T; //HACK... (why not?)
- priorityqueue_insert(pq, 1, 1.0);
- priorityqueue_insert(pq, 2, 3.0);
- priorityqueue_insert(pq, 3, 2.0);
- priorityqueue_insert(pq, 4, 4.0);
- priorityqueue_insert(pq, 5, 0.0);
- priorityqueue_insert(pq, 6, 0.0);
- priorityqueue_insert(pq, 7, 6.0);
- priorityqueue_remove(pq, 6);
- priorityqueue_remove(pq, 7);
- priorityqueue_set(pq, 3, 5.0);
- priorityqueue_set(pq, 5, 2.0);
-
- priorityqueue_peek(pq, a);
- lu_assert_int_eq(a, 3); //3 has highest priority (5.0, MAX_T)
- priorityqueue_pop(pq);
- priorityqueue_peek(pq, a);
- lu_assert_int_eq(a, 4); //4 -> 4.0
- priorityqueue_pop(pq);
- priorityqueue_peek(pq, a);
- lu_assert_int_eq(a, 2); //2 -> 3.0
- priorityqueue_pop(pq);
- priorityqueue_peek(pq, a);
- lu_assert_int_eq(a, 5); //5 -> 2.0
- priorityqueue_pop(pq);
- priorityqueue_peek(pq, a);
- lu_assert_int_eq(a, 1); // 1 -> 1.0
- priorityqueue_pop(pq);
-
- lu_assert(priorityqueue_empty(pq));
- priorityqueue_destroy(pq);
+ PriorityQueue* pq = priorityqueue_new(int, MIN_T, 3);
+
+ priorityqueue_insert(pq, 1, 1.0);
+ priorityqueue_insert(pq, 2, 3.0);
+ priorityqueue_insert(pq, 3, 2.0);
+ priorityqueue_insert(pq, 4, 4.0);
+ priorityqueue_insert(pq, 5, 0.0);
+
+ int a;
+ priorityqueue_peek(pq, a);
+ lu_assert_int_eq(a, 5); //5 has "highest" priority (0.0, MIN_T)
+ priorityqueue_pop(pq);
+ priorityqueue_peek(pq, a);
+ lu_assert_int_eq(a, 1); //1 -> 1.0
+ priorityqueue_pop(pq);
+ priorityqueue_peek(pq, a);
+ lu_assert_int_eq(a, 3); //3 -> 2.0
+ priorityqueue_pop(pq);
+ priorityqueue_peek(pq, a);
+ lu_assert_int_eq(a, 2); //2 -> 3.0
+ priorityqueue_pop(pq);
+ priorityqueue_peek(pq, a);
+ lu_assert_int_eq(a, 4); //4 -> 4.0
+ priorityqueue_pop(pq);
+ lu_assert(priorityqueue_empty(pq));
+
+ pq->heap->hType = MAX_T; //HACK... (why not?)
+ priorityqueue_insert(pq, 1, 1.0);
+ priorityqueue_insert(pq, 2, 3.0);
+ priorityqueue_insert(pq, 3, 2.0);
+ priorityqueue_insert(pq, 4, 4.0);
+ priorityqueue_insert(pq, 5, 0.0);
+ priorityqueue_insert(pq, 6, 0.0);
+ priorityqueue_insert(pq, 7, 6.0);
+ priorityqueue_remove(pq, 6);
+ priorityqueue_remove(pq, 7);
+ priorityqueue_set(pq, 3, 5.0);
+ priorityqueue_set(pq, 5, 2.0);
+
+ priorityqueue_peek(pq, a);
+ lu_assert_int_eq(a, 3); //3 has highest priority (5.0, MAX_T)
+ priorityqueue_pop(pq);
+ priorityqueue_peek(pq, a);
+ lu_assert_int_eq(a, 4); //4 -> 4.0
+ priorityqueue_pop(pq);
+ priorityqueue_peek(pq, a);
+ lu_assert_int_eq(a, 2); //2 -> 3.0
+ priorityqueue_pop(pq);
+ priorityqueue_peek(pq, a);
+ lu_assert_int_eq(a, 5); //5 -> 2.0
+ priorityqueue_pop(pq);
+ priorityqueue_peek(pq, a);
+ lu_assert_int_eq(a, 1); // 1 -> 1.0
+ priorityqueue_pop(pq);
+
+ lu_assert(priorityqueue_empty(pq));
+ priorityqueue_destroy(pq);
}
void t_priorityqueue_push_pop_evolved()
{
- int n = 10;
-
- PriorityQueue* pq = priorityqueue_new(StructTest1, MAX_T, 2);
- StructTest1* st1 = (StructTest1*) safe_malloc(n * sizeof (StructTest1));
- for (int i = n - 1; i >= 0; i--)
- {
- st1[i].a = i;
- st1[i].b = (double) rand() / RAND_MAX;
- priorityqueue_insert(pq, *(st1 + i), i); //item i has priority i
- }
- for (int i = n - 1; i >= 0; i--)
- {
- StructTest1 st1Cell;
- priorityqueue_peek(pq, st1Cell);
- lu_assert_int_eq(st1Cell.a, i);
- priorityqueue_pop(pq);
- }
- safe_free(st1);
- priorityqueue_destroy(pq);
-
- pq = priorityqueue_new(StructTest2*, MAX_T, 4);
- StructTest2* st2 = (StructTest2*) safe_malloc(n * sizeof (StructTest2));
- for (int i = n - 1; i >= 0; i--)
- {
- st2[i].a = (float) rand() / RAND_MAX;
- st2[i].b = (StructTest1*) safe_malloc(sizeof (StructTest1));
- st2[i].b->a = i;
- st2[i].b->b = (double) rand() / RAND_MAX;
- // item i has priority i+1 if i is even, i-1 if i is odd
- // that is to say, priorities are 1 0 3 2 5 4 ...
- priorityqueue_insert(pq, st2 + i, i % 2 == 0 ? i + 1 : i - 1);
- }
- for (int i = n - 1; i >= 0; i--)
- {
- StructTest2* st2Cell;
- priorityqueue_peek(pq, st2Cell);
- // NOTE: i |--> i%2==0 ? i+1 : i-1 is an involution
- lu_assert_int_eq(st2Cell->b->a, i % 2 == 0 ? i + 1 : i - 1);
- priorityqueue_pop(pq);
- safe_free(st2Cell->b);
- }
- safe_free(st2);
- priorityqueue_destroy(pq);
+ int n = 10;
+
+ PriorityQueue* pq = priorityqueue_new(StructTest1, MAX_T, 2);
+ StructTest1* st1 = (StructTest1*) safe_malloc(n * sizeof (StructTest1));
+ for (int i = n - 1; i >= 0; i--)
+ {
+ st1[i].a = i;
+ st1[i].b = (double) rand() / RAND_MAX;
+ priorityqueue_insert(pq, *(st1 + i), i); //item i has priority i
+ }
+ for (int i = n - 1; i >= 0; i--)
+ {
+ StructTest1 st1Cell;
+ priorityqueue_peek(pq, st1Cell);
+ lu_assert_int_eq(st1Cell.a, i);
+ priorityqueue_pop(pq);
+ }
+ safe_free(st1);
+ priorityqueue_destroy(pq);
+
+ pq = priorityqueue_new(StructTest2*, MAX_T, 4);
+ StructTest2* st2 = (StructTest2*) safe_malloc(n * sizeof (StructTest2));
+ for (int i = n - 1; i >= 0; i--)
+ {
+ st2[i].a = (float) rand() / RAND_MAX;
+ st2[i].b = (StructTest1*) safe_malloc(sizeof (StructTest1));
+ st2[i].b->a = i;
+ st2[i].b->b = (double) rand() / RAND_MAX;
+ // item i has priority i+1 if i is even, i-1 if i is odd
+ // that is to say, priorities are 1 0 3 2 5 4 ...
+ priorityqueue_insert(pq, st2 + i, i % 2 == 0 ? i + 1 : i - 1);
+ }
+ for (int i = n - 1; i >= 0; i--)
+ {
+ StructTest2* st2Cell;
+ priorityqueue_peek(pq, st2Cell);
+ // NOTE: i |--> i%2==0 ? i+1 : i-1 is an involution
+ lu_assert_int_eq(st2Cell->b->a, i % 2 == 0 ? i + 1 : i - 1);
+ priorityqueue_pop(pq);
+ safe_free(st2Cell->b);
+ }
+ safe_free(st2);
+ priorityqueue_destroy(pq);
}
void t_priorityqueue_copy()
{
- int n = 10;
-
- PriorityQueue* pq = priorityqueue_new(int, MIN_T, 3);
- for (int i = 0; i < n; i++)
- priorityqueue_insert(pq, rand() % 42, (double) rand() / RAND_MAX);
- PriorityQueue* pqc = priorityqueue_copy(pq);
-
- lu_assert_int_eq(priorityqueue_size(pq), priorityqueue_size(pqc));
- int a, b;
- for (int i = 0; i < n; i++)
- {
- priorityqueue_peek(pq, a);
- priorityqueue_peek(pqc, b);
- lu_assert_int_eq(a, b);
- priorityqueue_pop(pq);
- priorityqueue_pop(pqc);
- }
- priorityqueue_destroy(pq);
- priorityqueue_destroy(pqc);
+ int n = 10;
+
+ PriorityQueue* pq = priorityqueue_new(int, MIN_T, 3);
+ for (int i = 0; i < n; i++)
+ priorityqueue_insert(pq, rand() % 42, (double) rand() / RAND_MAX);
+ PriorityQueue* pqc = priorityqueue_copy(pq);
+
+ lu_assert_int_eq(priorityqueue_size(pq), priorityqueue_size(pqc));
+ int a, b;
+ for (int i = 0; i < n; i++)
+ {
+ priorityqueue_peek(pq, a);
+ priorityqueue_peek(pqc, b);
+ lu_assert_int_eq(a, b);
+ priorityqueue_pop(pq);
+ priorityqueue_pop(pqc);
+ }
+ priorityqueue_destroy(pq);
+ priorityqueue_destroy(pqc);
}
void t_queue_clear()
{
- Queue* q = queue_new(int);
+ Queue* q = queue_new(int);
- queue_push(q, 0);
- queue_push(q, 0);
- queue_push(q, 0);
+ queue_push(q, 0);
+ queue_push(q, 0);
+ queue_push(q, 0);
- queue_clear(q);
- lu_assert(queue_empty(q));
+ queue_clear(q);
+ lu_assert(queue_empty(q));
- queue_destroy(q);
+ queue_destroy(q);
}
void t_queue_size()
{
- Queue* q = queue_new(int);
+ Queue* q = queue_new(int);
- queue_push(q, 0);
- queue_push(q, 0);
- queue_push(q, 0);
- lu_assert_int_eq(queue_size(q), 3);
+ queue_push(q, 0);
+ queue_push(q, 0);
+ queue_push(q, 0);
+ lu_assert_int_eq(queue_size(q), 3);
- queue_push(q, 0);
- queue_push(q, 0);
- lu_assert_int_eq(queue_size(q), 5);
+ queue_push(q, 0);
+ queue_push(q, 0);
+ lu_assert_int_eq(queue_size(q), 5);
- queue_push(q, 0);
- queue_push(q, 0);
- queue_push(q, 0);
- lu_assert_int_eq(queue_size(q), 8);
+ queue_push(q, 0);
+ queue_push(q, 0);
+ queue_push(q, 0);
+ lu_assert_int_eq(queue_size(q), 8);
- queue_destroy(q);
+ queue_destroy(q);
}
void t_queue_push_pop_basic()
{
- int n = 10;
-
- Queue* q = queue_new(double);
- for (int i = 0; i < n; i++)
- queue_push(q, (double) i);
- // iterate and check values
- double ckValue = 0.0;
- while (!queue_empty(q))
- {
- double d;
- queue_peek(q, d);
- lu_assert_dbl_eq(d, ckValue);
- ckValue += 1.0;
- queue_pop(q);
- }
-
- lu_assert(queue_empty(q));
- queue_destroy(q);
+ int n = 10;
+
+ Queue* q = queue_new(double);
+ for (int i = 0; i < n; i++)
+ queue_push(q, (double) i);
+ // iterate and check values
+ double ckValue = 0.0;
+ while (!queue_empty(q))
+ {
+ double d;
+ queue_peek(q, d);
+ lu_assert_dbl_eq(d, ckValue);
+ ckValue += 1.0;
+ queue_pop(q);
+ }
+
+ lu_assert(queue_empty(q));
+ queue_destroy(q);
}
void t_queue_push_pop_evolved()
{
- int n = 10;
-
- Queue* q = queue_new(StructTest1);
- StructTest1* st1 = (StructTest1*) safe_malloc(n * sizeof (StructTest1));
- for (int i = 0; i < n; i++)
- {
- st1[i].a = rand() % 42;
- st1[i].b = (double) rand() / RAND_MAX;
- queue_push(q, *(st1 + i));
- }
- for (int i = 0; i < n; i++)
- {
- StructTest1 st1Cell;
- queue_peek(q, st1Cell);
- lu_assert_int_eq(st1Cell.a, st1[i].a);
- lu_assert_dbl_eq(st1Cell.b, st1[i].b);
- queue_pop(q);
- }
- safe_free(st1);
- queue_destroy(q);
-
- q = queue_new(StructTest2*);
- StructTest2* st2 = (StructTest2*) safe_malloc(n * sizeof (StructTest2));
- for (int i = 0; i < n; i++)
- {
- st2[i].a = (float) rand() / RAND_MAX;
- st2[i].b = (StructTest1*) safe_malloc(sizeof (StructTest1));
- st2[i].b->a = rand() % 42;
- st2[i].b->b = (double) rand() / RAND_MAX;
- queue_push(q, st2 + i);
- }
- for (int i = 0; i < n; i++)
- {
- StructTest2* st2Cell;
- queue_peek(q, st2Cell);
- lu_assert_dbl_eq(st2Cell->a, st2[i].a);
- lu_assert_int_eq(st2Cell->b->a, st2[i].b->a);
- lu_assert_dbl_eq(st2Cell->b->b, st2[i].b->b);
- queue_pop(q);
- safe_free(st2Cell->b);
- }
- safe_free(st2);
- queue_destroy(q);
+ int n = 10;
+
+ Queue* q = queue_new(StructTest1);
+ StructTest1* st1 = (StructTest1*) safe_malloc(n * sizeof (StructTest1));
+ for (int i = 0; i < n; i++)
+ {
+ st1[i].a = rand() % 42;
+ st1[i].b = (double) rand() / RAND_MAX;
+ queue_push(q, *(st1 + i));
+ }
+ for (int i = 0; i < n; i++)
+ {
+ StructTest1 st1Cell;
+ queue_peek(q, st1Cell);
+ lu_assert_int_eq(st1Cell.a, st1[i].a);
+ lu_assert_dbl_eq(st1Cell.b, st1[i].b);
+ queue_pop(q);
+ }
+ safe_free(st1);
+ queue_destroy(q);
+
+ q = queue_new(StructTest2*);
+ StructTest2* st2 = (StructTest2*) safe_malloc(n * sizeof (StructTest2));
+ for (int i = 0; i < n; i++)
+ {
+ st2[i].a = (float) rand() / RAND_MAX;
+ st2[i].b = (StructTest1*) safe_malloc(sizeof (StructTest1));
+ st2[i].b->a = rand() % 42;
+ st2[i].b->b = (double) rand() / RAND_MAX;
+ queue_push(q, st2 + i);
+ }
+ for (int i = 0; i < n; i++)
+ {
+ StructTest2* st2Cell;
+ queue_peek(q, st2Cell);
+ lu_assert_dbl_eq(st2Cell->a, st2[i].a);
+ lu_assert_int_eq(st2Cell->b->a, st2[i].b->a);
+ lu_assert_dbl_eq(st2Cell->b->b, st2[i].b->b);
+ queue_pop(q);
+ safe_free(st2Cell->b);
+ }
+ safe_free(st2);
+ queue_destroy(q);
}
void t_queue_copy()
{
- int n = 10;
-
- Queue* q = queue_new(int);
- for (int i = 0; i < n; i++)
- queue_push(q, rand() % 42);
- Queue* qc = queue_copy(q);
-
- lu_assert_int_eq(queue_size(q), queue_size(qc));
- int a, b;
- for (int i = 0; i < n; i++)
- {
- queue_peek(q, a);
- queue_peek(qc, b);
- lu_assert_int_eq(a, b);
- queue_pop(q);
- queue_pop(qc);
- }
- queue_destroy(q);
- queue_destroy(qc);
+ int n = 10;
+
+ Queue* q = queue_new(int);
+ for (int i = 0; i < n; i++)
+ queue_push(q, rand() % 42);
+ Queue* qc = queue_copy(q);
+
+ lu_assert_int_eq(queue_size(q), queue_size(qc));
+ int a, b;
+ for (int i = 0; i < n; i++)
+ {
+ queue_peek(q, a);
+ queue_peek(qc, b);
+ lu_assert_int_eq(a, b);
+ queue_pop(q);
+ queue_pop(qc);
+ }
+ queue_destroy(q);
+ queue_destroy(qc);
}
void t_stack_clear()
{
- Stack* s = stack_new(int);
+ Stack* s = stack_new(int);
- stack_push(s, 0);
- stack_push(s, 0);
- stack_push(s, 0);
+ stack_push(s, 0);
+ stack_push(s, 0);
+ stack_push(s, 0);
- stack_clear(s);
- lu_assert(stack_empty(s));
+ stack_clear(s);
+ lu_assert(stack_empty(s));
- stack_destroy(s);
+ stack_destroy(s);
}
void t_stack_size()
{
- Stack* s = stack_new(int);
+ Stack* s = stack_new(int);
- stack_push(s, 0);
- stack_push(s, 0);
- stack_push(s, 0);
- lu_assert_int_eq(stack_size(s), 3);
+ stack_push(s, 0);
+ stack_push(s, 0);
+ stack_push(s, 0);
+ lu_assert_int_eq(stack_size(s), 3);
- stack_push(s, 0);
- stack_push(s, 0);
- lu_assert_int_eq(stack_size(s), 5);
+ stack_push(s, 0);
+ stack_push(s, 0);
+ lu_assert_int_eq(stack_size(s), 5);
- stack_push(s, 0);
- stack_push(s, 0);
- stack_push(s, 0);
- lu_assert_int_eq(stack_size(s), 8);
+ stack_push(s, 0);
+ stack_push(s, 0);
+ stack_push(s, 0);
+ lu_assert_int_eq(stack_size(s), 8);
- stack_destroy(s);
+ stack_destroy(s);
}
void t_stack_push_pop_basic()
{
- int n = 10;
-
- Stack* s = stack_new(double);
- for (int i = 0; i < n; i++)
- stack_push(s, (double) i);
- // iterate and check values
- double ckValue = n - 1;
- while (!stack_empty(s))
- {
- double d;
- stack_top(s, d);
- lu_assert_dbl_eq(d, ckValue);
- ckValue -= 1.0;
- stack_pop(s);
- }
-
- lu_assert(stack_empty(s));
- stack_destroy(s);
+ int n = 10;
+
+ Stack* s = stack_new(double);
+ for (int i = 0; i < n; i++)
+ stack_push(s, (double) i);
+ // iterate and check values
+ double ckValue = n - 1;
+ while (!stack_empty(s))
+ {
+ double d;
+ stack_top(s, d);
+ lu_assert_dbl_eq(d, ckValue);
+ ckValue -= 1.0;
+ stack_pop(s);
+ }
+
+ lu_assert(stack_empty(s));
+ stack_destroy(s);
}
void t_stack_push_pop_evolved()
{
- Stack* s = stack_new(StructTest1);
-
- int n = 10;
- StructTest1* st1 = (StructTest1*) malloc(n * sizeof (StructTest1));
- for (int i = n - 1; i >= 0; i--)
- {
- st1[i].a = rand() % 42;
- st1[i].b = (double) rand() / RAND_MAX;
- stack_push(s, *(st1 + i));
- }
- for (int i = 0; i < n; i++)
- {
- StructTest1 st1Cell;
- stack_top(s, st1Cell);
- lu_assert_int_eq(st1Cell.a, st1[i].a);
- lu_assert_dbl_eq(st1Cell.b, st1[i].b);
- stack_pop(s);
- }
- safe_free(st1);
- stack_destroy(s);
-
- s = stack_new(StructTest2*);
- StructTest2* st2 = (StructTest2*) malloc(n * sizeof (StructTest2));
- for (int i = n - 1; i >= 0; i--)
- {
- st2[i].a = (float) rand() / RAND_MAX;
- st2[i].b = (StructTest1*) malloc(sizeof (StructTest1));
- st2[i].b->a = rand() % 42;
- st2[i].b->b = (double) rand() / RAND_MAX;
- stack_push(s, st2 + i);
- }
- for (int i = 0; i < n; i++)
- {
- StructTest2* st2Cell;
- stack_top(s, st2Cell);
- lu_assert_dbl_eq(st2Cell->a, st2[i].a);
- lu_assert_int_eq(st2Cell->b->a, st2[i].b->a);
- lu_assert_dbl_eq(st2Cell->b->b, st2[i].b->b);
- stack_pop(s);
- safe_free(st2Cell->b);
- }
- safe_free(st2);
- stack_destroy(s);
+ Stack* s = stack_new(StructTest1);
+
+ int n = 10;
+ StructTest1* st1 = (StructTest1*) malloc(n * sizeof (StructTest1));
+ for (int i = n - 1; i >= 0; i--)
+ {
+ st1[i].a = rand() % 42;
+ st1[i].b = (double) rand() / RAND_MAX;
+ stack_push(s, *(st1 + i));
+ }
+ for (int i = 0; i < n; i++)
+ {
+ StructTest1 st1Cell;
+ stack_top(s, st1Cell);
+ lu_assert_int_eq(st1Cell.a, st1[i].a);
+ lu_assert_dbl_eq(st1Cell.b, st1[i].b);
+ stack_pop(s);
+ }
+ safe_free(st1);
+ stack_destroy(s);
+
+ s = stack_new(StructTest2*);
+ StructTest2* st2 = (StructTest2*) malloc(n * sizeof (StructTest2));
+ for (int i = n - 1; i >= 0; i--)
+ {
+ st2[i].a = (float) rand() / RAND_MAX;
+ st2[i].b = (StructTest1*) malloc(sizeof (StructTest1));
+ st2[i].b->a = rand() % 42;
+ st2[i].b->b = (double) rand() / RAND_MAX;
+ stack_push(s, st2 + i);
+ }
+ for (int i = 0; i < n; i++)
+ {
+ StructTest2* st2Cell;
+ stack_top(s, st2Cell);
+ lu_assert_dbl_eq(st2Cell->a, st2[i].a);
+ lu_assert_int_eq(st2Cell->b->a, st2[i].b->a);
+ lu_assert_dbl_eq(st2Cell->b->b, st2[i].b->b);
+ stack_pop(s);
+ safe_free(st2Cell->b);
+ }
+ safe_free(st2);
+ stack_destroy(s);
}
void t_stack_copy()
{
- int n = 10;
-
- Stack* s = stack_new(int);
- for (int i = 0; i < n; i++)
- stack_push(s, rand() % 42);
- Stack* sc = stack_copy(s);
-
- lu_assert_int_eq(stack_size(s), stack_size(sc));
- int a, b;
- for (int i = 0; i < n; i++)
- {
- stack_top(s, a);
- stack_top(sc, b);
- lu_assert_int_eq(a, b);
- stack_pop(s);
- stack_pop(sc);
- }
- stack_destroy(s);
- stack_destroy(sc);
+ int n = 10;
+
+ Stack* s = stack_new(int);
+ for (int i = 0; i < n; i++)
+ stack_push(s, rand() % 42);
+ Stack* sc = stack_copy(s);
+
+ lu_assert_int_eq(stack_size(s), stack_size(sc));
+ int a, b;
+ for (int i = 0; i < n; i++)
+ {
+ stack_top(s, a);
+ stack_top(sc, b);
+ lu_assert_int_eq(a, b);
+ stack_pop(s);
+ stack_pop(sc);
+ }
+ stack_destroy(s);
+ stack_destroy(sc);
}
void t_tree_clear()
{
- Tree* t = tree_new(int);
-
- tree_set_root(t, 0);
- tree_add_child(t, t->root, 1);
- tree_add_child(t, t->root, 2);
- tree_add_child(t, t->root, 3);
- tree_add_child(t, t->root->firstChild, 1);
- tree_add_child(t, t->root->firstChild, 2);
- tree_add_child(t, t->root->firstChild->next, 1);
- tree_add_child(t, t->root->firstChild->next, 2);
- tree_add_child(t, t->root->firstChild->next, 3);
- tree_add_child(t, t->root->firstChild->next, 4);
-
- tree_clear(t);
- lu_assert(tree_empty(t));
-
- tree_destroy(t);
+ Tree* t = tree_new(int);
+
+ tree_set_root(t, 0);
+ tree_add_child(t, t->root, 1);
+ tree_add_child(t, t->root, 2);
+ tree_add_child(t, t->root, 3);
+ tree_add_child(t, t->root->firstChild, 1);
+ tree_add_child(t, t->root->firstChild, 2);
+ tree_add_child(t, t->root->firstChild->next, 1);
+ tree_add_child(t, t->root->firstChild->next, 2);
+ tree_add_child(t, t->root->firstChild->next, 3);
+ tree_add_child(t, t->root->firstChild->next, 4);
+
+ tree_clear(t);
+ lu_assert(tree_empty(t));
+
+ tree_destroy(t);
}
void t_tree_size()
{
- Tree* t = tree_new(int);
+ Tree* t = tree_new(int);
- tree_set_root(t, 0);
- tree_add_child(t, t->root, 1);
- tree_add_child(t, t->root, 2);
- tree_add_child(t, t->root, 3);
- lu_assert_int_eq(tree_size(t), 4);
+ tree_set_root(t, 0);
+ tree_add_child(t, t->root, 1);
+ tree_add_child(t, t->root, 2);
+ tree_add_child(t, t->root, 3);
+ lu_assert_int_eq(tree_size(t), 4);
- tree_add_child(t, t->root->firstChild, 1);
- tree_add_child(t, t->root->firstChild, 2);
- lu_assert_int_eq(tree_size(t), 6);
+ tree_add_child(t, t->root->firstChild, 1);
+ tree_add_child(t, t->root->firstChild, 2);
+ lu_assert_int_eq(tree_size(t), 6);
- tree_add_child(t, t->root->firstChild->next, 1);
- tree_add_child(t, t->root->firstChild->next, 2);
- tree_add_child(t, t->root->firstChild->next, 3);
- tree_add_child(t, t->root->firstChild->next, 4);
- lu_assert_int_eq(tree_size(t), 10);
+ tree_add_child(t, t->root->firstChild->next, 1);
+ tree_add_child(t, t->root->firstChild->next, 2);
+ tree_add_child(t, t->root->firstChild->next, 3);
+ tree_add_child(t, t->root->firstChild->next, 4);
+ lu_assert_int_eq(tree_size(t), 10);
- tree_destroy(t);
+ tree_destroy(t);
}
void t_tree_add_remove()
{
- Tree* t = tree_new(int);
-
- tree_set_root(t, 0);
- tree_add_child(t, t->root, 1);
- tree_add_child(t, t->root, 2);
- tree_add_child(t, t->root, 3);
- tree_add_child(t, t->root->firstChild, 1);
- tree_add_child(t, t->root->firstChild, 2);
- tree_add_child(t, t->root->firstChild->next, 1);
- tree_add_child(t, t->root->firstChild->next, 2);
- tree_add_child(t, t->root->firstChild->next, 3);
- tree_add_child(t, t->root->firstChild->next, 4);
- tree_add_child(t, t->root->lastChild, 1);
- tree_add_child(t, t->root->lastChild, 2);
- tree_add_child(t, t->root->lastChild, 3);
- lu_assert_int_eq(tree_size(t), 13);
-
- tree_remove(t, t->root->lastChild);
- lu_assert_int_eq(tree_size(t), 9);
- tree_rm_childs(t, t->root->firstChild);
- lu_assert_int_eq(tree_size(t), 7);
-
- tree_destroy(t);
+ Tree* t = tree_new(int);
+
+ tree_set_root(t, 0);
+ tree_add_child(t, t->root, 1);
+ tree_add_child(t, t->root, 2);
+ tree_add_child(t, t->root, 3);
+ tree_add_child(t, t->root->firstChild, 1);
+ tree_add_child(t, t->root->firstChild, 2);
+ tree_add_child(t, t->root->firstChild->next, 1);
+ tree_add_child(t, t->root->firstChild->next, 2);
+ tree_add_child(t, t->root->firstChild->next, 3);
+ tree_add_child(t, t->root->firstChild->next, 4);
+ tree_add_child(t, t->root->lastChild, 1);
+ tree_add_child(t, t->root->lastChild, 2);
+ tree_add_child(t, t->root->lastChild, 3);
+ lu_assert_int_eq(tree_size(t), 13);
+
+ tree_remove(t, t->root->lastChild);
+ lu_assert_int_eq(tree_size(t), 9);
+ tree_rm_childs(t, t->root->firstChild);
+ lu_assert_int_eq(tree_size(t), 7);
+
+ tree_destroy(t);
}
void t_tree_iterate()
{
- Tree* t = tree_new(int);
-
- tree_set_root(t, 0);
- tree_add_child(t, t->root, 1);
- tree_add_child(t, t->root, 2);
- tree_add_child(t, t->root, 3);
- tree_add_child(t, t->root->firstChild, 4);
- tree_add_child(t, t->root->firstChild, 5);
- tree_add_child(t, t->root->firstChild->next, 6);
- tree_add_child(t, t->root->firstChild->next, 7);
- tree_add_child(t, t->root->firstChild->next, 8);
- tree_add_child(t, t->root->firstChild->next, 9);
-
- TreeIterator* ti = tree_get_iterator(t, IN_BREADTH);
- int a;
- for (int i = 0; i < 10; i++)
- {
- lu_assert(treeI_has_data(ti));
- treeI_get(ti, a);
- lu_assert_int_eq(a, i);
- treeI_move_next(ti);
- }
-
- treeI_destroy(ti);
- tree_destroy(t);
+ Tree* t = tree_new(int);
+
+ tree_set_root(t, 0);
+ tree_add_child(t, t->root, 1);
+ tree_add_child(t, t->root, 2);
+ tree_add_child(t, t->root, 3);
+ tree_add_child(t, t->root->firstChild, 4);
+ tree_add_child(t, t->root->firstChild, 5);
+ tree_add_child(t, t->root->firstChild->next, 6);
+ tree_add_child(t, t->root->firstChild->next, 7);
+ tree_add_child(t, t->root->firstChild->next, 8);
+ tree_add_child(t, t->root->firstChild->next, 9);
+
+ TreeIterator* ti = tree_get_iterator(t, IN_BREADTH);
+ int a;
+ for (int i = 0; i < 10; i++)
+ {
+ lu_assert(treeI_has_data(ti));
+ treeI_get(ti, a);
+ lu_assert_int_eq(a, i);
+ treeI_move_next(ti);
+ }
+
+ treeI_destroy(ti);
+ tree_destroy(t);
}
void t_tree_copy()
{
- Tree* t = tree_new(int);
-
- tree_set_root(t, 0);
- tree_add_child(t, t->root, 1);
- tree_add_child(t, t->root, 2);
- tree_add_child(t, t->root, 3);
- tree_add_child(t, t->root->firstChild, 1);
- tree_add_child(t, t->root->firstChild, 2);
- tree_add_child(t, t->root->firstChild->next, 1);
- tree_add_child(t, t->root->firstChild->next, 2);
- tree_add_child(t, t->root->firstChild->next, 3);
- tree_add_child(t, t->root->firstChild->next, 4);
-
- Tree* tc = tree_copy(t);
- lu_assert_int_eq(t->size, tc->size);
-
- TreeIterator* ti = tree_get_iterator(t, IN_DEPTH);
- TreeIterator* tci = tree_get_iterator(tc, IN_DEPTH);
- int a, b;
- while (treeI_has_data(ti))
- {
- treeI_get(ti, a);
- treeI_get(tci, b);
- lu_assert_int_eq(a, b);
- treeI_move_next(ti);
- treeI_move_next(tci);
- }
- treeI_destroy(ti);
- treeI_destroy(tci);
-
- tree_destroy(t);
- tree_destroy(tc);
+ Tree* t = tree_new(int);
+
+ tree_set_root(t, 0);
+ tree_add_child(t, t->root, 1);
+ tree_add_child(t, t->root, 2);
+ tree_add_child(t, t->root, 3);
+ tree_add_child(t, t->root->firstChild, 1);
+ tree_add_child(t, t->root->firstChild, 2);
+ tree_add_child(t, t->root->firstChild->next, 1);
+ tree_add_child(t, t->root->firstChild->next, 2);
+ tree_add_child(t, t->root->firstChild->next, 3);
+ tree_add_child(t, t->root->firstChild->next, 4);
+
+ Tree* tc = tree_copy(t);
+ lu_assert_int_eq(t->size, tc->size);
+
+ TreeIterator* ti = tree_get_iterator(t, IN_DEPTH);
+ TreeIterator* tci = tree_get_iterator(tc, IN_DEPTH);
+ int a, b;
+ while (treeI_has_data(ti))
+ {
+ treeI_get(ti, a);
+ treeI_get(tci, b);
+ lu_assert_int_eq(a, b);
+ treeI_move_next(ti);
+ treeI_move_next(tci);
+ }
+ treeI_destroy(ti);
+ treeI_destroy(tci);
+
+ tree_destroy(t);
+ tree_destroy(tc);
}
void t_vector_clear()
{
- Vector* v = vector_new(int);
- lu_assert(vector_empty(v));
+ Vector* v = vector_new(int);
+ lu_assert(vector_empty(v));
- vector_push(v, 0);
- vector_push(v, 0);
- vector_push(v, 0);
+ vector_push(v, 0);
+ vector_push(v, 0);
+ vector_push(v, 0);
- vector_destroy(v);
- v = vector_new(int);
+ vector_destroy(v);
+ v = vector_new(int);
- vector_push(v, 0);
- vector_push(v, 0);
- vector_push(v, 0);
+ vector_push(v, 0);
+ vector_push(v, 0);
+ vector_push(v, 0);
- vector_clear(v);
- lu_assert(vector_empty(v));
+ vector_clear(v);
+ lu_assert(vector_empty(v));
- vector_destroy(v);
+ vector_destroy(v);
}
void t_vector_size()
{
- Vector* v = vector_new(int);
- lu_assert(vector_empty(v));
+ Vector* v = vector_new(int);
+ lu_assert(vector_empty(v));
- vector_push(v, 0);
- vector_push(v, 0);
- vector_push(v, 0);
- lu_assert_int_eq(vector_size(v), 3);
+ vector_push(v, 0);
+ vector_push(v, 0);
+ vector_push(v, 0);
+ lu_assert_int_eq(vector_size(v), 3);
- vector_push(v, 0);
- vector_push(v, 0);
- lu_assert_int_eq(vector_size(v), 5);
+ vector_push(v, 0);
+ vector_push(v, 0);
+ lu_assert_int_eq(vector_size(v), 5);
- vector_push(v, 0);
- vector_push(v, 0);
- vector_push(v, 0);
- lu_assert_int_eq(vector_size(v), 8);
+ vector_push(v, 0);
+ vector_push(v, 0);
+ vector_push(v, 0);
+ lu_assert_int_eq(vector_size(v), 8);
- vector_destroy(v);
+ vector_destroy(v);
}
void t_vector_push_pop_basic()
{
- int n = 10;
-
- Vector* v = vector_new(double);
- for (int i = 0; i < n; i++) vector_push(v, (double) i);
- // iterate and check values
- VectorIterator* vi = vector_get_iterator(v);
- double ckValue = 0.0;
- while (vectorI_has_data(vi))
- {
- double d;
- vectorI_get(vi, d);
- lu_assert_dbl_eq(d, ckValue);
- ckValue += 1.0;
- vectorI_move_next(vi);
- }
-
- // same, from end to beginning
- ckValue = n - 1;
- vectorI_reset_end(vi);
- while (vectorI_has_data(vi))
- {
- double d;
- vectorI_get(vi, d);
- lu_assert_dbl_eq(d, ckValue);
- ckValue -= 1.0;
- vectorI_move_prev(vi);
- }
- vector_destroy(v);
- vectorI_destroy(vi);
+ int n = 10;
+
+ Vector* v = vector_new(double);
+ for (int i = 0; i < n; i++) vector_push(v, (double) i);
+ // iterate and check values
+ VectorIterator* vi = vector_get_iterator(v);
+ double ckValue = 0.0;
+ while (vectorI_has_data(vi))
+ {
+ double d;
+ vectorI_get(vi, d);
+ lu_assert_dbl_eq(d, ckValue);
+ ckValue += 1.0;
+ vectorI_move_next(vi);
+ }
+
+ // same, from end to beginning
+ ckValue = n - 1;
+ vectorI_reset_end(vi);
+ while (vectorI_has_data(vi))
+ {
+ double d;
+ vectorI_get(vi, d);
+ lu_assert_dbl_eq(d, ckValue);
+ ckValue -= 1.0;
+ vectorI_move_prev(vi);
+ }
+ vector_destroy(v);
+ vectorI_destroy(vi);
}
void t_vector_push_pop_evolved()
{
- int n = 10;
-
- Vector* v = vector_new(StructTest1);
- StructTest1* st1 = (StructTest1*) malloc(n * sizeof (StructTest1));
- for (int i = 0; i < n; i++)
- {
- st1[i].a = random() % 42;
- st1[i].b = (double) random() / RAND_MAX;
- vector_push(v, *(st1 + i));
- }
- for (int i = 0; i < n; i++)
- {
- //another way to access elements
- StructTest1 st1Cell;
- vector_get(v, i, st1Cell);
- lu_assert_int_eq(st1Cell.a, st1[i].a);
- lu_assert_dbl_eq(st1Cell.b, st1[i].b);
- }
- safe_free(st1);
- vector_destroy(v);
-
- v = vector_new(StructTest2*);
- StructTest2* st2 = (StructTest2*) malloc(n * sizeof (StructTest2));
- for (int i = 0; i < n; i++)
- {
- st2[i].a = (float) random() / RAND_MAX;
- st2[i].b = (StructTest1*) malloc(sizeof (StructTest1));
- st2[i].b->a = random() % 42;
- st2[i].b->b = (double) random() / RAND_MAX;
- vector_push(v, st2 + i);
- }
- for (int i = 0; i < n; i++)
- {
- StructTest2* st2Cell;
- vector_get(v, i, st2Cell);
- lu_assert_dbl_eq(st2Cell->a, st2[i].a);
- lu_assert_int_eq(st2Cell->b->a, st2[i].b->a);
- lu_assert_dbl_eq(st2Cell->b->b, st2[i].b->b);
- safe_free(st2Cell->b);
- }
- safe_free(st2);
- vector_destroy(v);
+ int n = 10;
+
+ Vector* v = vector_new(StructTest1);
+ StructTest1* st1 = (StructTest1*) malloc(n * sizeof (StructTest1));
+ for (int i = 0; i < n; i++)
+ {
+ st1[i].a = random() % 42;
+ st1[i].b = (double) random() / RAND_MAX;
+ vector_push(v, *(st1 + i));
+ }
+ for (int i = 0; i < n; i++)
+ {
+ //another way to access elements
+ StructTest1 st1Cell;
+ vector_get(v, i, st1Cell);
+ lu_assert_int_eq(st1Cell.a, st1[i].a);
+ lu_assert_dbl_eq(st1Cell.b, st1[i].b);
+ }
+ safe_free(st1);
+ vector_destroy(v);
+
+ v = vector_new(StructTest2*);
+ StructTest2* st2 = (StructTest2*) malloc(n * sizeof (StructTest2));
+ for (int i = 0; i < n; i++)
+ {
+ st2[i].a = (float) random() / RAND_MAX;
+ st2[i].b = (StructTest1*) malloc(sizeof (StructTest1));
+ st2[i].b->a = random() % 42;
+ st2[i].b->b = (double) random() / RAND_MAX;
+ vector_push(v, st2 + i);
+ }
+ for (int i = 0; i < n; i++)
+ {
+ StructTest2* st2Cell;
+ vector_get(v, i, st2Cell);
+ lu_assert_dbl_eq(st2Cell->a, st2[i].a);
+ lu_assert_int_eq(st2Cell->b->a, st2[i].b->a);
+ lu_assert_dbl_eq(st2Cell->b->b, st2[i].b->b);
+ safe_free(st2Cell->b);
+ }
+ safe_free(st2);
+ vector_destroy(v);
}
void t_vector_copy()
{
- int n = 10;
-
- Vector* v = vector_new(int);
- for (int i = 0; i < n; i++)
- vector_push(v, random() % 42);
- Vector* vc = vector_copy(v);
-
- lu_assert_int_eq(v->size, vc->size);
- int a, b;
- for (int i = 0; i < n; i++)
- {
- vector_get(v, i, a);
- vector_get(vc, i, b);
- lu_assert_int_eq(a, b);
- }
- vector_destroy(v);
- vector_destroy(vc);
+ int n = 10;
+
+ Vector* v = vector_new(int);
+ for (int i = 0; i < n; i++)
+ vector_push(v, random() % 42);
+ Vector* vc = vector_copy(v);
+
+ lu_assert_int_eq(v->size, vc->size);
+ int a, b;
+ for (int i = 0; i < n; i++)
+ {
+ vector_get(v, i, a);
+ vector_get(vc, i, b);
+ lu_assert_int_eq(a, b);
+ }
+ vector_destroy(v);
+ vector_destroy(vc);
}