cycle.c (1618B)
1 #include <stddef.h> // for size_t 2 #include <stdlib.h> // for malloc() and free() 3 #include <assert.h> 4 #include "utils.h" 5 #include "cycle.h" 6 7 /* cycling iterable */ 8 struct Cycle { 9 const void *base; 10 size_t i; 11 size_t memb_n; 12 size_t memb_size; 13 }; 14 15 /* 16 * cycle_new: create a new cycle of array startinng at 'base' with memb_n 17 * elements each of size 'memb_size' 18 */ 19 struct Cycle * 20 cycle_new(const void *base, size_t memb_n, size_t memb_size) 21 { 22 assert(base != NULL); 23 assert(memb_n > 0); 24 assert(memb_size > 0); 25 struct Cycle *cycle = malloc(sizeof *cycle); 26 27 if (cycle == NULL) { 28 return NULL; 29 } 30 cycle->base = base; 31 cycle->i = 0; 32 cycle->memb_n = memb_n; 33 cycle->memb_size = memb_size; 34 return cycle; 35 } 36 37 /* cycle_free: free memmory used by cycle */ 38 void 39 cycle_free(struct Cycle *cycle) 40 { 41 assert(cycle != NULL); 42 free(cycle); 43 } 44 45 /* cycle_index: get index of current element of cycle */ 46 size_t 47 cycle_index(struct Cycle *cycle) 48 { 49 assert(cycle != NULL); 50 return cycle->i; 51 } 52 53 /* cycle_current: get current element of cycle */ 54 const void * 55 cycle_current(struct Cycle *cycle) 56 { 57 assert(cycle != NULL); 58 return (const char *)cycle->base + cycle->memb_size*cycle->i; 59 } 60 61 /* cycle_next: point cycle to next element and return it */ 62 const void * 63 cycle_next(struct Cycle *cycle) 64 { 65 assert(cycle != NULL); 66 cycle->i = (cycle->i >= cycle->memb_n-1) ? 0 : cycle->i+1; 67 return cycle_current(cycle); 68 } 69 70 /* cycle_prev: point cycle to previous elemetn and return it */ 71 const void * 72 cycle_prev(struct Cycle *cycle) 73 { 74 assert(cycle != NULL); 75 cycle->i = (cycle->i <= 0) ? cycle->memb_n-1 : cycle->i-1; 76 return cycle_current(cycle); 77 }