Lists are good
This commit is contained in:
		
							parent
							
								
									05c55837fb
								
							
						
					
					
						commit
						64ec8a8e5a
					
				
					 2 changed files with 247 additions and 0 deletions
				
			
		
							
								
								
									
										64
									
								
								include/patty/list.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								include/patty/list.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,64 @@ | |||
| #ifndef _PATTY_LIST_H | ||||
| #define _PATTY_LIST_H | ||||
| 
 | ||||
| #include <stdint.h> | ||||
| #include <sys/types.h> | ||||
| 
 | ||||
| typedef struct _patty_list_item { | ||||
|     struct _patty_list_item * prev; | ||||
|     struct _patty_list_item * next; | ||||
| 
 | ||||
|     void * value; | ||||
| } patty_list_item; | ||||
| 
 | ||||
| typedef struct _patty_list { | ||||
|     uint64_t size; | ||||
|     uint64_t length; | ||||
| 
 | ||||
|     patty_list_item * first; | ||||
|     patty_list_item * last; | ||||
| } patty_list; | ||||
| 
 | ||||
| typedef struct _patty_list_iterator { | ||||
|     patty_list *list; | ||||
| 
 | ||||
|     size_t index; | ||||
|     patty_list_item * item; | ||||
| } patty_list_iterator; | ||||
| 
 | ||||
| typedef void (*patty_list_callback)(void *item, void *ctx); | ||||
| 
 | ||||
| patty_list *patty_list_new(); | ||||
| 
 | ||||
| void patty_list_destroy(patty_list *list); | ||||
| 
 | ||||
| size_t patty_list_length(patty_list *list); | ||||
| 
 | ||||
| void *patty_list_set(patty_list *list, off_t index, void *item); | ||||
| 
 | ||||
| void *patty_list_append(patty_list *list, void *item); | ||||
| 
 | ||||
| void *patty_list_prepend(patty_list *list, void *item); | ||||
| 
 | ||||
| void *patty_list_last(patty_list *list); | ||||
| 
 | ||||
| void *patty_list_pop(patty_list *list); | ||||
| 
 | ||||
| void *patty_list_insert(patty_list *list, off_t index); | ||||
| 
 | ||||
| void *patty_list_index(patty_list *list, off_t index); | ||||
| 
 | ||||
| patty_list_iterator *patty_list_start(patty_list *list); | ||||
| 
 | ||||
| void *patty_list_next(patty_list_iterator *iterator); | ||||
| 
 | ||||
| void patty_list_reset(patty_list_iterator *iterator); | ||||
| 
 | ||||
| void patty_list_finish(patty_list_iterator *iterator); | ||||
| 
 | ||||
| void patty_list_each( | ||||
|     patty_list *        list, | ||||
|     patty_list_callback callback, | ||||
|     void *                ctx); | ||||
| 
 | ||||
| #endif /* _PATTY_LIST_H */ | ||||
							
								
								
									
										183
									
								
								src/list.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										183
									
								
								src/list.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,183 @@ | |||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <sys/types.h> | ||||
| 
 | ||||
| #include <patty/list.h> | ||||
| 
 | ||||
| patty_list *patty_list_new() { | ||||
|     patty_list *list; | ||||
| 
 | ||||
|     if ((list = malloc(sizeof(*list))) == NULL) { | ||||
|         goto error_malloc_list; | ||||
|     } | ||||
| 
 | ||||
|     list->length = 0; | ||||
|     list->size   = 0; | ||||
|     list->first  = NULL; | ||||
|     list->last   = NULL; | ||||
| 
 | ||||
|     return list; | ||||
| 
 | ||||
| error_malloc_list: | ||||
|     return NULL; | ||||
| } | ||||
| 
 | ||||
| void patty_list_destroy(patty_list *list) { | ||||
|     patty_list_item *item = list->first; | ||||
| 
 | ||||
|     while (item != NULL) { | ||||
|         patty_list_item *next = (patty_list_item *)item->next; | ||||
| 
 | ||||
|         free(item); | ||||
| 
 | ||||
|         item = next; | ||||
|     } | ||||
| 
 | ||||
|     free(list); | ||||
| } | ||||
| 
 | ||||
| size_t patty_list_length(patty_list *list) { | ||||
|     return list->length; | ||||
| } | ||||
| 
 | ||||
| void *patty_list_set(patty_list *list, off_t index, void *value) { | ||||
|     patty_list_item *item = list->first; | ||||
|     size_t i = 0; | ||||
| 
 | ||||
|     while (item != NULL) { | ||||
|         if (i++ == index) { | ||||
|             return item->value = value; | ||||
|         } | ||||
| 
 | ||||
|         item = item->next; | ||||
|     } | ||||
| 
 | ||||
|     return NULL; | ||||
| } | ||||
| 
 | ||||
| void *patty_list_append(patty_list *list, void *value) { | ||||
|     patty_list_item *item = list->first; | ||||
|     patty_list_item *new; | ||||
| 
 | ||||
|     if ((new = malloc(sizeof(*new))) == NULL) { | ||||
|         goto error_malloc_item; | ||||
|     } | ||||
| 
 | ||||
|     new->value = value; | ||||
| 
 | ||||
|     if (list->first == NULL) { | ||||
|         list->first = new; | ||||
|     } else { | ||||
|         for (item = list->first; item->next != NULL; item = item->next); | ||||
| 
 | ||||
|         item->next = new; | ||||
|     } | ||||
| 
 | ||||
|     list->length++; | ||||
| 
 | ||||
|     return value; | ||||
| 
 | ||||
| error_malloc_item: | ||||
|     return NULL; | ||||
| } | ||||
| 
 | ||||
| void *patty_list_last(patty_list *list) { | ||||
|     patty_list_item *item = list->first; | ||||
| 
 | ||||
|     while (item->next != NULL) { | ||||
|         item = item->next; | ||||
|     } | ||||
| 
 | ||||
|     return item->value; | ||||
| } | ||||
| 
 | ||||
| void *patty_list_pop(patty_list *list) { | ||||
|     patty_list_item *item = list->first; | ||||
|     patty_list_item *last = NULL; | ||||
| 
 | ||||
|     while (item != NULL) { | ||||
|         if (item->next == NULL) { | ||||
|             void *ret = item->value; | ||||
| 
 | ||||
|             if (last == NULL) { | ||||
|                 list->first = NULL; | ||||
|             } else { | ||||
|                 last->next = NULL; | ||||
|             } | ||||
| 
 | ||||
|             free(item); | ||||
| 
 | ||||
|             return ret; | ||||
|         } | ||||
| 
 | ||||
|         last = item; | ||||
|         item = item->next; | ||||
|     } | ||||
| 
 | ||||
|     return NULL; | ||||
| } | ||||
| 
 | ||||
| void *patty_list_index(patty_list *list, off_t index) { | ||||
|     patty_list_item *item = list->first; | ||||
|     size_t i = 0; | ||||
| 
 | ||||
|     if (index < 0) { | ||||
|         index += list->length; | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     if (index >= list->length || index < 0) { | ||||
|         return NULL; | ||||
|     } | ||||
| 
 | ||||
|     while (i < index && item->next != NULL) { | ||||
|         item = item->next; | ||||
|         i++; | ||||
|     } | ||||
| 
 | ||||
|     return item->value; | ||||
| } | ||||
| 
 | ||||
| patty_list_iterator *patty_list_start(patty_list *list) { | ||||
|     patty_list_iterator *iterator; | ||||
| 
 | ||||
|     if ((iterator = malloc(sizeof(patty_list_iterator))) == NULL) { | ||||
|         goto error_malloc; | ||||
|     } | ||||
| 
 | ||||
|     iterator->list = list; | ||||
|     iterator->item = list->first; | ||||
| 
 | ||||
|     return iterator; | ||||
| 
 | ||||
| error_malloc: | ||||
|     return NULL; | ||||
| } | ||||
| 
 | ||||
| void *patty_list_next(patty_list_iterator *iterator) { | ||||
|     void *value = NULL; | ||||
| 
 | ||||
|     if (iterator->item) { | ||||
|         value = iterator->item->value; | ||||
| 
 | ||||
|         iterator->item = iterator->item->next; | ||||
|     } | ||||
| 
 | ||||
|     return value; | ||||
| } | ||||
| 
 | ||||
| void patty_list_reset(patty_list_iterator *iterator) { | ||||
|     iterator->item = iterator->list->first; | ||||
| } | ||||
| 
 | ||||
| void patty_list_finish(patty_list_iterator *iterator) { | ||||
|     free(iterator); | ||||
| } | ||||
| 
 | ||||
| void patty_list_each(patty_list *list, patty_list_callback callback, void *ctx) { | ||||
|     patty_list_item *item; | ||||
| 
 | ||||
|     for (item = list->first; item != NULL; item = item->next) { | ||||
|         callback(item->value, ctx); | ||||
|     } | ||||
| } | ||||
		Loading…
	
	Add table
		
		Reference in a new issue