Implement HashTable + fix some extra blank spaces, remove Bool type (using bool ...
authorBenjamin Auder <benjamin.auder@somewhere>
Wed, 3 Feb 2021 21:42:55 +0000 (22:42 +0100)
committerBenjamin Auder <benjamin.auder@somewhere>
Wed, 3 Feb 2021 21:42:55 +0000 (22:42 +0100)
32 files changed:
.gitignore
Makefile
src/BufferTop.c
src/BufferTop.h
src/HashTable.c [new file with mode: 0644]
src/HashTable.h [new file with mode: 0644]
src/Heap.c
src/Heap.h
src/List.c
src/List.h
src/PriorityQueue.c
src/PriorityQueue.h
src/Queue.c
src/Queue.h
src/Stack.c
src/Stack.h
src/Tree.c
src/Tree.h
src/Vector.c
src/Vector.h
src/cgds.h [moved from src/cds.h with 82% similarity]
src/safe_alloc.c
src/types.h
test/lut.h
test/main.c
test/t.BufferTop.c
test/t.HashTable.c [new file with mode: 0644]
test/t.Heap.c
test/t.PriorityQueue.c
test/t.Queue.c
test/t.Stack.c
test/t.Vector.c

index b9d261d..941f4fb 100644 (file)
@@ -1,5 +1,6 @@
 *.o
 /src/obj/*.so
 /test/test
+/test/vgcore.*
 /doc/html/
 /doc/latex/
index de9dd81..640ed2e 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -22,9 +22,11 @@ install:
        cp src/obj/$(LIBRARY) $(INSTALL_PREFIX)/lib/
        mkdir -p $(INSTALL_PREFIX)/include/cgds
        cp src/*.h $(INSTALL_PREFIX)/include/cgds/
+       mv $(INSTALL_PREFIX)/include/cgds/cgds.h $(INSTALL_PREFIX)/include/
 
 uninstall:
        rm -f ${INSTALL_PREFIX}/lib/${LIBRARY}
+       rm -f ${INSTALL_PREFIX}/include/cgds.h
        [[ -d ${INSTALL_PREFIX}/include/cgds ]] && rm -rf ${INSTALL_PREFIX}/include/cgds
 
 .PHONY: src test doc clean install uninstall
index db66476..1ead6b8 100644 (file)
@@ -43,7 +43,7 @@ List* buffertop_2list(BufferTop* bufferTop)
        return bufferInList;
 }
 
-Bool buffertop_empty(BufferTop* bufferTop)
+bool buffertop_empty(BufferTop* bufferTop)
 {
        return (heap_size(bufferTop->heap) == 0);
 }
index 1f7d9a9..96af769 100644 (file)
@@ -17,7 +17,7 @@
  */
 typedef struct BufferTop {
        UInt capacity; ///< Buffer capacity (in items count).
-       OrderType bType; ///< Type of buffer: keep max items (MAX_T) or min items (MIN_T).
+       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;
 
@@ -27,7 +27,7 @@ typedef struct BufferTop {
 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 items (bType==MAX_T) or min items (bType==MIN_T).
+       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.
 );
 
@@ -35,16 +35,17 @@ BufferTop* _buffertop_new(
  * @brief Return an allocated and initialized buffer.
  * @param type Type of a buffer item (int, char*, ...).
  * @param capacity Maximum number of elements that the buffer can contain.
- * @param bType type of buffer top: max items (bType==MAX_T) or min items (bType==MIN_T).
+ * @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)
 
 /**
- * @brief Copy constructor (works well if items do not have allocated sub-pointers).
+ * @brief Copy constructor (shallow copy, ok for basic types).
  */
 BufferTop* buffertop_copy(
        BufferTop* bufferTop ///< "this" pointer.
@@ -60,7 +61,7 @@ List* buffertop_2list(
 /**
  * @brief Check if the buffer is empty.
  */
-Bool buffertop_empty(
+bool buffertop_empty(
        BufferTop* bufferTop ///< "this" pointer.
 );
 
@@ -85,7 +86,7 @@ void _buffertop_tryadd(
  * @param bufferTop "this" pointer.
  * @param item Item of type as defined in the constructor.
  * @param value Value associated with the item.
- * 
+ *
  * Usage: void buffertop_tryadd(BufferTop* bufferTop, void item, Real value)
  */
 #define buffertop_tryadd(bufferTop, item, value) \
@@ -105,7 +106,7 @@ ItemValue* buffertop_first_raw(
  * @brief Set item_ to the top ("worst among best") item inside current buffer.
  * @param bufferTop "this" pointer.
  * @param item_ Variable to be assigned.
- * 
+ *
  * Usage: void buffertop_first(BufferTop* bufferTop, void item)
  */
 #define buffertop_first(bufferTop, item_) \
diff --git a/src/HashTable.c b/src/HashTable.c
new file mode 100644 (file)
index 0000000..7bd310c
--- /dev/null
@@ -0,0 +1,163 @@
+/**
+ * @file HashTable.c
+ */
+
+#include "cgds/HashTable.h"
+
+void _hashtable_init(HashTable* hashTable, size_t dataSize, size_t hashSize)
+{
+       hashTable->hashSize = hashSize;
+  hashTable->dataSize = dataSize;
+       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_copy(HashTable* hashTable)
+{
+       HashTable* hashTableCopy =
+    _hashtable_new(hashTable->dataSize, hashTable->hashSize);
+       hashTableCopy->size = hashTable->size;
+  for (UInt i = 0; i < hashTable->hashSize; i++)
+       {
+    HashCell *cell = hashTable->head[i],
+             *cellCopy = hashTableCopy->head[i],
+             *prev = NULL;
+    while (cell != NULL)
+    {
+      // cellCopy == NULL (from empty list)
+      cellCopy = (HashCell*) safe_malloc(sizeof(HashCell*));
+                 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);
+      if (prev == NULL) hashTableCopy->head[i] = cellCopy;
+      else prev->next = cellCopy;
+      prev = cellCopy;
+      cell = cell->next;
+    }
+    if (cellCopy != NULL) cellCopy->next = NULL;
+       }
+       return hashTableCopy;
+}
+
+bool hashtable_empty(HashTable* hashTable)
+{
+       return (hashTable->size == 0);
+}
+
+UInt hashtable_size(HashTable* hashTable)
+{
+       return hashTable->size;
+}
+
+// Function (string) key --> (integer) hash [internal usage]
+UInt _compute_hash(char* key, size_t hashSize)
+{
+  UInt res = 0;
+  for (unsigned char* s = key; *s != '\0'; s++)
+    // NOTE: '31' from here https://stackoverflow.com/a/4384446
+    res += *s + 31 * res;
+  return res % hashSize;
+}
+
+void* _hashtable_get(HashTable* hashTable, char* key)
+{
+  UInt hashIdx = _compute_hash(key, hashTable->hashSize);
+  HashCell* cell = hashTable->head[hashIdx];
+  while (cell != NULL)
+  {
+    if (strcmp(cell->key, key) == 0) return cell->data;
+    cell = cell->next;
+  }
+  return NULL;
+}
+
+void _hashtable_set(HashTable* hashTable, char* key, void* data)
+{
+  UInt hashIdx = _compute_hash(key, hashTable->hashSize);
+  HashCell
+    *cell = hashTable->head[hashIdx],
+    *prev = NULL;
+  while (cell != NULL)
+  {
+    if (strcmp(cell->key, key) == 0)
+    {
+      // Modify:
+      memcpy(cell->data, data, hashTable->dataSize);
+      return;
+    }
+    prev = cell;
+    cell = cell->next;
+  }
+  // New element: insert after prev (which may be NULL)
+  HashCell* newCell = (HashCell*) safe_malloc(sizeof(HashCell));
+  newCell->key = (char*) safe_malloc(strlen(key) + 1);
+  strcpy(newCell->key, key);
+  newCell->data = safe_malloc(hashTable->dataSize);
+  memcpy(newCell->data, data, hashTable->dataSize);
+  newCell->next = NULL;
+  if (prev == NULL)
+    hashTable->head[hashIdx] = newCell;
+  else
+    prev->next = newCell;
+  hashTable->size++;
+}
+
+void hashtable_delete(HashTable* hashTable, char* key)
+{
+  UInt hashIdx = _compute_hash(key, hashTable->hashSize);
+  HashCell
+    *cell = hashTable->head[hashIdx],
+    *prev = NULL;
+  while (cell != NULL)
+  {
+    if (strcmp(cell->key, key) == 0)
+    {
+      if (prev == NULL)
+        hashTable->head[hashIdx] = cell->next;
+      else
+        prev->next = cell->next;
+      safe_free(cell->key);
+      safe_free(cell->data);
+      safe_free(cell);
+      hashTable->size--;
+      break;
+    }
+    prev = cell;
+    cell = cell->next;
+  }
+}
+
+void hashtable_clear(HashTable* hashTable)
+{
+       for (UInt i = 0; i < hashTable->hashSize; i++)
+  {
+    HashCell* cell = hashTable->head[i];
+    while (cell != NULL)
+    {
+      HashCell* next = cell->next;
+      safe_free(cell->key);
+      safe_free(cell->data);
+      safe_free(cell);
+      cell = next;
+    }
+    hashTable->head[i] = NULL;
+  }
+       hashTable->size = 0;
+}
+
+void hashtable_destroy(HashTable* hashTable)
+{
+       hashtable_clear(hashTable);
+       safe_free(hashTable->head);
+  safe_free(hashTable);
+}
diff --git a/src/HashTable.h b/src/HashTable.h
new file mode 100644 (file)
index 0000000..7014de3
--- /dev/null
@@ -0,0 +1,147 @@
+/**
+ * @file HashTable.h
+ */
+
+#ifndef CGDS_HASH_TABLE_H
+#define CGDS_HASH_TABLE_H
+
+#include <stdlib.h>
+#include <string.h>
+#include "cgds/safe_alloc.h"
+#include "cgds/types.h"
+#include "cgds/Vector.h"
+
+/**
+ * @brief Cell of a dictionary.
+ */
+typedef struct HashCell {
+       char* key; ///< Key (as a string).
+  void* data; ///< Generic data contained in this cell.
+       struct HashCell* next; ///< Pointer to next cell in the list.
+} HashCell;
+
+/**
+ * @brief Generic dictionary string --> any data.
+ */
+typedef struct HashTable {
+  UInt size; ///< Count elements in the dictionary.
+       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.
+} HashTable;
+
+/**
+ * @brief Initialize an empty dictionary.
+ */
+void _hashtable_init(
+       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 hashSize ///< (Maximum) Number of stored hash keys.
+);
+
+/**
+ * @brief Return an allocated and initialized vector.
+ * @param type Type of a vector element (int, char*, ...).
+ *
+ * Usage: HashTable* hashtable_new(<Type> type, UInt hash_size)
+ */
+#define hashtable_new(type, hsize) \
+       _hashtable_new(sizeof(type), hsize)
+
+/**
+ * @brief Copy constructor (shallow copy, ok for basic types).
+ */
+HashTable* hashtable_copy(
+       HashTable* hashTable ///< "this" pointer.
+);
+
+/**
+ * @brief Check if the dictionary is empty.
+ */
+bool hashtable_empty(
+       HashTable* hastTable ///< "this" pointer.
+);
+
+/**
+ * @brief Return current size.
+ */
+UInt hashtable_size(
+       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.
+);
+
+/**
+ * @brief Lookup element of given key.
+ * @param hashTable "this" pointer.
+ * @param key Key of the element to retrieve..
+ * @param data 'out' variable to contain the result.
+ *
+ * Usage: void hashtable_get(HashTable* hashTable, char* key, void data)
+ */
+#define hashtable_get(hashTable, key, data) \
+{ \
+       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.
+);
+
+/**
+ * @brief Add the entry (key, value) to dictionary.
+ * @param hashTable "this" pointer.
+ * @param key Key of the element to add or modify.
+ * @param data New data at given key.
+ *
+ * Usage: void hashtable_set(HashTable* hashTable, char* key, void data)
+ */
+#define hashtable_set(hashTable, key, data) \
+{ \
+       typeof((data)) tmp = data; \
+       _hashtable_set(hashTable, key, &tmp); \
+}
+
+/**
+ * @brief Remove the given key (+ associated value).
+ */
+void hashtable_delete(
+       HashTable* hashTable, ///< "this" pointer.
+  char* key ///< Key of the element to delete.
+);
+
+/**
+ * @brief Clear the entire dictionary.
+ */
+void hashtable_clear(
+       HashTable* hashTable ///< "this" pointer.
+);
+
+/**
+ * @brief Destroy the dictionary: clear it, and free hashes array.
+ */
+void hashtable_destroy(
+       HashTable* hashTable ///< "this" pointer.
+);
+
+#endif
index 659e539..fd41a09 100644 (file)
@@ -19,23 +19,28 @@ Heap* _heap_new(size_t dataSize, OrderType hType, UInt arity)
 Heap* heap_copy(Heap* heap)
 {
        Heap* heapCopy = _heap_new(heap->dataSize, heap->hType, heap->arity);
-       // HACK: vector_copy is not enough, since we also have to allocate ItemValue(->item)
+       // 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 = (void**)safe_malloc(heap->array->capacity*sizeof(void*));
+       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), 
+                       .item=safe_malloc(heap->dataSize),
                        .value=((ItemValue*)(heap->array->datas[i]))->value};
-               memcpy(itemValueCopy.item, ((ItemValue*)(heap->array->datas[i]))->item, heap->dataSize);
+               memcpy(
+      itemValueCopy.item,
+      ((ItemValue*)(heap->array->datas[i]))->item,
+      heap->dataSize);
                memcpy(heapCopy->array->datas[i], &itemValueCopy, sizeof(ItemValue));
        }
        return heapCopy;
 }
 
-Bool heap_empty(Heap* heap)
+bool heap_empty(Heap* heap)
 {
        return vector_empty(heap->array);
 }
@@ -45,22 +50,22 @@ UInt heap_size(Heap* heap)
        return vector_size(heap->array);
 }
 
-// NOTE: [perf] in two following methods, full heap[k] exchanges are not needed;
-// we keep track of the moving element without assigning it at every step,
-// thus saving array accesses and affectations + 'aux' temp. memory.
+// NOTE: [perf] in two following methods, full heap[k] exchanges are
+// not needed; we keep track of the moving element without assigning it at
+// every step, thus saving array accesses and affectations + 'aux' tmp memory.
 // --> this is not the most natural way of writing these functions.
 
 void _heap_bubble_up(Heap* heap, UInt startIndex)
 {
        UInt currentIndex = startIndex;
        ItemValue* startItemValue = heap->array->datas[startIndex];
-       while (C_TRUE)
+       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 || 
+               if (currentIndex == 0 ||
                        (heap->hType == MIN_T && startItemValue->value >= nextValue) ||
                        (heap->hType == MAX_T && startItemValue->value <= nextValue))
                {
@@ -78,7 +83,7 @@ void _heap_bubble_down(Heap* heap, UInt startIndex)
 {
        UInt currentIndex = startIndex;
        ItemValue* startItemValue = heap->array->datas[startIndex];
-       while (C_TRUE)
+       while (true)
        {
                if (currentIndex * heap->arity >= heap->array->size)
                {
@@ -121,7 +126,8 @@ void _heap_bubble_down(Heap* heap, UInt startIndex)
 
 void _heap_insert(Heap* heap, void* item, Real value)
 {
-       ItemValue itemValue = (ItemValue){.item=safe_malloc(heap->dataSize), .value=value};
+       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);
@@ -136,7 +142,7 @@ void _heap_modify(Heap* heap, UInt index, Real newValue)
        {
                _heap_bubble_down(heap, index);
        }
-       else 
+       else
                _heap_bubble_up(heap, index);
 }
 
@@ -147,7 +153,7 @@ void _heap_remove(Heap* heap, UInt 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) 
+       if (heap->array->size > 0)
                _heap_bubble_down(heap, index);
 }
 
index 895eb32..c17cb73 100644 (file)
@@ -36,14 +36,14 @@ Heap* _heap_new(
  * @param type Type of a buffer item (int, char*, ...).
  * @param hType Type of heap: max first (MAX_T) or min first (MIN_T).
  * @param 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)
 
 /**
- * @brief Copy constructor (works well if items do not have allocated sub-pointers).
+ * @brief Copy constructor (shallow copy, ok for basic types).
  */
 Heap* heap_copy(
        Heap* heap ///< "this" pointer.
@@ -52,7 +52,7 @@ Heap* heap_copy(
 /**
  * @brief Check if the heap is empty.
  */
-Bool heap_empty(
+bool heap_empty(
        Heap* heap ///< "this" pointer.
 );
 
@@ -64,7 +64,8 @@ UInt heap_size(
 );
 
 /**
- * @brief "Bubble up" an item-value inserted somewhere in the tree in O(log(n)) operations.
+ * @brief "Bubble up" an item-value inserted somewhere in the tree
+ * in O(log(n)) operations.
  */
 void _heap_bubble_up(
        Heap* heap, ///< "this" pointer.
@@ -72,7 +73,8 @@ void _heap_bubble_up(
 );
 
 /**
- * @brief "Bubble down" an item-value inserted somewhere in the tree in O(log(n)) operations.
+ * @brief "Bubble down" an item-value inserted somewhere in the tree
+ * in O(log(n)) operations.
  */
 void _heap_bubble_down(
        Heap* heap, ///< "this" pointer.
@@ -93,7 +95,7 @@ void _heap_insert(
  * @param heap "this" pointer.
  * @param item Item of type as defined in the constructor.
  * @param value Value associated with the item.
- * 
+ *
  * Usage: void heap_insert(Heap* heap, void item, Real value)
  */
 #define heap_insert(heap, item, value) \
@@ -117,7 +119,7 @@ void _heap_modify(
  * @param item_ Item to modify.
  * @param 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.
  */
@@ -146,7 +148,7 @@ void _heap_remove(
  * @param heap "this" pointer.
  * @param item_ 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.
  */
@@ -173,7 +175,7 @@ ItemValue* heap_top_raw(
  * @brief Return what is at the beginning of the heap.
  * @param heap "this" pointer.
  * @param item_ Item to be assigned.
- * 
+ *
  * Usage: void heap_top(Heap* heap, void item_)
  */
 #define heap_top(heap, item_) \
index d34fc92..0d4c113 100644 (file)
@@ -35,7 +35,7 @@ List* list_copy(List* list)
        return listCopy;
 }
 
-Bool list_empty(List* list)
+bool list_empty(List* list)
 {
        return (list->size == 0);
 }
@@ -115,13 +115,13 @@ void _list_insert_back(List* list, void* data)
 
 void list_remove(List* list, ListCell* listCell)
 {
-       if (listCell->prev != NULL) 
+       if (listCell->prev != NULL)
                listCell->prev->next = listCell->next;
-       else 
+       else
                list->head = listCell->next;
-       if (listCell->next != NULL) 
+       if (listCell->next != NULL)
                listCell->next->prev = listCell->prev;
-       else 
+       else
                list->tail = listCell->prev;
        safe_free(listCell->data);
        safe_free(listCell);
@@ -180,7 +180,7 @@ void listI_reset_tail(ListIterator* listI)
        listI->current = listI->list->tail;
 }
 
-Bool listI_has_data(ListIterator* listI)
+bool listI_has_data(ListIterator* listI)
 {
        return (listI->current != NULL);
 }
index 3e1c4ad..0a36ea0 100644 (file)
@@ -28,7 +28,7 @@ typedef struct ListCell {
  */
 typedef struct List {
        UInt size; ///< Count elements in the list.
-       size_t dataSize; ///< Size of a list cell elements in bytes.
+       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;
@@ -52,14 +52,14 @@ List* _list_new(
 /**
  * @brief Return an allocated and initialized list.
  * @param type Type of a list element (int, char*, ...).
- * 
+ *
  * Usage: List* list_new(<Type> type)
  */
 #define list_new(type) \
        _list_new(sizeof(type))
 
 /**
- * @brief Copy constructor (works well if items do not have allocated sub-pointers).
+ * @brief Copy constructor (shallow copy, ok for basic types).
  */
 List* list_copy(
        List* list ///< "this" pointer.
@@ -68,7 +68,7 @@ List* list_copy(
 /**
  * @brief Check if the list is empty.
  */
-Bool list_empty(
+bool list_empty(
        List* list ///< "this" pointer.
 );
 
@@ -90,7 +90,7 @@ void* _list_get(
  * @brief Get data at the given list cell argument.
  * @param listCell Pointer to a cell inside "this" list.
  * @param data Data to be assigned.
- * 
+ *
  * Usage: void list_get(ListCell* listCell, void data)
  */
 #define list_get(listCell, data) \
@@ -113,7 +113,7 @@ void _list_set(
  * @param list "this" pointer.
  * @param listCell Pointer to a cell inside "this" list.
  * @param data Data to be set.
- * 
+ *
  * Usage: void list_set(List* list, ListCell* listCell, void data);
  */
 #define list_set(list, listCell, data) \
@@ -144,7 +144,7 @@ void _list_insert_before(
  * @param list "this" pointer.
  * @param listCell Pointer to a cell inside "this" list.
  * @param data Data to be inserted.
- * 
+ *
  * Usage: void list_insert_before(List* list, ListCell* listCell, void data)
  */
 #define list_insert_before(list, listCell, data) \
@@ -167,7 +167,7 @@ void _list_insert_after(
  * @param list "this" pointer.
  * @param listCell Pointer to a cell inside "this" list.
  * @param data Data to be inserted.
- * 
+ *
  * Usage: void list_insert_after(List* list, ListCell* listCell, void data)
  */
 #define list_insert_after(list, listCell, data) \
@@ -188,7 +188,7 @@ void _list_insert_front(
  * @brief Add data at the beginning of the list.
  * @param list "this" pointer.
  * @param data Data to be inserted.
- * 
+ *
  * Usage: void list_insert_front(List* list, void data)
  */
 #define list_insert_front(list, data) \
@@ -209,7 +209,7 @@ void _list_insert_back(
  * @brief Add data at the end of the list.
  * @param list "this" pointer.
  * @param data Data to be inserted.
- * 
+ *
  * Usage: void list_insert_back(List* list, void data)
  */
 #define list_insert_back(list, data) \
@@ -218,7 +218,7 @@ void _list_insert_back(
        _list_insert_back(list, &tmp); \
 }
 
-/** 
+/**
  * @brief Remove data at position given by 'listCell'.
  */
 void list_remove(
@@ -290,7 +290,7 @@ void listI_reset_tail(
 /**
  * @brief Tell if there is some data at the current index.
  */
-Bool listI_has_data(
+bool listI_has_data(
        ListIterator* listI ///< "this" pointer.
 );
 
@@ -298,7 +298,7 @@ Bool listI_has_data(
  * @brief Return data contained in the current list cell.
  * @param listI "this" pointer.
  * @param data Data to be assigned.
- * 
+ *
  * Usage: void listI_get(ListIterator* listI, void data)
  */
 #define listI_get(listI, data) \
@@ -308,8 +308,8 @@ Bool listI_has_data(
  * @brief Set data at the current iterator position.
  * @param listI "this" pointer
  * @param data Data to assign.
- * 
- * Usage: void listI_set(ListIterator* listI, void data); 
+ *
+ * Usage: void listI_set(ListIterator* listI, void data);
  */
 #define listI_set(listI, data) \
        list_set(listI->list, listI->current, data)
@@ -318,7 +318,7 @@ Bool listI_has_data(
  * @brief Add data before current list cell.
  * @param listI "this" pointer
  * @param data Data to be inserted.
- * 
+ *
  * Usage: void listI_insert_before(ListIteratorI* listI, void data)
  */
 #define listI_insert_before(listI, data) \
@@ -328,7 +328,7 @@ Bool listI_has_data(
  * @brief Add data after current list cell.
  * @param listI "this" pointer
  * @param data Data to be inserted.
- * 
+ *
  * Usage: void listI_insert_after(ListIteratorI* listI, void data)
  */
 #define listI_insert_after(listI, data) \
index 5606db3..f0b71e4 100644 (file)
@@ -4,11 +4,13 @@
 
 #include "cgds/PriorityQueue.h"
 
-// NOTE: no _init() method here, since PriorityQueue has no specific initialization
+// NOTE: no _init() method here,
+// since PriorityQueue has no specific initialization
 
 PriorityQueue* _priorityqueue_new(size_t dataSize, OrderType pType, UInt arity)
 {
-       PriorityQueue* priorityQueue = (PriorityQueue*) safe_malloc(sizeof (PriorityQueue));
+       PriorityQueue* priorityQueue =
+    (PriorityQueue*) safe_malloc(sizeof (PriorityQueue));
        Heap* heap = _heap_new(dataSize, pType, arity);
        priorityQueue->heap = heap;
        return priorityQueue;
@@ -24,7 +26,7 @@ PriorityQueue* priorityqueue_copy(PriorityQueue* priorityQueue)
        return priorityQueueCopy;
 }
 
-Bool priorityqueue_empty(PriorityQueue* priorityQueue)
+bool priorityqueue_empty(PriorityQueue* priorityQueue)
 {
        return heap_empty(priorityQueue->heap);
 }
index a543dd8..59fe511 100644 (file)
@@ -23,23 +23,24 @@ typedef struct PriorityQueue {
  */
 PriorityQueue* _priorityqueue_new(
        size_t dataSize, ///< Size in bytes of a priority queue element.
-       OrderType pType, ///< Type of priority queue: max first (hType==MAX_T) or min first (hType==MIN_T).
+       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.
 );
 
 /**
  * @brief Return an allocated and initialized Queue.
  * @param type Type of a priority queue item (int, char*, ...).
- * @param pType type of priority queue: max first (hType==MAX_T) or min first (hType==MIN_T).
+ * @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)
 
 /**
- * @brief Copy constructor (works well if items do not have allocated sub-pointers).
+ * @brief Copy constructor (shallow copy, ok for basic types).
  */
 PriorityQueue* priorityqueue_copy(
        PriorityQueue* priorityQueue ///< "this" pointer.
@@ -48,7 +49,7 @@ PriorityQueue* priorityqueue_copy(
 /**
  * @brief Check if the priority queue is empty.
  */
-Bool priorityqueue_empty(
+bool priorityqueue_empty(
        PriorityQueue* priorityQueue ///< "this" pointer.
 );
 
@@ -64,8 +65,9 @@ UInt priorityqueue_size(
  * @param 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)
@@ -76,8 +78,9 @@ UInt priorityqueue_size(
  * @param item Item to be modified.
  * @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)
@@ -87,7 +90,7 @@ UInt priorityqueue_size(
  * @param priorityQueue "this" pointer.
  * @param item Item to be removed.
  * @note If several similar items are present, only the first is deleted.
- * 
+ *
  * Usage: void priorityqueue_remove(PriorityQueue* priorityQueue, void item)
  */
 #define priorityqueue_remove(priorityQueue, item) \
@@ -95,7 +98,7 @@ UInt priorityqueue_size(
 
 /**
  * @brief Return what is at the beginning of the queue.
- * @return An ItemValue* 'iv' with iv->item is the data, and iv->value its priority.
+ * @return An ItemValue* 'iv' with iv->item = data, and iv->value its priority.
  */
 ItemValue* priorityqueue_peek_raw(
        PriorityQueue* priorityQueue ///< "this" pointer.
@@ -105,7 +108,7 @@ ItemValue* priorityqueue_peek_raw(
  * @brief Peek the item at the beginning of the queue.
  * @param priorityQueue "this" pointer.
  * @param item Item to be assigned.
- * 
+ *
  * Usage: void priorityqueue_peek(PriorityQueue* priorityQueue, void item)
  */
 #define priorityqueue_peek(priorityQueue, item) \
@@ -118,7 +121,7 @@ void priorityqueue_pop(
        PriorityQueue* priorityQueue ///< "this" pointer.
 );
 
-/** 
+/**
  * @brief Clear the entire queue.
  */
 void priorityqueue_clear(
index 3e61381..0303505 100644 (file)
@@ -27,7 +27,7 @@ Queue* queue_copy(Queue* queue)
        return queueCopy;
 }
 
-Bool queue_empty(Queue* queue)
+bool queue_empty(Queue* queue)
 {
        return list_empty(queue->list);
 }
index 0cd9766..9aae379 100644 (file)
@@ -30,24 +30,24 @@ void _queue_init(
        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.
 );
 
-/** 
+/**
  * @brief Return an allocated and initialized queue.
  * @param type Type of a queue element (int, char*, ...).
- * 
+ *
  * Usage: Queue* queue_new(<Type> type)
  */
 #define queue_new(type) \
        _queue_new(sizeof(type))
 
 /**
- * @brief Copy constructor (works well if items do not have allocated sub-pointers).
+ * @brief Copy constructor (shallow copy, ok for basic types).
  */
 Queue* queue_copy(
        Queue* queue ///< "this" pointer.
@@ -56,7 +56,7 @@ Queue* queue_copy(
 /**
  * @brief Check if the queue is empty.
  */
-Bool queue_empty(
+bool queue_empty(
        Queue* queue ///< "this" pointer.
 );
 
@@ -79,7 +79,7 @@ void _queue_push(
  * @brief Add something at the end of the queue.
  * @param queue "this" pointer
  * @param data Data to be pushed.
- * 
+ *
  * Usage: void queue_push(Queue* queue, void data)
  */
 #define queue_push(queue, data) \
@@ -99,7 +99,7 @@ void* _queue_peek(
  * @brief Return what is at the beginning of the queue.
  * @param queue "this" pointer.
  * @param data Data to be assigned.
- * 
+ *
  * Usage: void queue_peek(Queue* queue, void data)
  */
 #define queue_peek(queue, data) \
index 8aa7800..92457c0 100644 (file)
@@ -27,7 +27,7 @@ Stack* stack_copy(Stack* stack)
        return stackCopy;
 }
 
-Bool stack_empty(Stack* stack)
+bool stack_empty(Stack* stack)
 {
        return vector_empty(stack->array);
 }
index c314c28..24ad176 100644 (file)
@@ -27,24 +27,24 @@ void _stack_init(
        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.
 );
 
-/** 
+/**
  * @brief Return an allocated and initialized stack.
  * @param type Type of a stack element (int, char*, ...).
- * 
+ *
  * Usage: Stack* stack_new(<Type> type)
  */
 #define stack_new(type) \
        _stack_new(sizeof(type))
 
 /**
- * @brief Copy constructor (works well if items do not have allocated sub-pointers).
+ * @brief Copy constructor (shallow copy, ok for basic types).
  */
 Stack* stack_copy(
        Stack* stack ///< "this" pointer.
@@ -53,7 +53,7 @@ Stack* stack_copy(
 /**
  * @brief Check if the stack is empty.
  */
-Bool stack_empty(
+bool stack_empty(
        Stack* stack ///< "this" pointer.
 );
 
@@ -76,7 +76,7 @@ void _stack_push(
  * @brief Add something on top of the stack.
  * @param stack "this" pointer.
  * @param data Data to be added.
- * 
+ *
  * Usage: void stack_push(Stack* stack, void data)
  */
 #define stack_push(stack, data) \
@@ -96,7 +96,7 @@ void* _stack_top(
  * @brief Return what is on top of the stack.
  * @param stack "this" pointer.
  * @param data Data to be assigned.
- * 
+ *
  * Usage: void stack_top(Stack* stack, void data)
  */
 #define stack_top(stack, data) \
index fe21a6b..1ee3b51 100644 (file)
@@ -25,7 +25,7 @@ Tree* _tree_new(size_t dataSize)
 Tree* tree_copy(Tree* tree)
 {
        Tree* treeCopy = _tree_new(tree->dataSize);
-       if (tree->root == NULL) 
+       if (tree->root == NULL)
                return treeCopy;
        _tree_set_root(treeCopy, tree->root->data);
 
@@ -88,7 +88,7 @@ Tree* tree_copy(Tree* tree)
        return treeCopy;
 }
 
-Bool tree_empty(Tree* tree)
+bool tree_empty(Tree* tree)
 {
        return (tree->root == NULL);
 }
@@ -100,14 +100,14 @@ UInt tree_size(Tree* tree)
 
 UInt _tree_height_rekursiv(TreeNode* treeNode)
 {
-       if (tree_is_leaf(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) 
+               if (heightChild > maxHeightChild)
                        maxHeightChild = heightChild;
                child = child->next;
        }
@@ -116,12 +116,12 @@ UInt _tree_height_rekursiv(TreeNode* treeNode)
 
 UInt tree_height(Tree* tree)
 {
-       if (tree_empty(tree)) 
+       if (tree_empty(tree))
                return 0;
        return _tree_height_rekursiv(tree->root);
 }
 
-Bool tree_is_leaf(TreeNode* treeNode)
+bool tree_is_leaf(TreeNode* treeNode)
 {
        return (treeNode->firstChild == NULL);
 }
@@ -155,11 +155,11 @@ void _tree_add_child(Tree* tree, TreeNode* treeNode, void* data)
        newChildNode->data = safe_malloc(tree->dataSize);
        memcpy(newChildNode->data, data, tree->dataSize);
        newChildNode->next = NULL;
-       if (treeNode->lastChild != NULL) 
+       if (treeNode->lastChild != NULL)
                treeNode->lastChild->next = newChildNode;
        newChildNode->prev = treeNode->lastChild;
        treeNode->lastChild = newChildNode;
-       if (treeNode->firstChild == NULL) 
+       if (treeNode->firstChild == NULL)
                treeNode->firstChild = newChildNode;
        newChildNode->parent = treeNode;
        newChildNode->firstChild = NULL;
@@ -173,7 +173,7 @@ void _tree_add_sibling(Tree* tree, TreeNode* treeNode, void* data)
        newSiblingNode->data = safe_malloc(tree->dataSize);
        memcpy(newSiblingNode->data, data, tree->dataSize);
        newSiblingNode->next = treeNode->next;
-       if (treeNode->next != NULL) 
+       if (treeNode->next != NULL)
                treeNode->next->prev = newSiblingNode;
        newSiblingNode->prev = treeNode;
        treeNode->next = newSiblingNode;
@@ -201,14 +201,14 @@ void tree_remove(Tree* tree, TreeNode* treeNode)
 {
        if (treeNode->parent != NULL)
        {
-               if (treeNode->prev == NULL) 
+               if (treeNode->prev == NULL)
                        treeNode->parent->firstChild = treeNode->next;
-               if (treeNode->next == NULL) 
+               if (treeNode->next == NULL)
                        treeNode->parent->lastChild = treeNode->prev;
        }
-       if (treeNode->next != NULL) 
+       if (treeNode->next != NULL)
                treeNode->next->prev = treeNode->prev;
-       if (treeNode->prev != NULL) 
+       if (treeNode->prev != NULL)
                treeNode->prev->next = treeNode->next;
        _tree_remove_rekursiv(tree, treeNode);
 }
@@ -228,14 +228,14 @@ void tree_rm_childs(Tree* tree, TreeNode* treeNode)
 
 void tree_clear(Tree* tree)
 {
-       if (tree->root != NULL) 
+       if (tree->root != NULL)
                _tree_remove_rekursiv(tree, tree->root);
        _tree_init(tree, tree->dataSize);
 }
 
 void tree_destroy(Tree* tree)
 {
-       if (tree->root != NULL) 
+       if (tree->root != NULL)
                tree_clear(tree);
        safe_free(tree);
 }
@@ -258,7 +258,7 @@ void treeI_reset(TreeIterator* treeI)
        treeI->current = treeI->tree->root;
 }
 
-Bool treeI_has_data(TreeIterator* treeI)
+bool treeI_has_data(TreeIterator* treeI)
 {
        return (treeI->current != NULL);
 }
index 3fa66fc..617ea15 100644 (file)
@@ -53,14 +53,14 @@ Tree* _tree_new(
 /**
  * @brief Return an allocated and initialized tree.
  * @param type Type at a tree node (int, char*, ...).
- * 
+ *
  * Usage: Tree* tree_new(<Type> type)
  */
 #define tree_new(type) \
        _tree_new(sizeof(type))
 
 /**
- * @brief Copy constructor (works well if items do not have allocated sub-pointers).
+ * @brief Copy constructor (shallow copy, ok for basic types).
  */
 Tree* tree_copy(
        Tree* tree ///< "this" pointer.
@@ -69,7 +69,7 @@ Tree* tree_copy(
 /**
  * @brief Check if the tree is empty.
  */
-Bool tree_empty(
+bool tree_empty(
        Tree* tree ///< "this" pointer.
 );
 
@@ -97,7 +97,7 @@ UInt tree_height(
 /**
  * @brief Check if a sub-tree is a leaf (without children).
  */
-Bool tree_is_leaf(
+bool tree_is_leaf(
        TreeNode* treeNode ///< Pointer to a node in the "this" tree.
 );
 
@@ -113,7 +113,7 @@ void _tree_set_root(
  * @brief Initialize tree root when the tree is empty.
  * @param tree "this" pointer.
  * @param data Data to be assigned.
- * 
+ *
  * Usage: void tree_set_root(Tree* tree, void data)
  */
 #define tree_set_root(tree, data) \
@@ -133,7 +133,7 @@ void* _tree_get(
  * @brief Retrieve data contained in a given tree node.
  * @param treeNode Pointer to a node in the "this" tree.
  * @param data Data to be assigned.
- * 
+ *
  * Usage: void tree_get(TreeNode* treeNode, void data)
  */
 #define tree_get(treeNode, data) \
@@ -156,7 +156,7 @@ void _tree_set(
  * @param tree "this" pointer.
  * @param treeNode Pointer to a node in the "this" tree.
  * @param data Data to be assigned.
- * 
+ *
  * Usage: void tree_set(Tree* tree, TreeNode* treeNode, void data)
  */
 #define tree_set(tree, treeNode, data) \
@@ -179,7 +179,7 @@ void _tree_add_child(
  * @param tree "this" pointer.
  * @param treeNode Pointer to a node in the "this" tree.
  * @param data Data to be added.
- * 
+ *
  * Usage: void tree_add_child(Tree* tree, TreeNode* treeNode, void data)
  */
 #define tree_add_child(tree,treeNode,data) \
@@ -202,7 +202,7 @@ void _tree_add_sibling(
  * @param tree "this" pointer.
  * @param treeNode Pointer to a node in the "this" tree.
  * @param data Data to be added.
- * 
+ *
  * Usage: void tree_add_sibling(Tree* tree, TreeNode* treeNode, void data)
  */
 #define tree_add_sibling(tree, treeNode, data) \
@@ -288,7 +288,7 @@ void treeI_reset(
 /**
  * @brief Tell if there is some data at the current index.
  */
-Bool treeI_has_data(
+bool treeI_has_data(
        TreeIterator* treeI ///< "this" pointer.
 );
 
@@ -303,7 +303,7 @@ TreeNode* treeI_get_raw(
  * @brief Get data at current tree node.
  * @param treeI "this" pointer.
  * @param data Data to be assigned.
- * 
+ *
  * Usage: void treeI_get(TreeIterator* treeI, void data)
  */
 #define treeI_get(treeI, data) \
@@ -313,7 +313,7 @@ TreeNode* treeI_get_raw(
  * @brief Set (alter) data at current tree node.
  * @param treeI "this" pointer.
  * @param data Data to be assigned.
- * 
+ *
  * Usage: void treeI_set(TreeIterator* treeI, void data)
  */
 #define treeI_set(treeI, data) \
index 2d00985..042e75c 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * @file Vector.cpp
+ * @file Vector.c
  */
 
 #include "cgds/Vector.h"
@@ -37,7 +37,7 @@ Vector* vector_copy(Vector* vector)
        return vectorCopy;
 }
 
-Bool vector_empty(Vector* vector)
+bool vector_empty(Vector* vector)
 {
        return (vector->size == 0);
 }
@@ -112,7 +112,8 @@ void vector_destroy(Vector* vector)
 
 VectorIterator* vector_get_iterator(Vector* vector)
 {
-       VectorIterator* vectorI = (VectorIterator*) safe_malloc(sizeof (VectorIterator));
+       VectorIterator* vectorI =
+    (VectorIterator*) safe_malloc(sizeof (VectorIterator));
        vectorI->vector = vector;
        vectorI_reset_begin(vectorI);
        return vectorI;
@@ -128,7 +129,7 @@ void vectorI_reset_end(VectorIterator* vectorI)
        vectorI->current = vectorI->vector->datas + vectorI->vector->size - 1;
 }
 
-Bool vectorI_has_data(VectorIterator* vectorI)
+bool vectorI_has_data(VectorIterator* vectorI)
 {
        return (vectorI->current >= vectorI->vector->datas &&
                vectorI->current < vectorI->vector->datas + vectorI->vector->size);
index d3fe04c..f6060f8 100644 (file)
@@ -42,14 +42,14 @@ Vector* _vector_new(
 /**
  * @brief Return an allocated and initialized vector.
  * @param type Type of a vector element (int, char*, ...).
- * 
+ *
  * Usage: Vector* vector_new(<Type> type)
  */
 #define vector_new(type) \
        _vector_new(sizeof(type))
 
 /**
- * @brief Copy constructor (works well if items do not have allocated sub-pointers).
+ * @brief Copy constructor (shallow copy, ok for basic types).
  */
 Vector* vector_copy(
        Vector* vector ///< "this" pointer.
@@ -58,7 +58,7 @@ Vector* vector_copy(
 /**
  * @brief Check if the vector is empty.
  */
-Bool vector_empty(
+bool vector_empty(
        Vector* vector ///< "this" pointer.
 );
 
@@ -89,7 +89,7 @@ void _vector_push(
  * @brief Add data at the end.
  * @param vector "this" pointer.
  * @param data Data to be added.
- * 
+ *
  * Usage: void vector_push(Vector* vector, void data)
  */
 #define vector_push(vector, data) \
@@ -118,7 +118,7 @@ void* _vector_get(
  * @param vector "this" pointer.
  * @param index Index of the element to retrieve.
  * @param data 'out' variable to contain the result.
- * 
+ *
  * Usage: void vector_get(Vector* vector, size_t index, void data)
  */
 #define vector_get(vector, index, data) \
@@ -141,7 +141,7 @@ void _vector_set(
  * @param vector "this" pointer.
  * @param index Index of the element to be modified.
  * @param data New data at given index.
- * 
+ *
  * Usage: void vector_set(Vector* vector, size_t index, void data)
  */
 #define vector_set(vector, index, data) \
@@ -200,7 +200,7 @@ void vectorI_reset_end(
 /**
  * @brief Tell if there is some data at the current index.
  */
-Bool vectorI_has_data(
+bool vectorI_has_data(
        VectorIterator* vectorI ///< "this" pointer.
 );
 
@@ -215,7 +215,7 @@ void* _vectorI_get(
  * @brief Get data contained at the current index.
  * @param vectorI "this" pointer.
  * @param data 'out' variable to contain the result.
- * 
+ *
  * Usage: void vectorI_get(VectorIterator* vectorI, void data);
  */
 #define vectorI_get(vectorI, data) \
@@ -236,7 +236,7 @@ void _vectorI_set(
  * @brief Set the element at current index.
  * @param vectorI "this" pointer.
  * @param data Data to be assigned.
- * 
+ *
  * Usage: void vectorI_set(VectorIterator* vectorI, void data)
  */
 #define vectorI_set(vectorI, data) \
similarity index 82%
rename from src/cds.h
rename to src/cgds.h
index 89e6e79..6533a7e 100644 (file)
--- a/src/cds.h
@@ -1,7 +1,9 @@
 #ifndef LIBCGDS_H
 #define LIBCGDS_H
 
+// To include everything:
 #include <cgds/BufferTop.h>
+#include <cgds/HashTable.h>
 #include <cgds/Heap.h>
 #include <cgds/List.h>
 #include <cgds/PriorityQueue.h>
index 9d1de7e..dcb8c33 100644 (file)
@@ -39,6 +39,6 @@ void* safe_realloc(void* ptr, size_t size)
 
 void safe_free(void* ptr)
 {
-       if (ptr != NULL) 
+       if (ptr != NULL)
                free(ptr);
 }
index 99b6d2c..f202b26 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <stdlib.h>
 #include <stdint.h>
+#include <stdbool.h>
 
 /**
  * @brief Signed integer type.
@@ -24,14 +25,6 @@ typedef uint64_t UInt;
  */
 typedef double Real;
 
-/**
- * @brief Boolean type (prefixed with C_ to avoid some conflicts).
- */
-typedef enum {
-       C_FALSE = 0, ///< False is mapped to 0
-       C_TRUE = 1 ///< True is mapped to 1
-} Bool;
-
 /**
  * @brief Enumeration for the type of buffer or heap.
  */
index 821feb3..e41e9c9 100644 (file)
 #define _lu_assert_int(X, OP, Y) do { \
        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); \
+       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_eq(X, Y) _lu_assert_int(X, ==, Y) 
-#define lu_assert_int_ne(X, Y) _lu_assert_int(X, !=, Y) 
+#define lu_assert_int_eq(X, Y) _lu_assert_int(X, ==, Y)
+#define lu_assert_int_ne(X, Y) _lu_assert_int(X, !=, Y)
 #define lu_assert_int_lt(X, Y) _lu_assert_int(X, <, Y)
 #define lu_assert_int_le(X, Y) _lu_assert_int(X, <=, Y)
 #define lu_assert_int_gt(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, "Assertion '"#X#OP#Y"' failed: "#X"==%g, "#Y"==%g", _lu_x, _lu_y); \
+       lu_assert_msg(_lu_x OP _lu_y, \
+                "Assertion '"#X#OP#Y"' failed: "#X"==%g, "#Y"==%g", \
+                _lu_x, _lu_y); \
 } while (0)
-#define lu_assert_dbl_eq(X, Y) _lu_assert_dbl(X, ==, Y) 
-#define lu_assert_dbl_ne(X, Y) _lu_assert_dbl(X, !=, Y) 
+#define lu_assert_dbl_eq(X, Y) _lu_assert_dbl(X, ==, Y)
+#define lu_assert_dbl_ne(X, Y) _lu_assert_dbl(X, !=, Y)
 #define lu_assert_dbl_lt(X, Y) _lu_assert_dbl(X, <, Y)
 #define lu_assert_dbl_le(X, Y) _lu_assert_dbl(X, <=, Y)
 #define lu_assert_dbl_gt(X, Y) _lu_assert_dbl(X, >, Y)
index 3c2cf04..c5683f8 100644 (file)
@@ -2,20 +2,6 @@
 
 int main(int argc, char** argv)
 {
-       //file ./t.Stack.c :
-       t_stack_clear();
-       t_stack_size();
-       t_stack_push_pop_basic();
-       t_stack_push_pop_evolved();
-       t_stack_copy();
-
-       //file ./t.List.c :
-       t_list_clear();
-       t_list_size();
-       t_list_push_pop_basic();
-       t_list_push_pop_evolved();
-       t_list_copy();
-
        //file ./t.Tree.c :
        t_tree_clear();
        t_tree_size();
@@ -23,19 +9,12 @@ int main(int argc, char** argv)
        t_tree_iterate();
        t_tree_copy();
 
-       //file ./t.Vector.c :
-       t_vector_clear();
-       t_vector_size();
-       t_vector_push_pop_basic();
-       t_vector_push_pop_evolved();
-       t_vector_copy();
-
-       //file ./t.Queue.c :
-       t_queue_clear();
-       t_queue_size();
-       t_queue_push_pop_basic();
-       t_queue_push_pop_evolved();
-       t_queue_copy();
+       //file ./t.PriorityQueue.c :
+       t_priorityqueue_clear();
+       t_priorityqueue_size();
+       t_priorityqueue_push_pop_basic();
+       t_priorityqueue_push_pop_evolved();
+       t_priorityqueue_copy();
 
        //file ./t.Heap.c :
        t_heap_clear();
@@ -44,6 +23,13 @@ int main(int argc, char** argv)
        t_heap_push_pop_evolved();
        t_heap_copy();
 
+       //file ./t.List.c :
+       t_list_clear();
+       t_list_size();
+       t_list_push_pop_basic();
+       t_list_push_pop_evolved();
+       t_list_copy();
+
        //file ./t.BufferTop.c :
        t_buffertop_clear();
        t_buffertop_size();
@@ -51,12 +37,33 @@ int main(int argc, char** argv)
        t_buffertop_push_pop_evolved();
        t_buffertop_copy();
 
-       //file ./t.PriorityQueue.c :
-       t_priorityqueue_clear();
-       t_priorityqueue_size();
-       t_priorityqueue_push_pop_basic();
-       t_priorityqueue_push_pop_evolved();
-       t_priorityqueue_copy();
+       //file ./t.HashTable.c :
+       //t_hashtable_clear();
+       //t_hashtable_size();
+       t_hashtable_set_remove_basic();
+       //t_hashtable_getnull_modify();
+       //t_hashtable_copy();
+
+       //file ./t.Stack.c :
+       t_stack_clear();
+       t_stack_size();
+       t_stack_push_pop_basic();
+       t_stack_push_pop_evolved();
+       t_stack_copy();
+
+       //file ./t.Queue.c :
+       t_queue_clear();
+       t_queue_size();
+       t_queue_push_pop_basic();
+       t_queue_push_pop_evolved();
+       t_queue_copy();
+
+       //file ./t.Vector.c :
+       t_vector_clear();
+       t_vector_size();
+       t_vector_push_pop_basic();
+       t_vector_push_pop_evolved();
+       t_vector_copy();
 
        return 0;
 }
index 42b31c9..53899c4 100644 (file)
@@ -7,7 +7,7 @@ void t_buffertop_clear()
 {
        BufferTop* bt = buffertop_new(int, 10, MIN_T, 2);
 
-       // NOTE: items with same values are supported; 
+       // 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);
diff --git a/test/t.HashTable.c b/test/t.HashTable.c
new file mode 100644 (file)
index 0000000..5c23cb7
--- /dev/null
@@ -0,0 +1,159 @@
+#include <stdlib.h>
+#include "cgds/HashTable.h"
+#include "helpers.h"
+#include "lut.h"
+
+void t_hashtable_clear()
+{
+  HashTable* h = hashtable_new(int, 16);
+  lu_assert(hashtable_empty(h));
+
+  hashtable_set(h, "key1", 0);
+  hashtable_set(h, "key2", 1);
+  hashtable_set(h, "key3", 2);
+
+  hashtable_destroy(h);
+  h = hashtable_new(int, 8);
+
+  hashtable_set(h, "key1", 1);
+  hashtable_set(h, "key2", 2);
+  hashtable_set(h, "key3", 3);
+
+  hashtable_clear(h);
+  lu_assert(hashtable_empty(h));
+
+  hashtable_destroy(h);
+}
+
+void t_hashtable_size()
+{
+  HashTable* h = hashtable_new(int, 16);
+  lu_assert(hashtable_empty(h));
+
+  hashtable_set(h, "key1", 0);
+  hashtable_set(h, "key2", 1);
+  hashtable_set(h, "key3", 2);
+  lu_assert_int_eq(hashtable_size(h), 3);
+
+  hashtable_set(h, "key4", 3);
+  hashtable_set(h, "key5", 4);
+  lu_assert_int_eq(hashtable_size(h), 5);
+
+  hashtable_set(h, "key6", 5);
+  hashtable_set(h, "key7", 6);
+  hashtable_set(h, "key8", 7);
+  lu_assert_int_eq(hashtable_size(h), 8);
+
+  hashtable_destroy(h);
+}
+
+void t_hashtable_set_remove_basic()
+{
+  int n = 10;
+
+  HashTable* h = hashtable_new(double, 4);
+  char key[] = "key_";
+  for (int i = 0; i < n; i++)
+  {
+    key[3] = (char)(48 + i);
+    hashtable_set(h, key, (double)i);
+  }
+  lu_assert_int_eq(hashtable_size(h), n);
+
+  // Check values
+  double ckValue = 0.0;
+  for (int i = 0; i < n; i++)
+  {
+    double d;
+    key[3] = (char)(48 + i);
+    hashtable_get(h, key, d);
+    lu_assert_dbl_eq(d, ckValue);
+    ckValue += 1.0;
+  }
+
+  //Remove keys / values
+  for (int i = 0; i < n; i++)
+  {
+    double d;
+    key[3] = (char)(48 + i);
+    hashtable_delete(h, key);
+  }
+  lu_assert_int_eq(hashtable_size(h), 0);
+
+  hashtable_destroy(h);
+}
+
+void t_hashtable_getnull_modify()
+{
+  int n = 10;
+
+  HashTable* h = hashtable_new(StructTest1, 4);
+  StructTest1* st1 = (StructTest1*) malloc(n * sizeof (StructTest1));
+  char* key = "key_";
+  for (int i = 0; i < n; i++)
+  {
+    key[3] = (char)(48 + i);
+    st1[i].a = random() % 42;
+    st1[i].b = (double) random() / RAND_MAX;
+    hashtable_set(h, key, *(st1 + i));
+  }
+  for (int i = 0; i < n; i++)
+  {
+    //another way to access elements
+    key[3] = (char)(48 + i);
+    StructTest1 st1Cell;
+    hashtable_get(h, key, st1Cell);
+    lu_assert_int_eq(st1Cell.a, st1[i].a);
+    lu_assert_dbl_eq(st1Cell.b, st1[i].b);
+  }
+
+  // Get null:
+  StructTest1* stmp;
+  hashtable_get(h, "key12", stmp);
+  lu_assert(stmp == NULL);
+  hashtable_get(h, "key32", stmp);
+  lu_assert(stmp == NULL);
+  // Modify:
+  StructTest1* stMod;
+  stMod->a = -17;
+  stMod->b = 3.0;
+  hashtable_set(h, "key1", stMod);
+  hashtable_get(h, "key1", stmp);
+  lu_assert_int_eq(stmp->a, stMod->a);
+  lu_assert_dbl_eq(stmp->b, stMod->b);
+  stMod->a = -7;
+  stMod->b = 3.5;
+  hashtable_set(h, "key5", stMod);
+  hashtable_get(h, "key5", stmp);
+  lu_assert_int_eq(stmp->a, stMod->a);
+  lu_assert_dbl_eq(stmp->b, stMod->b);
+
+  safe_free(st1);
+  hashtable_destroy(h);
+}
+
+void t_hashtable_copy()
+{
+  int n = 10;
+
+  HashTable* h = hashtable_new(int, 8);
+  char* key = "key_";
+  for (int i = 0; i < n; i++)
+  {
+    key[3] = (char)(48 + i);
+    hashtable_set(h, key, random() % 42);
+  }
+  HashTable* hc = hashtable_copy(h);
+
+  lu_assert_int_eq(h->size, hc->size);
+  int a, b;
+  for (int i = 0; i < n; i++)
+  {
+    key[3] = (char)(48 + i);
+    hashtable_get(h, key, a);
+    hashtable_get(hc, key, b);
+    lu_assert_int_eq(a, b);
+  }
+  hashtable_destroy(h);
+  hashtable_destroy(hc);
+}
index b01f835..733f104 100644 (file)
@@ -7,7 +7,7 @@ void t_heap_clear()
 {
        Heap* h = heap_new(int, MIN_T, 2);
 
-       // NOTE: items with same priorities are supported; 
+       // 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);
index e5c3bae..8cabc1e 100644 (file)
@@ -7,7 +7,7 @@ void t_priorityqueue_clear()
 {
        PriorityQueue* pq = priorityqueue_new(int, MIN_T, 2);
 
-       // NOTE: items with same priorities are supported; 
+       // 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);
index a393da2..9dd1986 100644 (file)
@@ -43,7 +43,7 @@ void t_queue_push_pop_basic()
        int n = 10;
 
        Queue* q = queue_new(double);
-       for (int i = 0; i < n; i++) 
+       for (int i = 0; i < n; i++)
                queue_push(q, (double) i);
        // iterate and check values
        double ckValue = 0.0;
index ba53e9f..3cbaef6 100644 (file)
@@ -44,7 +44,7 @@ void t_stack_push_pop_basic()
        int n = 10;
 
        Stack* s = stack_new(double);
-       for (int i = 0; i < n; i++) 
+       for (int i = 0; i < n; i++)
                stack_push(s, (double) i);
        // iterate and check values
        double ckValue = n - 1;
index 6cae626..7fde1e9 100644 (file)
@@ -88,8 +88,8 @@ void t_vector_push_pop_evolved()
        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;
+               st1[i].a = random() % 42;
+               st1[i].b = (double) random() / RAND_MAX;
                vector_push(v, *(st1 + i));
        }
        for (int i = 0; i < n; i++)
@@ -107,10 +107,10 @@ void t_vector_push_pop_evolved()
        StructTest2* st2 = (StructTest2*) malloc(n * sizeof (StructTest2));
        for (int i = 0; i < n; i++)
        {
-               st2[i].a = (float) rand() / RAND_MAX;
+               st2[i].a = (float) random() / RAND_MAX;
                st2[i].b = (StructTest1*) malloc(sizeof (StructTest1));
-               st2[i].b->a = rand() % 42;
-               st2[i].b->b = (double) rand() / RAND_MAX;
+               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++)
@@ -132,7 +132,7 @@ void t_vector_copy()
 
        Vector* v = vector_new(int);
        for (int i = 0; i < n; i++)
-               vector_push(v, rand() % 42);
+               vector_push(v, random() % 42);
        Vector* vc = vector_copy(v);
 
        lu_assert_int_eq(v->size, vc->size);