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