diff options
Diffstat (limited to 'lib/vector.c')
-rw-r--r-- | lib/vector.c | 103 |
1 files changed, 73 insertions, 30 deletions
diff --git a/lib/vector.c b/lib/vector.c index 8268c830..b1ec160d 100644 --- a/lib/vector.c +++ b/lib/vector.c @@ -234,6 +234,79 @@ vector_ream(vector v, int free_structure) } ; /*============================================================================== + * Unset item, condensing and trimming vector. + */ + +/* Trim any NULL entries at the current (logical) end of the vector. + * + * Returns the (new) end of the vector. + */ +extern vector_index +vector_trim(vector v) +{ + vector_index i = v->end ; + while ((i > 0) && (v->p_items[i - 1] == NULL)) + --i ; + v->end = i ; + return i ; +} ; + +/* Removes any NULL entries from the given vector. + * + * Returns the (new) end of the vector. + */ +extern vector_index vector_condense(vector v) +{ + vector_index i = 0 ; + vector_index j ; + + /* Find first NULL, if any */ + while ((i < v->end) && (v->p_items[i] != NULL)) + ++i ; + + /* Quit if no NULLs (or vector is empty) */ + if (i == v->end) + return i ; + + /* Shuffle any remaining non-NULL down */ + for (j = i + 1 ; j < v->end ; ++j) + if (v->p_items[j] != NULL) + v->p_items[i++] = v->p_items[j] ; + + v->end = i ; + + return i ; +} ; + +/* Unset item at given index (ie set it NULL). + * + * Return the old value of the item. + * + * If the item at the current (logical) end of the vector is NULL, move the + * end backwards until finds a non-NULL item, or the vector becomes empty. + */ +extern p_vector_item +vector_unset_item(vector v, vector_index i) +{ + p_vector_item was ; + + if (i < v->end) + { + was = v->p_items[i] ; + v->p_items[i] = NULL ; + } + else if (v->end == 0) + return NULL ; /* avoid test for last entry NULL if is empty */ + else + was = NULL ; + + if (v->p_items[v->end - 1] == NULL) + vector_trim(v) ; + + return was ; +} ; + +/*============================================================================== * Inserting and deleting items. */ @@ -822,36 +895,6 @@ vector_lookup_ensure (vector v, vector_index i) return v->p_items[i]; } -/* Unset value at specified index slot. */ -void -vector_unset (vector v, vector_index i) -{ - vector_index j ; - if (i >= v->end) - return; /* Everything beyond or at end is implicitly NULL */ - - v->p_items[i] = NULL; - - /* See if everything ahead of 'i' is also NULL. */ - j = i ; - while (++j < v->end) - if (v->p_items[j] != NULL) - return ; /* Finished if anything ahead 'i' is not NULL */ - - /* Everything from 'i' onwards is NULL. - * Step backwards across any NULLs and then set the new end. - */ -#if 0 - v->end--; - while (i && v->p_items[--i] == NULL && v->end--) - ; /* Is this ugly ? */ -#endif - while ((i != 0) && (v->p_items[i - 1] == NULL)) - --i ; - - v->end = i ; -} - /* Count the number of not empty slots. */ vector_index vector_count (vector v) |