From cc64a9ae6c4ca7518ba904d6cdf38b3d8dccbbf7 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Tue, 5 Dec 2017 12:14:44 +0100 Subject: Add const versions of RefList iteration --- libcrystfel/src/reflist.c | 113 +++++++++++++++++++++++++++++++++++++++++++++- libcrystfel/src/reflist.h | 2 + 2 files changed, 114 insertions(+), 1 deletion(-) diff --git a/libcrystfel/src/reflist.c b/libcrystfel/src/reflist.c index 6f44681d..707c802e 100644 --- a/libcrystfel/src/reflist.c +++ b/libcrystfel/src/reflist.c @@ -955,7 +955,8 @@ struct _reflistiterator { int stack_size; int stack_ptr; Reflection **stack; - + const Reflection **stack_const; + int is_const; }; @@ -980,6 +981,7 @@ Reflection *first_refl(RefList *list, RefListIterator **piter) iter->stack_size = 32; iter->stack = malloc(iter->stack_size*sizeof(Reflection *)); iter->stack_ptr = 0; + iter->is_const = 0; *piter = iter; if ( list == NULL ) return NULL; @@ -1013,6 +1015,60 @@ Reflection *first_refl(RefList *list, RefListIterator **piter) } +/** + * first_refl_const: + * @list: A %RefList to iterate over + * @piter: Address at which to store a %RefListIterator + * + * As first_refl(), except returns a const %Reflection. + * Use this when you don't need to modify any of the reflections. + * + * Returns: the first reflection in the list. + * + **/ +const Reflection *first_refl_const(const RefList *list, RefListIterator **piter) +{ + const Reflection *refl; + RefListIterator *iter; + + iter = malloc(sizeof(struct _reflistiterator)); + iter->stack_size = 32; + iter->stack_const = malloc(iter->stack_size*sizeof(Reflection *)); + iter->stack_ptr = 0; + iter->is_const = 1; + *piter = iter; + + if ( list == NULL ) return NULL; + + refl = list->head; + + do { + + if ( refl != NULL ) { + iter->stack_const[iter->stack_ptr++] = refl; + if ( iter->stack_ptr == iter->stack_size ) { + iter->stack_size += 32; + iter->stack_const = realloc(iter->stack_const, + iter->stack_size*sizeof(Reflection *)); + } + refl = refl->child[0]; + continue; + } + + if ( iter->stack_ptr == 0 ) { + free(iter->stack_const); + free(iter); + return NULL; + } + + refl = iter->stack_const[--iter->stack_ptr]; + + return refl; + + } while ( 1 ); +} + + /** * next_refl: * @refl: A reflection @@ -1026,6 +1082,8 @@ Reflection *first_refl(RefList *list, RefListIterator **piter) **/ Reflection *next_refl(Reflection *refl, RefListIterator *iter) { + assert(!iter->is_const); + /* Are there more reflections with the same indices? */ if ( refl->next != NULL ) { return refl->next; @@ -1065,6 +1123,59 @@ Reflection *next_refl(Reflection *refl, RefListIterator *iter) } +/** + * next_refl_const: + * @refl: A reflection + * @iter: A %RefListIterator + * + * As next_refl(), except returns a const %Reflection. + * Use this when you don't need to modify any of the reflections. + * + * Returns: the next reflection in the list, or NULL if no more. + * + **/ +const Reflection *next_refl_const(const Reflection *refl, RefListIterator *iter) +{ + assert(iter->is_const); + + /* Are there more reflections with the same indices? */ + if ( refl->next != NULL ) { + return refl->next; + } else { + + /* No, so rewind back to the head of the list */ + while ( refl->prev != NULL ) { + refl = refl->prev; + } + + } + + refl = refl->child[1]; + do { + + if ( refl != NULL ) { + + iter->stack_const[iter->stack_ptr++] = refl; + if ( iter->stack_ptr == iter->stack_size ) { + iter->stack_size += 32; + iter->stack_const = realloc(iter->stack_const, + iter->stack_size*sizeof(Reflection *)); + } + refl = refl->child[0]; + continue; + + } + if ( iter->stack_ptr == 0 ) { + free(iter->stack_const); + free(iter); + return NULL; + } + + return iter->stack_const[--iter->stack_ptr]; + + } while ( 1 ); +} + /*********************************** Voodoo ***********************************/ static int recursive_depth(Reflection *refl) diff --git a/libcrystfel/src/reflist.h b/libcrystfel/src/reflist.h index 3f0ff783..f2126ac9 100644 --- a/libcrystfel/src/reflist.h +++ b/libcrystfel/src/reflist.h @@ -132,6 +132,8 @@ extern void add_refl_to_list(Reflection *refl, RefList *list); /* Iteration */ extern Reflection *first_refl(RefList *list, RefListIterator **piter); extern Reflection *next_refl(Reflection *refl, RefListIterator *iter); +extern const Reflection *first_refl_const(const RefList *list, RefListIterator **piter); +extern const Reflection *next_refl_const(const Reflection *refl, RefListIterator *iter); /* Misc */ extern int num_reflections(RefList *list); -- cgit v1.2.3