summaryrefslogtreecommitdiffstats
path: root/lib/vector.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/vector.c')
-rw-r--r--lib/vector.c103
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)