Commit Diff


commit - b7a1d3fcb52c4517db8f3bd9fe6c242078e4bd24
commit + 5256e868ed7f0d40ccaf480bd903ef722df4a052
blob - aa3d3a9f05645beee2c1a4c390185747da6bcb99
blob + ba38adb6678861381669e0b59ea2d874f47eb8ad
--- include/lfvector.h
+++ include/lfvector.h
@@ -34,6 +34,14 @@ const void *vec_min(const Vector *vec, int(*cmp)(const
 
 const void *vec_max(const Vector *vec, int(*cmp)(const void *a, const void *b));
 
+void *vec_pop(Vector *vec);
+
+void vec_reverse(Vector *vec);
+
+void vec_sort(Vector *vec, int (*cmp)(const void *a, const void *b));
+
+void *vec_bsearch(Vector *vec, const void *key, int (*cmp)(const void *a, const void *b));
+
 int vec_cmp_int(const void *a, const void *b);
 
 int vec_cmp_char(const void *a, const void *b);
blob - 86f65c6f6b4f52c38a382ae4a35ab935d0a45eb9
blob + 4fcf4f00c195c3b8f19fab2c186ffad1ee7d1aa9
--- src/vector.c
+++ src/vector.c
@@ -13,6 +13,8 @@
 
 #define VEC_INIT_CAP 2
 
+static int (*vec_sort_cmp_fn)(const void *, const void *);
+
 int vec_init(Vector *vec, void (*destroy)(void *data)) {
     return vec_init_with_capacity(vec, destroy, VEC_INIT_CAP);
 }
@@ -178,6 +180,57 @@ const void *vec_max(const Vector *vec, int(*cmp)(const
     return a;
 }
 
+void *vec_pop(Vector *vec) {
+    if (vec_len(vec) == 0) {
+        return NULL;
+    }
+    return vec_remove(vec, vec_len(vec) - 1);
+}
+
+void vec_reverse(Vector *vec) {
+    size_t lo = 0;
+    size_t hi = vec_len(vec);
+    while (lo + 1 < hi) {
+        --hi;
+        void *tmp = vec->elements[lo];
+        vec->elements[lo] = vec->elements[hi];
+        vec->elements[hi] = tmp;
+        ++lo;
+    }
+}
+
+static int vec_sort_cmp_wrapper(const void *a, const void *b) {
+    /* qsort passes pointers to elements; our elements are void*, so a is void** */
+    const void *ea = *(const void **)a;
+    const void *eb = *(const void **)b;
+    return vec_sort_cmp_fn(ea, eb);
+}
+
+void vec_sort(Vector *vec, int (*cmp)(const void *a, const void *b)) {
+    if (vec_len(vec) < 2) {
+        return;
+    }
+    vec_sort_cmp_fn = cmp;
+    qsort(vec->elements, vec_len(vec), sizeof(void *), vec_sort_cmp_wrapper);
+}
+
+void *vec_bsearch(Vector *vec, const void *key, int (*cmp)(const void *a, const void *b)) {
+    size_t lo = 0;
+    size_t hi = vec_len(vec);
+    while (lo < hi) {
+        size_t mid = lo + (hi - lo) / 2;
+        int r = cmp(key, vec->elements[mid]);
+        if (r == 0) {
+            return vec->elements[mid];
+        } else if (r < 0) {
+            hi = mid;
+        } else {
+            lo = mid + 1;
+        }
+    }
+    return NULL;
+}
+
 int vec_cmp_int(const void *a, const void *b) {
     const int x = *(int*)a;
     const int y = *(int*)b;
blob - efca273644b392b0885d8e9f10840b81d4e34dc7
blob + 104b6f1acfc1c7a060396ba8ebc70626d3995941
--- tests/test_vector.c
+++ tests/test_vector.c
@@ -56,6 +56,80 @@ int main() {
     ASSERT_EQ(vec_len(v), 0);
 
     vec_destroy(v);
+
+    /* vec_pop */
+    vec_init(v, NULL);
+    int p1 = 10, p2 = 20, p3 = 30;
+    vec_push(v, &p1);
+    vec_push(v, &p2);
+    vec_push(v, &p3);
+
+    int *popped = vec_pop(v);
+    ASSERT_EQ(*popped, 30);
+    ASSERT_EQ(vec_len(v), 2);
+
+    popped = vec_pop(v);
+    ASSERT_EQ(*popped, 20);
+
+    popped = vec_pop(v);
+    ASSERT_EQ(*popped, 10);
+    ASSERT_EQ(vec_len(v), 0);
+
+    popped = vec_pop(v);
+    ASSERT_NULL(popped);
+
+    vec_destroy(v);
+
+    /* vec_reverse */
+    vec_init(v, NULL);
+    int r1 = 1, r2 = 2, r3 = 3, r4 = 4;
+    vec_push(v, &r1);
+    vec_push(v, &r2);
+    vec_push(v, &r3);
+    vec_push(v, &r4);
+
+    vec_reverse(v);
+    ASSERT_EQ(*(int *)vec_at(v, 0), 4);
+    ASSERT_EQ(*(int *)vec_at(v, 1), 3);
+    ASSERT_EQ(*(int *)vec_at(v, 2), 2);
+    ASSERT_EQ(*(int *)vec_at(v, 3), 1);
+
+    /* reverse odd-length */
+    vec_pop(v);
+    vec_reverse(v);
+    ASSERT_EQ(*(int *)vec_at(v, 0), 2);
+    ASSERT_EQ(*(int *)vec_at(v, 1), 3);
+    ASSERT_EQ(*(int *)vec_at(v, 2), 4);
+
+    vec_destroy(v);
+
+    /* vec_sort */
+    vec_init(v, NULL);
+    int s1 = 5, s2 = 1, s3 = 3, s4 = 2, s5 = 4;
+    vec_push(v, &s1);
+    vec_push(v, &s2);
+    vec_push(v, &s3);
+    vec_push(v, &s4);
+    vec_push(v, &s5);
+
+    vec_sort(v, vec_cmp_int);
+    ASSERT_EQ(*(int *)vec_at(v, 0), 1);
+    ASSERT_EQ(*(int *)vec_at(v, 1), 2);
+    ASSERT_EQ(*(int *)vec_at(v, 2), 3);
+    ASSERT_EQ(*(int *)vec_at(v, 3), 4);
+    ASSERT_EQ(*(int *)vec_at(v, 4), 5);
+
+    /* vec_bsearch on sorted vector */
+    int key = 3;
+    int *found = vec_bsearch(v, &key, vec_cmp_int);
+    ASSERT_NOT_NULL(found);
+    ASSERT_EQ(*found, 3);
+
+    int missing = 99;
+    found = vec_bsearch(v, &missing, vec_cmp_int);
+    ASSERT_NULL(found);
+
+    vec_destroy(v);
     free(v);
 
     TEST_REPORT();