diff --git a/code/game/g_active.c b/code/game/g_active.c index 957d73f..ad62534 100644 --- a/code/game/g_active.c +++ b/code/game/g_active.c @@ -510,13 +510,13 @@ static char *TimedMessage( void ){ } if(iterTimedMessages == NULL) { - iterTimedMessages = list_iterator(level.timedMessages, LIST_FRONT); + iterTimedMessages = level.timedMessages->iterator(level.timedMessages, LIST_FRONT); if(iterTimedMessages == NULL) { // something went wrong return "^1RPG-X ERROR: No messages to display"; } } - c = list_cycl_next(iterTimedMessages); + c = level.timedMessages->cycl_next(iterTimedMessages); message = c->data; return message; diff --git a/code/game/g_cmds.c b/code/game/g_cmds.c index b37cd58..f8e578d 100644 --- a/code/game/g_cmds.c +++ b/code/game/g_cmds.c @@ -6338,8 +6338,8 @@ static void Cmd_getEntByTarget_f(gentity_t *ent) { list_init(&entities, free); G_GetEntityByTarget(arg, &entities); - iter = list_iterator(&entities, LIST_FRONT); - for(c = list_next(iter); c != NULL; c = list_next(iter)) { + iter = entities.iterator(&entities, LIST_FRONT); + for(c = entities.next(iter); c != NULL; c = entities.next(iter)) { t = c->data; if(t == NULL) { @@ -6353,7 +6353,7 @@ static void Cmd_getEntByTarget_f(gentity_t *ent) { G_PrintfClient(ent, "ENT %i: %s\n\"", t->s.number, t->classname); } destroy_iterator(iter); - list_clear(&entities); + entities.clear(&entities); } /* @@ -7379,12 +7379,12 @@ static void Cmd_findEntitiesInRadius(gentity_t *ent) { list_init(&entities, free); list_init(&ignore, free); - list_append_ptr(&ignore, ent, LT_DATA); + ignore.append_ptr(&ignore, ent, LT_DATA); G_RadiusList(ent->r.currentOrigin, radius, &ignore, takeDamage, &entities); - list_clear(&ignore); + ignore.clear(&ignore); - iter = list_iterator(&entities, LIST_FRONT); - for(c = list_next(iter); c != NULL; c = list_next(iter)) { + iter = entities.iterator(&entities, LIST_FRONT); + for(c = entities.next(iter); c != NULL; c = entities.next(iter)) { t = c->data; if(t == NULL) { @@ -7400,7 +7400,7 @@ static void Cmd_findEntitiesInRadius(gentity_t *ent) { } } destroy_iterator(iter); - list_clear(&entities); + entities.clear(&entities); } // CCAM @@ -7444,19 +7444,20 @@ void addShaderToList(list_p list, char *shader) { return; } - i = list_iterator(list, LIST_FRONT); + i = list->iterator(list, LIST_FRONT); if(i == NULL) { return; } - for(c = list_next(i)->data; c != NULL; c = list_next(i)->data) { + for(c = list->next(i); c != NULL; c = list->next(i)) { t = c->data; if(!strcmp(shader, t)) { return; } } + destroy_iterator(i); - list_append(list, s, LT_STRING, strlen(s)+1); + list->append(list, s, LT_STRING, strlen(s)+1); } extern target_alert_Shaders_s alertShaders; @@ -7513,14 +7514,14 @@ void Cmd_GeneratePrecacheFile(gentity_t *ent) { } } - iter = list_iterator(shaders, LIST_FRONT); + iter = shaders->iterator(shaders, LIST_FRONT); if(iter == NULL) { trap_FS_FCloseFile(f); destroy_list(shaders); return; } - for(c = list_next(iter)->data; c != NULL; c = list_next(iter)->data) { + for(c = shaders->next(iter); c != NULL; c = shaders->next(iter)) { s = c->data; G_Printf("\t%s\n", s); if(first) { @@ -7535,6 +7536,7 @@ void Cmd_GeneratePrecacheFile(gentity_t *ent) { } } trap_FS_Write("\n\"END\"", 6, f); + destroy_iterator(iter); G_Printf("Done.\n"); diff --git a/code/game/g_main.c b/code/game/g_main.c index 5f76e41..5d1de29 100644 --- a/code/game/g_main.c +++ b/code/game/g_main.c @@ -960,7 +960,7 @@ static void G_LoadTimedMessages(void) { continue; } - list_append(level.timedMessages, token, LT_STRING, strlen(token)+1); + level.timedMessages->append(level.timedMessages, token, LT_STRING, strlen(token)+1); } else { if(token[0] == '}') { break; diff --git a/code/game/g_turrets.c b/code/game/g_turrets.c index 034c693..48c3e21 100644 --- a/code/game/g_turrets.c +++ b/code/game/g_turrets.c @@ -557,15 +557,15 @@ void turret_base_think (gentity_t *self) list_init(&ignore, free); if(lastEnemy && lastEnemy->lastEnemy) { - list_append_ptr(&ignore, lastEnemy->lastEnemy, LT_DATA); + ignore.append_ptr(&ignore, lastEnemy->lastEnemy, LT_DATA); G_RadiusList( self->r.currentOrigin, self->random, &ignore, qtrue, &entity_list ); } else { G_RadiusList( self->r.currentOrigin, self->random, NULL, qtrue, &entity_list ); } - list_clear(&ignore); + ignore.clear(&ignore); - iter = list_iterator(&entity_list, LIST_FRONT); - for(c = list_next(iter); c != NULL; c = list_next(iter)) { + iter = entity_list.iterator(&entity_list, LIST_FRONT); + for(c = entity_list.next(iter); c != NULL; c = entity_list.next(iter)) { target = c->data; if(target == NULL) { @@ -616,7 +616,7 @@ void turret_base_think (gentity_t *self) } } destroy_iterator(iter); - list_clear(&entity_list); + entity_list.clear(&entity_list); } if ( self->enemy ) diff --git a/code/game/g_utils.c b/code/game/g_utils.c index 11f9d65..8d04a78 100644 --- a/code/game/g_utils.c +++ b/code/game/g_utils.c @@ -821,8 +821,8 @@ int G_RadiusList ( vec3_t origin, float radius, list_p ignore, qboolean takeDama } if(ignore != NULL) { - iter = list_iterator(ignore, LIST_FRONT); - for(c = list_next(iter); c != NULL; c = list_next(iter)) { + iter = ignore->iterator(ignore, LIST_FRONT); + for(c = ignore->next(iter); c != NULL; c = ignore->next(iter)) { t = c->data; if(t == NULL) { @@ -863,7 +863,7 @@ int G_RadiusList ( vec3_t origin, float radius, list_p ignore, qboolean takeDama } /* ok, we are within the radius, add us to the incoming list */ - list_append_ptr(ent_list, ent, LT_DATA); + ent_list->append_ptr(ent_list, ent, LT_DATA); } /* we are done, return how many we found */ return ent_list->length; @@ -914,8 +914,8 @@ int G_RadiusListOfTypes(list_p classnames, vec3_t origin, float radius, list_p i } if(ignore != NULL) { - iter = list_iterator(ignore, LIST_FRONT); - for(c = list_next(iter); c != NULL; c = list_next(iter)) { + iter = ignore->iterator(ignore, LIST_FRONT); + for(c = ignore->next(iter); c != NULL; c = ignore->next(iter)) { t = c->data; if(t == NULL) { @@ -934,8 +934,8 @@ int G_RadiusListOfTypes(list_p classnames, vec3_t origin, float radius, list_p i continue; } - iter = list_iterator(classnames, LIST_FRONT); - for(c = list_next(iter); c != NULL; c = list_next(iter)) { + iter = classnames->iterator(classnames, LIST_FRONT); + for(c = classnames->next(iter); c != NULL; c = classnames->next(iter)) { if(!strcmp(ent->classname, (char*)c->data)) { valid = qtrue; break; @@ -969,7 +969,7 @@ int G_RadiusListOfTypes(list_p classnames, vec3_t origin, float radius, list_p i } /* ok, we are within the radius, add us to the incoming list */ - list_append_ptr(ent_list, ent, LT_DATA); + ent_list->append_ptr(ent_list, ent, LT_DATA); valid = qfalse; } @@ -1007,8 +1007,8 @@ gentity_t *G_GetNearestEnt(char *classname, vec3_t origin, float radius, list_p list_init(&entList, free); G_RadiusList(origin, radius, ignore, takeDamage, &entList); - iter = list_iterator(&entList, LIST_FRONT); - for(c = list_next(iter); c != NULL; c = list_next(iter)) { + iter = entList.iterator(&entList, LIST_FRONT); + for(c = entList.next(iter); c != NULL; c = entList.next(iter)) { t = c->data; if(t == NULL) { @@ -1039,7 +1039,7 @@ gentity_t *G_GetNearestEnt(char *classname, vec3_t origin, float radius, list_p } } destroy_iterator(iter); - list_clear(&entList); + entList.clear(&entList); return nearest; } @@ -1072,8 +1072,8 @@ gentity_t *G_GetNearestPlayer(vec3_t origin, float radius, list_p ignore ) { list_init(&entList, free); G_RadiusList(origin, radius, ignore, qtrue, &entList); - iter = list_iterator(&entList, LIST_FRONT); - for(c = list_next(iter); c != NULL; c = list_next(iter)) { + iter = entList.iterator(&entList, LIST_FRONT); + for(c = entList.next(iter); c != NULL; c = entList.next(iter)) { t = c->data; if(t == NULL) { @@ -1092,7 +1092,7 @@ gentity_t *G_GetNearestPlayer(vec3_t origin, float radius, list_p ignore ) { } } destroy_iterator(iter); - list_clear(&entList); + entList.clear(&entList); return nearest; } @@ -1109,7 +1109,7 @@ int G_GetEntityByTargetname(const char *targetname, list_p entities) { if(!&g_entities[i]) continue; t = &g_entities[i]; if(t->targetname && !Q_strncmp(t->targetname, targetname, strlen(targetname))) { - list_append_ptr(entities, t, LT_DATA); + entities->append_ptr(entities, t, LT_DATA); } } @@ -1128,7 +1128,7 @@ int G_GetEntityByTarget(const char *target, list_p entities) { if(!&g_entities[i]) continue; t = &g_entities[i]; if(t->target && !Q_strncmp(t->target, target, strlen(target))) { - list_append_ptr(entities, t, LT_DATA); + entities->append_ptr(entities, t, LT_DATA); } } @@ -1147,7 +1147,7 @@ int G_GetEntityByBmodel(char *bmodel, list_p entities) { if(!&g_entities[i]) continue; t = &g_entities[i]; if(t->model && !Q_strncmp(t->model, bmodel, strlen(bmodel))) { - list_append_ptr(entities, t, LT_DATA); + entities->append_ptr(entities, t, LT_DATA); } } diff --git a/code/game/g_weapon.c b/code/game/g_weapon.c index 6b09c08..b47c5dc 100644 --- a/code/game/g_weapon.c +++ b/code/game/g_weapon.c @@ -116,18 +116,18 @@ static void WP_FireHyperspanner(gentity_t *ent, qboolean alt_fire) { /* prepare lists */ list_init(&classnames, free); list_init(&validEnts, free); - list_append(&classnames, "func_breakable", LT_STRING, strlen("func_breakable")+1); - list_append(&classnames, "misc_model_breakable", LT_STRING, strlen("misc_model_breakable")+1); + classnames.append(&classnames, "func_breakable", LT_STRING, strlen("func_breakable")+1); + classnames.append(&classnames, "misc_model_breakable", LT_STRING, strlen("misc_model_breakable")+1); /* find all vlaid entities in range */ count = G_RadiusListOfTypes(&classnames, ent->r.currentOrigin, 512, NULL, &validEnts); - list_clear(&classnames); + classnames.clear(&classnames); //G_Printf("Found %d possible candidates\n", count); if(count) { trace_t tr; - iter = list_iterator(&validEnts, LIST_FRONT); - for(cont = list_next(iter); cont != NULL; cont = list_next(iter)) { + iter = validEnts.iterator(&validEnts, LIST_FRONT); + for(cont = validEnts.next(iter); cont != NULL; cont = validEnts.next(iter)) { e = cont->data; // TODO: fix problems with small distance @@ -161,7 +161,7 @@ static void WP_FireHyperspanner(gentity_t *ent, qboolean alt_fire) { } if(nearest == NULL || nearest->inuse == qfalse) { - list_clear(&validEnts); + validEnts.clear(&validEnts); return; } @@ -179,7 +179,7 @@ static void WP_FireHyperspanner(gentity_t *ent, qboolean alt_fire) { G_Repair(ent, nearest, HYPERSPANNER_RATE * modifier); } - list_clear(&validEnts); + validEnts.clear(&validEnts); } /* diff --git a/code/game/list.c b/code/game/list.c index 77dfffc..472cd88 100644 --- a/code/game/list.c +++ b/code/game/list.c @@ -22,22 +22,17 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "list.h" #include -list_p create_list() { - list_p list = (list_p)malloc(sizeof(struct list)); - - if(list == NULL) { - return NULL; - } - - list->length = 0; - list->first = NULL; - list->last = NULL; - list->destructor = free; - - return list; -} - -list_iter_p list_iterator(list_p list, char init) { +/** + * Create a list_iter object for the linked_list list. The flag init can be + * either LIST_FRONT or LIST_BACK and indicates whether to start the iterator from the first + * or last item in the list + * + * \param list pointer to a list + * \param init indicator where to start from + * \return A new list iterator. + * + */ +static list_iter_p list_iterator(list_p list, char init) { list_iter_p iter = (list_iter_p)malloc(sizeof(struct list_iter)); if(iter == NULL) { @@ -58,7 +53,20 @@ list_iter_p list_iterator(list_p list, char init) { return iter; } -int list_add(list_p list, void* data, dataType_t type, size_t size, char end) { +/** + * Add an item with the given value, type, and size to the list. + * The data is copied by value, so the original pointer must be freed if it + * was allocated on the heap. + * Returns the length of the list if succesfull else returns 0. + * + * \param list pointer to a list + * \param data pointer to data + * \param type type of data + * \param size size of data + * \param end indicator where to add the data + * \return Count of elements in the list + */ +static int list_add(list_p list, void* data, dataType_t type, size_t size, char end) { lnode_p node = (lnode_p)malloc(sizeof(struct linked_node)); node->cont = (container_p)malloc(sizeof(container)); @@ -101,15 +109,49 @@ int list_add(list_p list, void* data, dataType_t type, size_t size, char end) { return list->length; } -int list_append(list_p list, void* data, dataType_t type, size_t size) { +/** + * Add an item with the given calue, type, and size to the end of the list. + * The data is copied by value, so the original pointer must be freed if it + * was allocated on the heap. + * Returns the length of the list if successfull else returns 0. + * + * \param list pointer to a list + * \param data pointer to data + * \param type type of data + * \param size size of data + * \return Count of elements in the list + */ +static int list_append(list_p list, void* data, dataType_t type, size_t size) { return list_add(list, data, type, size, LIST_BACK); } -int list_prepend(list_p list, void* data, dataType_t type, size_t size) { +/** + * Add an item with the given calue, type, and size to the front of the list. + * The data is copied by value, so the original pointer must be freed if it + * was allocated on the heap. + * Returns the length of the list if successfull else returns 0. + * + * \param list pointer to a list + * \param data pointer to data + * \param type type of data + * \param size size of data + * \return Count of elements in the list + */ +static int list_prepend(list_p list, void* data, dataType_t type, size_t size) { return list_add(list, data, type, size, LIST_FRONT); } -int list_add_ptr(list_p list, void* data, dataType_t type, char end) { +/** + * Add a pointer to an item with the given value and type to the list. + * Returns the length of the list if succesfull else returns 0. + * + * \param list pointer to a list + * \param data pointer to data + * \param type type of the data + * \param end indicator where to insert + * \return Count of elements in the list + */ +static int list_add_ptr(list_p list, void* data, dataType_t type, char end) { lnode_p node = (lnode_p)malloc(sizeof(struct linked_node)); node->cont = (container_p)malloc(sizeof(container)); @@ -148,15 +190,39 @@ int list_add_ptr(list_p list, void* data, dataType_t type, char end) { return list->length; } -int list_append_ptr(list_p list, void* data, dataType_t type) { +/** + * Add a pointer to an item with the given calue, type, and size to the end of the list. + * Returns the length of the list if successfull else returns 0. + * + * \param list pointer to a list + * \param data pointer to data + * \param type type of data + * \return Count of elements in list + */ +static int list_append_ptr(list_p list, void* data, dataType_t type) { return list_add_ptr(list, data, type, LIST_BACK); } -int list_prepend_ptr(list_p list, void* data, dataType_t type) { +/** + * Add a pointer to an item with the given calue, type, and size to the front of the list. + * Returns the length of the list if successfull else returns 0. + * + * \param list pointer to a list + * \param data pointer to data + * \param type type of data + * \return Count of elements in list + */ +static int list_prepend_ptr(list_p list, void* data, dataType_t type) { return list_add_ptr(list, data, type, LIST_FRONT); } -container_p list_current(list_iter_p iter){ +/** + * Return the data held by the current item pointed to by the iterator + * + * \param list pointer to a iterator + * \return container for the current element + */ +static container_p list_current(list_iter_p iter){ if(iter->started && iter->current != NULL) { return iter->current->cont; } @@ -164,7 +230,14 @@ container_p list_current(list_iter_p iter){ return NULL; } -container_p list_next(list_iter_p iter) { +/** + * Advances the iterator to the next item in the list and returns the data + * stored there. + * + * \param list pointer to a iterator + * \return container of the next element + */ +static container_p list_next(list_iter_p iter) { if(!iter->started && iter->current != NULL) { iter->started = 1; return iter->current->cont; @@ -178,7 +251,15 @@ container_p list_next(list_iter_p iter) { return NULL; } -container_p list_cycl_next(list_iter_p iter) { +/** + * Advances the iterator to the next item in the list and returns the data + * stored there. If the end of the list is reached it continues with the first + * element of the list. + * + * \param list pointer to a iterator + * \return container of the next element + */ +static container_p list_cycl_next(list_iter_p iter) { if(!iter->started && iter->current != NULL) { iter->started = 1; return iter->current->cont; @@ -193,7 +274,14 @@ container_p list_cycl_next(list_iter_p iter) { return NULL; } -container_p list_prev(list_iter_p iter) { +/** + * Advances the iterator to the previous item in the list and returns the data + * stored there. + * + * \param list pointer to a iterator + * \return container of the previous element + */ +static container_p list_prev(list_iter_p iter) { if(!iter->started&&iter->current!=NULL) { iter->started = 1; return iter->current->cont; @@ -205,7 +293,15 @@ container_p list_prev(list_iter_p iter) { return NULL; } -container_p list_cycl_prev(list_iter_p iter){ +/** + * Advances the iterator to the previous item in the list and returns the data + * stored there. If the start of the list is reached it continues with the last + * element of the list. + * + * \param list pointer to a iterator + * \return container of the previous element + */ +static container_p list_cycl_prev(list_iter_p iter){ if(!iter->started && iter->current != NULL) { iter->started =1 ; return iter->current->cont; @@ -222,15 +318,34 @@ container_p list_cycl_prev(list_iter_p iter){ return NULL; } -container_p list_first(list_p list) { +/** + * Gets the data stored in the first item of the list or NULL if the list is empty + * + * \param list pointer to a list + * \return container for the first element of the list + */ +static container_p list_first(list_p list) { return list->first->cont; } -container_p list_last(list_p list) { +/** + * Gets the data stored in the last item of the list or NULL if the list is empty + * + * \param list pointer to a list + * \return container for the last element of the list + */ +static container_p list_last(list_p list) { return list->last->cont; } -container_p list_pop(list_p list) { +/** + * Removes the last item in the list (LIFO order) and returns the data stored + * there. The data returned must be freed later in order to remain memory safe. + * + * \param list pointer to a list + * \return container for the last element of the list + */ +static container_p list_pop(list_p list) { container_p cont; lnode_p last = list->last; @@ -255,7 +370,14 @@ container_p list_pop(list_p list) { return cont; } -container_p list_poll(list_p list){ +/** + * Removes the first item in the list (FIFO order) and returns the data stored + * there. The data return must be freed later in order to remain memory safe. + * + * \param list pointer to a list + * \return container for the first element of the list + */ +static container_p list_poll(list_p list){ container_p cont; lnode_p first = list->first; @@ -280,7 +402,16 @@ container_p list_poll(list_p list){ return cont; } -void list_remove(list_p list, char end) { +/** + * Convenience function for completely destroying an item in the list. If the end + * flag is LIST_FRONT, an item will be polled from the front of the list and its data + * freed. If the end flag is set to LIST_BACK, an item will be popped off the end of + * the list and the data freed. + * + * \param list pointer to a list + * \param end indicator where to remove + */ +static void list_remove(list_p list, char end) { container_p cont; if(end == LIST_FRONT) { @@ -300,6 +431,64 @@ void list_remove(list_p list, char end) { } } +/** + * Function for completely destroying an item in the list at a given index. + * + * \param list pointer to a list + * \param idx index of the element to remove + */ +static void list_remove_at(list_p list, int idx) { + container_p cont; + list_iter_p iter; + lnode_p target = NULL; + int i; + + if(idx < 0 || idx >= list->length || list->length == 0) { + return; + } + + iter = list_iterator(list, LIST_FRONT); + for(cont = list_next(iter), i = 0; cont != NULL; cont = list_next(iter), i++) { + if(i == idx) { + target = iter->current; + break; + } + } + destroy_iterator(iter); + + if(target == NULL) { + return; + } + + if(list->length == 1) { + list->first = list->last = NULL; + list->length--; + + free(target); + } else { + target->prev->next = target->next; + target->next->prev = target->prev; + + if(target == list->first) { + list->first = target->next; + } + if(target == list->last) { + list->last = target->prev; + } + list->length--; + + free(target); + } + + if(cont != NULL) { + if(cont->pointer == 0 && cont->data != NULL) { + list->destructor(cont->data); + } + + free(cont); + } +} + void destroy_list(list_p list) { lnode_p cur = list->first; lnode_p next; @@ -318,7 +507,12 @@ void destroy_list(list_p list) { free(list); } -void list_clear(list_p list) { +/** + * Remove all elements. + * + * \param list pointer to a list + */ +static void list_clear(list_p list) { while(list->length > 0) { list_remove(list, LIST_BACK); } @@ -332,12 +526,14 @@ void destroy_iterator(list_iter_p iter) { free(iter); } -void list_init(struct list * l, void (*destructor)(void*)) { - memset(l, 0, sizeof(struct list)); - l->destructor = destructor; -} - -container_p list_at(list_p list, int idx) { +/** + * Get the element at the given index. + * + * \param list a list + * \param idx index + * \return element at given index or NULL if index is out of bounds + */ +static container_p list_at(list_p list, int idx) { list_iter_p iter; container_p c = NULL; int i; @@ -356,3 +552,63 @@ container_p list_at(list_p list, int idx) { return c; } +list_p create_list() { + list_p list = (list_p)malloc(sizeof(struct list)); + + if(list == NULL) { + return NULL; + } + + list->length = 0; + list->first = NULL; + list->last = NULL; + list->destructor = free; + list->add = list_add; + list->add_ptr = list_add_ptr; + list->append = list_append; + list->append_ptr = list_append_ptr; + list->at = list_at; + list->clear = list_clear; + list->current = list_current; + list->cycl_next = list_cycl_next; + list->cycl_prev = list_cycl_prev; + list->end = list_first; + list->front = list_last; + list->iterator = list_iterator; + list->next = list_next; + list->poll = list_poll; + list->pop = list_pop; + list->prepend = list_prepend; + list->prepend_ptr = list_prepend_ptr; + list->prev = list_prev; + list->remove = list_remove; + list->removeAt = list_remove_at; + + return list; +} + +void list_init(struct list * l, void (*destructor)(void*)) { + memset(l, 0, sizeof(struct list)); + l->destructor = destructor; + l->add = list_add; + l->add_ptr = list_add_ptr; + l->append = list_append; + l->append_ptr = list_append_ptr; + l->at = list_at; + l->clear = list_clear; + l->current = list_current; + l->cycl_next = list_cycl_next; + l->cycl_prev = list_cycl_prev; + l->end = list_first; + l->front = list_last; + l->iterator = list_iterator; + l->next = list_next; + l->poll = list_poll; + l->pop = list_pop; + l->prepend = list_prepend; + l->prepend_ptr = list_prepend_ptr; + l->prev = list_prev; + l->remove = list_remove; + l->removeAt = list_remove_at; +} + diff --git a/code/game/list.h b/code/game/list.h index 062764a..a68d54f 100644 --- a/code/game/list.h +++ b/code/game/list.h @@ -81,6 +81,16 @@ struct linked_node { */ typedef struct linked_node* lnode_p; +/** + * Type for a pointer to a list iterator. + */ +typedef struct list_iter * list_iter_p; + +/** + * Type for a pointer to a list. + */ +typedef struct list * list_p; + /** * Struct describing a list. */ @@ -89,27 +99,37 @@ struct list{ lnode_p first; /*!< first element of the list */ lnode_p last; /*!< last element of the list */ void (*destructor)(void*); /*!< pointer to destructor for data. Default is free. */ + list_iter_p (*iterator)(list_p list, char init); /*!< creates a new list iterator */ + int (*add_ptr)(list_p list, void* data, dataType_t type, char end); /*!< add a pointer to the list */ + int (*append_ptr)(list_p list, void* data, dataType_t type); /*!< append a pointer to the list */ + int (*prepend_ptr)(list_p list, void* data, dataType_t type); /*!< prepend a pointer to the list */ + int (*add)(list_p list, void* data, dataType_t type, size_t size, char end); /*!< add data to the list */ + int (*append)(list_p list, void* data, dataType_t type, size_t size); /*!< append data to the list */ + int (*prepend)(list_p list, void* data, dataType_t type, size_t size); /*!< prepend data to the list */ + container_p (*at)(list_p list, int idx); /*!< get container at given index */ + void (*clear)(list_p list); /*!< clear the list */ + container_p (*current)(list_iter_p iter); /*!< get the current element for the iterator */ + container_p (*cycl_next)(list_iter_p iter); /*!< get the next element for the iterator (cyclic access) */ + container_p (*cycl_prev)(list_iter_p iter); /*!< get the previous element for the iterator (cyclic acccess) */ + container_p (*front)(list_p list); /*!< get the first element of the list */ + container_p (*end)(list_p list); /*!< get the last element of the list */ + container_p (*next)(list_iter_p iter); /*!< get the next element for the iterator */ + container_p (*prev)(list_iter_p iter); /*!< get the previous element for the iterator */ + container_p (*poll)(list_p list); /*