* This list uses an obstack and a free-list to efficiently manage its
* elements.
* @author Kimon Hoffmann
- * @date 14.07.2005
+ * @date 14.07.2005
+ * @cvs-id $Id$
* @note Until now the code is entirely untested so it probably contains
* plenty of errors.
*/
* @param list the list for which to allocate the element.
* @return the newly allocated, uninitialized element.
*/
-static PListElement* allocate_element(PList* list) {
- PListElement* newElement;
- if (list->firstFreeElement != NULL) {
- newElement = list->firstFreeElement;
- list->firstFreeElement = newElement->next;
- newElement->next = NULL;
- } else {
+static plist_element_t* allocate_element(plist_t* list) {
+ plist_element_t* newElement;
+
+ if (list->first_free_element != NULL) {
+ newElement = list->first_free_element;
+ list->first_free_element = newElement->next;
+ newElement->next = NULL;
+ }
+ else {
newElement = obstack_alloc(&list->obst, sizeof(*newElement));
}
+
return newElement;
}
-PList* plist_new(void) {
- PList* list = xmalloc(sizeof(*list));
+plist_t* plist_new(void) {
+ plist_t* list = xmalloc(sizeof(*list));
+
obstack_init(&list->obst);
- list->firstElement = NULL;
- list->lastElement = NULL;
- list->firstFreeElement = NULL;
- list->elementCount = 0;
+ list->first_element = NULL;
+ list->last_element = NULL;
+ list->first_free_element = NULL;
+ list->element_count = 0;
+
return list;
}
-void plist_free(PList* list) {
+void plist_free(plist_t* list) {
obstack_free(&list->obst, NULL);
- list->firstElement = NULL;
- list->lastElement = NULL;
- list->firstFreeElement = NULL;
- list->elementCount = 0;
+
+ list->first_element = NULL;
+ list->last_element = NULL;
+ list->first_free_element = NULL;
+ list->element_count = 0;
xfree(list);
}
-void plist_insert_back(PList* list, void* value) {
- if (list->lastElement != NULL) {
- plist_insert_after(list, list->lastElement, value);
- } else {
- PListElement* newElement = allocate_element(list);
- newElement->data = value;
- newElement->prev = NULL;
- newElement->next = NULL;
- list->firstElement = list->lastElement = newElement;
- list->elementCount = 1;
+void plist_insert_back(plist_t* list, void* value) {
+ if (list->last_element != NULL) {
+ plist_insert_after(list, list->last_element, value);
+ }
+ else {
+ plist_element_t* newElement = allocate_element(list);
+
+ newElement->data = value;
+ newElement->prev = NULL;
+ newElement->next = NULL;
+ list->first_element = list->last_element = newElement;
+ list->element_count = 1;
}
}
-void plist_insert_front(PList* list, void* value) {
- if (list->firstElement != NULL) {
- plist_insert_before(list, list->firstElement, value);
- } else {
- PListElement* newElement = allocate_element(list);
- newElement->data = value;
- newElement->prev = NULL;
- newElement->next = NULL;
- list->firstElement = list->lastElement = newElement;
- list->elementCount = 1;
+void plist_insert_front(plist_t* list, void* value) {
+ if (list->first_element != NULL) {
+ plist_insert_before(list, list->first_element, value);
+ }
+ else {
+ plist_element_t* newElement = allocate_element(list);
+
+ newElement->data = value;
+ newElement->prev = NULL;
+ newElement->next = NULL;
+ list->first_element = list->last_element = newElement;
+ list->element_count = 1;
}
}
-void plist_insert_before(PList* list, PListElement* element, void* value) {
- PListElement* prevElement;
- PListElement* newElement = allocate_element(list);
+void plist_insert_before(plist_t* list, plist_element_t* element, void* value) {
+ plist_element_t* prevElement;
+ plist_element_t* newElement = allocate_element(list);
newElement->data = value;
newElement->next = element;
- prevElement = element->prev;
+ prevElement = element->prev;
newElement->prev = prevElement;
+
if (prevElement != NULL) {
prevElement->next = newElement;
- } else {
- list->firstElement = newElement;
}
- element->prev = newElement;
- ++list->elementCount;
+ else {
+ list->first_element = newElement;
+ }
+
+ element->prev = newElement;
+ ++list->element_count;
}
-void plist_insert_after(PList* list, PListElement* element, void* value) {
- PListElement* nextElement;
- PListElement* newElement = allocate_element(list);
+void plist_insert_after(plist_t* list, plist_element_t* element, void* value) {
+ plist_element_t* nextElement;
+ plist_element_t* newElement = allocate_element(list);
newElement->data = value;
newElement->prev = element;
- nextElement = element->next;
+ nextElement = element->next;
newElement->next = nextElement;
+
if (nextElement != NULL) {
nextElement->prev = newElement;
- } else {
- list->lastElement = newElement;
}
+ else {
+ list->last_element = newElement;
+ }
+
element->next = newElement;
- ++list->elementCount;
+ ++list->element_count;
}
-void plist_erase(PList* list, PListElement* element) {
- PListElement* nextElement = element->next;
- PListElement* prevElement = element->prev;
+void plist_erase(plist_t* list, plist_element_t* element) {
+ plist_element_t* nextElement = element->next;
+ plist_element_t* prevElement = element->prev;
+
if (nextElement != NULL) {
nextElement->prev = prevElement;
- } else {
- list->lastElement = prevElement;
}
+ else {
+ list->last_element = prevElement;
+ }
+
if (prevElement != NULL) {
prevElement->next = nextElement;
- } else {
- list->firstElement = nextElement;
}
- --list->elementCount;
+ else {
+ list->first_element = nextElement;
+ }
+
+ --list->element_count;
+
/* Clean the element and prepend it to the free list */
- element->prev = NULL; /* The allocation code expects prev to be NULL */
- element->next = list->firstFreeElement;
- list->firstFreeElement = element;
+ element->prev = NULL; /* The allocation code expects prev to be NULL */
+ element->next = list->first_free_element;
+ list->first_free_element = element;
}
-void plist_clear(PList* list) {
- PListElement* currentElement = list->firstElement;
+void plist_clear(plist_t* list) {
+ plist_element_t* currentElement = list->first_element;
+
while (currentElement != NULL) {
currentElement->prev = NULL;
- currentElement = currentElement->next;
+ currentElement = currentElement->next;
}
- currentElement = list->lastElement;
+
+ currentElement = list->last_element;
+
if (currentElement != NULL) {
- currentElement->next = list->firstFreeElement;
+ currentElement->next = list->first_free_element;
}
- list->firstFreeElement = list->firstElement;
- list->firstElement = list->lastElement = 0;
- list->elementCount = 0;
+
+ list->first_free_element = list->first_element;
+ list->first_element = 0;
+ list->last_element = 0;
+ list->element_count = 0;
}
* This list uses an obstack and a free-list to efficiently manage its
* elements.
* @author Kimon Hoffmann
- * @date 14.07.2005
+ * @date 14.07.2005
+ * @cvs-id $Id$
* @note Until now the code is entirely untested so it probably contains
* plenty of errors.
*/
#include <stddef.h>
#include "obst.h"
-typedef struct PListElement PListElement;
-typedef struct PList PList;
+typedef struct _plist_element plist_element_t;
+typedef struct _plist plist_t;
/**
- * The Plist data type.
+ * The plist data type.
*/
-struct PList {
+struct _plist {
/**
* The obstack used for all allocations.
*/
/**
* First element in the list.
*/
- PListElement* firstElement;
+ plist_element_t *first_element;
/**
* Last element in the list.
*/
- PListElement* lastElement;
+ plist_element_t *last_element;
/**
* Current number of elements in the list.
*/
- int elementCount;
+ int element_count;
/**
* First element in the free list.
* Please note that the free list is a single linked list and all back
* references are invalid.
*/
- PListElement* firstFreeElement;
+ plist_element_t* first_free_element;
};
/**
* An element in the pointer list.
*/
-struct PListElement {
- PListElement* next;
- PListElement* prev;
+struct _plist_element {
+ plist_element_t* next;
+ plist_element_t* prev;
void* data;
};
* Creates a new pointer list and initializes it.
* @return The newly created pointer list.
*/
-PList* plist_new(void);
+plist_t* plist_new(void);
/**
* Frees the passed pointer list.
* After a call to this function all references to the list and any of
* its elements are invalid.
*/
-void plist_free(PList* list);
+void plist_free(plist_t* list);
/**
* Returns the number of elements in a pointer list.
* @return The number of elements in a pointer list.
*/
#define plist_count(list) \
- ((list)->elementCount)
+ ((list)->element_count)
/**
* Inserts an element at the back of a pointer list.
* @param list the pointer list to append the new element to.
* @param value the element value to append.
*/
-void plist_insert_back(PList* list, void* value);
+void plist_insert_back(plist_t* list, void* value);
/**
* Inserts an element at the front of a pointer list.
* @param list the pointer list to prepend the new element to.
* @param value the element value to prepend.
*/
-void plist_insert_front(PList* list, void* value);
+void plist_insert_front(plist_t* list, void* value);
/**
* Inserts an element into a pointer list before the specified element,
* be inserted. This element must be a part of @p list.
* @param value the element value to insert.
*/
-void plist_insert_before(PList* list, PListElement* element, void* value);
+void plist_insert_before(plist_t* list, plist_element_t* element, void* value);
/**
* Inserts an element into a pointer list after the specified element,
* be inserted. This element must be a part of @p list.
* @param value the element value to insert.
*/
-void plist_insert_after(PList* list, PListElement* element, void* value);
+void plist_insert_after(plist_t* list, plist_element_t* element, void* value);
/**
* Erases the specified element from the pointer list.
* @param element the list element to erase. This element must be a part
* of @p list.
*/
-void plist_erase(PList* list, PListElement* element);
+void plist_erase(plist_t* list, plist_element_t* element);
/**
* Erases all elements from the specified pointer list.
* @param list the pointer list that should be cleard.
*/
-void plist_clear(PList* list);
+void plist_clear(plist_t* list);
/**
* Returns the first element of a pointer list.
* @return a pointer to the element or NULL if the list is empty
*/
#define plist_first(list) \
- ((list)->firstElement)
+ ((list)->first_element)
/**
* Returns the last element of a pointer list.
* @return a pointer to the element or NULL if the list is empty
*/
#define plist_last(list) \
- ((list)->lastElement)
+ ((list)->last_element)
/**
* Checks whether a pointer list element has a successor or not.
#define plist_element_get_value(element) \
((element)->data)
+/**
+ * Convenience macro to iterate over a plist.
+ */
+#define foreach_plist(list, el) \
+ for (el = plist_first(list); el; el = plist_element_get_next(el))
+
#endif /*_PLIST_H_*/