mirror of
https://github.com/rizinorg/rizin.git
synced 2026-10-12 02:21:57 +00:00
Several rz_vector improvements. (#6250)
* Add getter for vector capacity. * Make rz_(p)vector_assign_at consistent in behavior. * Document rz_vector_clear * Move doxygen for rz_vector_flush to definition. * Add rz_vector_purge for clearing, but capacity keeping. * Rename flush -> take_array to signal ownership transfer.
This commit is contained in:
+1
-1
@@ -102,7 +102,7 @@ RZ_API RzBinSourceLineInfo *rz_bin_source_line_info_builder_build_and_fini(RzBin
|
||||
|
||||
RzPVector sorter;
|
||||
rz_pvector_init(&sorter, NULL);
|
||||
RzBinSourceLineSample *initial_samples = rz_vector_flush(&builder->samples);
|
||||
RzBinSourceLineSample *initial_samples = rz_vector_take_array(&builder->samples);
|
||||
rz_pvector_reserve(&sorter, initial_samples_count);
|
||||
for (size_t i = 0; i < initial_samples_count; i++) {
|
||||
rz_pvector_push(&sorter, &initial_samples[i]);
|
||||
|
||||
+1
-1
@@ -139,7 +139,7 @@ RZ_API RzILRegBinding *rz_il_reg_binding_derive(RZ_NONNULL RzReg *reg) {
|
||||
}
|
||||
// from now on, the array should be treated immutable, so we deliberately don't use RzVector anymore.
|
||||
rb->regs_count = rz_vector_len(®s);
|
||||
rb->regs = rz_vector_flush(®s);
|
||||
rb->regs = rz_vector_take_array(®s);
|
||||
rz_vector_fini(®s);
|
||||
return rb;
|
||||
err:
|
||||
|
||||
+49
-22
@@ -90,7 +90,7 @@ static inline bool rz_vector_empty(RZ_NULLABLE const RzVector *vec) {
|
||||
return vec ? vec->len == 0 : true;
|
||||
}
|
||||
|
||||
RZ_API void rz_vector_clear(RzVector *vec);
|
||||
RZ_API void rz_vector_clear(RZ_BORROW RzVector *vec);
|
||||
|
||||
// returns the length of the vector
|
||||
static inline size_t rz_vector_len(RZ_NULLABLE const RzVector *vec) {
|
||||
@@ -118,13 +118,7 @@ static inline void *rz_vector_tail(RzVector *vec) {
|
||||
return (char *)vec->a + vec->elem_size * (vec->len - 1);
|
||||
}
|
||||
|
||||
// helper function to assign an element of size vec->elem_size from elem to p.
|
||||
// elem is a pointer to the actual data to assign!
|
||||
RZ_API void rz_vector_assign(RzVector *vec, void *p, void *elem);
|
||||
|
||||
// assign the value of size vec->elem_size at elem to vec at the given index.
|
||||
// elem is a pointer to the actual data to assign!
|
||||
RZ_API void *rz_vector_assign_at(RzVector *vec, size_t index, void *elem);
|
||||
RZ_API void *rz_vector_assign_at(RZ_BORROW RzVector *vec, size_t index, RZ_NULLABLE const void *elem);
|
||||
|
||||
// remove the element at the given index and write the content to into.
|
||||
// It is the caller's responsibility to free potential resources associated with the element.
|
||||
@@ -136,6 +130,8 @@ RZ_API void rz_vector_remove_at(RzVector *vec, size_t index, void *into);
|
||||
*/
|
||||
RZ_API void rz_vector_remove_range(RzVector *vec, size_t index, size_t count, void *into);
|
||||
|
||||
RZ_API void rz_vector_purge(RZ_BORROW RzVector *vec);
|
||||
|
||||
// insert the value of size vec->elem_size at x at the given index.
|
||||
// x is a pointer to the actual data to assign!
|
||||
RZ_API void *rz_vector_insert(RzVector *vec, size_t index, void *x);
|
||||
@@ -174,18 +170,28 @@ RZ_API void *rz_vector_reserve(RzVector *vec, size_t capacity);
|
||||
// shrink capacity to len.
|
||||
RZ_API void *rz_vector_shrink(RzVector *vec);
|
||||
|
||||
/**
|
||||
* \brief Turn the vector into a fixed-size array.
|
||||
* This will clear the vector and return an array of its original contents whose
|
||||
* ownership is transferred to the caller.
|
||||
* This is useful when RzVector is used for its dynamically growing functionality as an
|
||||
* intermediate step to generate a fixed-size array in the end.
|
||||
*/
|
||||
RZ_API void *rz_vector_flush(RzVector *vec);
|
||||
RZ_API RZ_OWN void *rz_vector_take_array(RzVector *vec);
|
||||
|
||||
// sort vector
|
||||
RZ_API void rz_vector_sort(RzVector *vec, RzVectorComparator cmp, bool reverse, void *user);
|
||||
|
||||
/**
|
||||
* \brief Return the capacity of the vector.
|
||||
*/
|
||||
static inline size_t rz_vector_capacity(RzVector *vec) {
|
||||
rz_return_val_if_fail(vec, 0);
|
||||
return vec->capacity;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set element at \p index.
|
||||
* \param vec The vector to update.
|
||||
*/
|
||||
static inline void rz_vector_set(RZ_BORROW RzVector *vec, size_t index, const RZ_NONNULL void *elem) {
|
||||
rz_return_if_fail(vec && index < rz_vector_capacity(vec) && elem);
|
||||
rz_vector_assign_at(vec, index, elem);
|
||||
}
|
||||
|
||||
/*
|
||||
* example:
|
||||
*
|
||||
@@ -251,8 +257,7 @@ RZ_API RzPVector *rz_pvector_new(RzPVectorFree free);
|
||||
|
||||
RZ_API RzPVector *rz_pvector_new_with_len(RzPVectorFree free, size_t length);
|
||||
|
||||
// clear the vector and call vec->v.free on every element.
|
||||
RZ_API void rz_pvector_clear(RzPVector *vec);
|
||||
RZ_API void rz_pvector_clear(RZ_BORROW RzPVector *vec);
|
||||
|
||||
// free the vector and call vec->v.free on every element.
|
||||
RZ_API void rz_pvector_free(RzPVector *vec);
|
||||
@@ -281,8 +286,15 @@ static inline void *rz_pvector_at(const RzPVector *vec, size_t index) {
|
||||
return ((void **)vec->v.a)[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return the capacity of the pvector.
|
||||
*/
|
||||
static inline size_t rz_pvector_capacity(RzPVector *vec) {
|
||||
return rz_vector_capacity(&vec->v);
|
||||
}
|
||||
|
||||
static inline void rz_pvector_set(RzPVector *vec, size_t index, void *e) {
|
||||
rz_return_if_fail(vec && index < vec->v.len);
|
||||
rz_return_if_fail(vec && index < rz_pvector_capacity(vec));
|
||||
((void **)vec->v.a)[index] = e;
|
||||
}
|
||||
|
||||
@@ -326,11 +338,19 @@ RZ_API size_t rz_pvector_find_index(RZ_NONNULL const RzPVector *vec, RZ_NONNULL
|
||||
// join two pvector into one, pvec1 should free the joined element in pvec2
|
||||
RZ_API bool rz_pvector_join(RZ_NONNULL RzPVector *pvec1, RZ_NONNULL RzPVector *pvec2);
|
||||
|
||||
RZ_API void *rz_pvector_assign_at(RZ_BORROW RZ_NONNULL RzPVector *vec, size_t index, RZ_OWN RZ_NONNULL void *ptr);
|
||||
RZ_API void *rz_pvector_assign_at(RZ_BORROW RZ_NONNULL RzPVector *vec, size_t index, RZ_OWN RZ_NULLABLE void *ptr);
|
||||
|
||||
// removes and returns the pointer at the given index. Does not call free.
|
||||
RZ_API void *rz_pvector_remove_at(RzPVector *vec, size_t index);
|
||||
|
||||
/**
|
||||
* \brief Deletes all pointers in the vector. Capacity stays the same.
|
||||
*/
|
||||
static inline void rz_pvector_purge(RZ_BORROW RzPVector *vec) {
|
||||
rz_return_if_fail(vec);
|
||||
rz_vector_purge(&vec->v);
|
||||
}
|
||||
|
||||
// removes the element x, if present. Does not call free.
|
||||
RZ_API void rz_pvector_remove_data(RzPVector *vec, void *x);
|
||||
|
||||
@@ -374,8 +394,15 @@ static inline void **rz_pvector_shrink(RzPVector *vec) {
|
||||
return (void **)rz_vector_shrink(&vec->v);
|
||||
}
|
||||
|
||||
static inline void **rz_pvector_flush(RzPVector *vec) {
|
||||
return (void **)rz_vector_flush(&vec->v);
|
||||
/**
|
||||
* \brief Turn the vector into a fixed-size array.
|
||||
* This will clear the vector and return an array of its original contents whose
|
||||
* ownership is transferred to the caller.
|
||||
* This is useful when RzPVector is used for its dynamically growing functionality as an
|
||||
* intermediate step to generate a fixed-size array in the end.
|
||||
*/
|
||||
static inline void **rz_pvector_flush(RZ_BORROW RzPVector *vec) {
|
||||
return (void **)rz_vector_take_array(&vec->v);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+82
-19
@@ -2,6 +2,7 @@
|
||||
// SPDX-FileCopyrightText: 2017-2020 thestr4ng3r <[email protected]>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include "rz_util/rz_assert.h"
|
||||
#include "rz_vector.h"
|
||||
|
||||
// Optimize memory usage on glibc
|
||||
@@ -69,7 +70,13 @@ RZ_API void rz_vector_fini(RzVector *vec) {
|
||||
vec->free_user = NULL;
|
||||
}
|
||||
|
||||
RZ_API void rz_vector_clear(RzVector *vec) {
|
||||
/**
|
||||
* \brief Removes all elements, frees the internal buffer, and
|
||||
* sets the vector's capacity to 0.
|
||||
*
|
||||
* Use rz_vector_purge() if the buffer's capacity should not change.
|
||||
*/
|
||||
RZ_API void rz_vector_clear(RZ_BORROW RzVector *vec) {
|
||||
rz_return_if_fail(vec);
|
||||
vector_free_elems(vec);
|
||||
RZ_FREE(vec->a);
|
||||
@@ -83,6 +90,19 @@ RZ_API void rz_vector_free(RzVector *vec) {
|
||||
}
|
||||
}
|
||||
|
||||
static void rz_vector_assign(RzVector *vec, void *p, const void *elem) {
|
||||
rz_return_if_fail(vec && p && elem);
|
||||
memcpy(p, elem, vec->elem_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set \p n elements, starting at element \p i to \p c.
|
||||
*/
|
||||
static void rz_vector_zeroize(RzVector *vec, size_t i, size_t n) {
|
||||
rz_return_if_fail(vec);
|
||||
memset(vec->a + (vec->elem_size * i), 0, vec->elem_size * n);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Clone the contents of \p src into \p dst.
|
||||
* \param dst The vector to clone into.
|
||||
@@ -180,16 +200,33 @@ RZ_API RZ_OWN RzVector *rz_vector_clone(
|
||||
return dst;
|
||||
}
|
||||
|
||||
RZ_API void rz_vector_assign(RzVector *vec, void *p, void *elem) {
|
||||
rz_return_if_fail(vec && p && elem);
|
||||
memcpy(p, elem, vec->elem_size);
|
||||
}
|
||||
|
||||
RZ_API void *rz_vector_assign_at(RzVector *vec, size_t index, void *elem) {
|
||||
/**
|
||||
* \brief Assign the element \p elem at \p index in the vector.
|
||||
*
|
||||
* NOTE: This function can update the length of the vector. If the index
|
||||
* points after the last element, but not beyond the vector's capacity, it
|
||||
* sets the vector length to \p index + 1. Elements at [len, index) are set to zero.
|
||||
* Use rz_vector_set() if you need sideeffect-less manipulation of the vector slots.
|
||||
*
|
||||
* \param vec The vector to assign to.
|
||||
* \param index The index to assign the element to.
|
||||
* \param elem Pointer to the element to assign. If NULL, only the vector length is updated under the above condition.
|
||||
*
|
||||
* \return Pointer to the element at \p index. Or NULL in case of failure.
|
||||
*/
|
||||
RZ_API void *rz_vector_assign_at(RZ_BORROW RzVector *vec, size_t index, RZ_NULLABLE const void *elem) {
|
||||
rz_return_val_if_fail(vec && index < vec->capacity, NULL);
|
||||
void *p = rz_vector_index_ptr(vec, index);
|
||||
if (elem) {
|
||||
rz_vector_assign(vec, p, elem);
|
||||
}
|
||||
if (index >= rz_vector_len(vec)) {
|
||||
size_t len = rz_vector_len(vec);
|
||||
// Also zero the slot at index, if no element is assigned to it.
|
||||
size_t n = index - len + (!elem ? 1 : 0);
|
||||
rz_vector_zeroize(vec, len, n);
|
||||
vec->len = index + 1;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -219,6 +256,16 @@ RZ_API void rz_vector_remove_range(RzVector *vec, size_t index, size_t count, vo
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Deletes all elements in the vector. The internal buffer is not freed
|
||||
* so the vector's capacity stays the same.
|
||||
*
|
||||
* Use rz_vector_clear() if the buffer should be freed.
|
||||
*/
|
||||
RZ_API void rz_vector_purge(RZ_BORROW RzVector *vec) {
|
||||
vector_free_elems(vec);
|
||||
}
|
||||
|
||||
RZ_API void *rz_vector_insert(RzVector *vec, size_t index, void *x) {
|
||||
rz_return_val_if_fail(vec && index <= vec->len, NULL);
|
||||
if (vec->len >= vec->capacity) {
|
||||
@@ -436,7 +483,14 @@ RZ_API void *rz_vector_shrink(RzVector *vec) {
|
||||
return vec->a;
|
||||
}
|
||||
|
||||
RZ_API void *rz_vector_flush(RzVector *vec) {
|
||||
/**
|
||||
* \brief Turn the vector into a fixed-size array.
|
||||
* This will clear the vector and return an array of its original contents whose
|
||||
* ownership is transferred to the caller.
|
||||
* This is useful when RzVector is used for its dynamically growing functionality as an
|
||||
* intermediate step to generate a fixed-size array in the end.
|
||||
*/
|
||||
RZ_API RZ_OWN void *rz_vector_take_array(RZ_BORROW RzVector *vec) {
|
||||
rz_return_val_if_fail(vec, NULL);
|
||||
rz_vector_shrink(vec);
|
||||
void *r = vec->a;
|
||||
@@ -532,12 +586,15 @@ RZ_API RzPVector *rz_pvector_new_with_len(RzPVectorFree free, size_t length) {
|
||||
rz_pvector_free(v);
|
||||
return NULL;
|
||||
}
|
||||
memset(p, 0, v->v.elem_size * v->v.capacity);
|
||||
rz_vector_zeroize(&v->v, 0, v->v.capacity);
|
||||
v->v.len = length;
|
||||
return v;
|
||||
}
|
||||
|
||||
RZ_API void rz_pvector_clear(RzPVector *vec) {
|
||||
/**
|
||||
* \brief Removes all elements and frees the internal buffer.
|
||||
*/
|
||||
RZ_API void rz_pvector_clear(RZ_BORROW RzPVector *vec) {
|
||||
rz_return_if_fail(vec);
|
||||
rz_vector_clear(&vec->v);
|
||||
}
|
||||
@@ -638,26 +695,32 @@ RZ_API bool rz_pvector_join(RZ_NONNULL RzPVector *pvec1, RZ_NONNULL RzPVector *p
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Assign the pointer \p ptr at \p index in the pvector.
|
||||
* \brief Assign the pointer \p ptr at \p index into the pvector.
|
||||
*
|
||||
* NOTE: This function can update the length of the vector. If the index
|
||||
* points after the last element, but not beyond the vector's capacity, it
|
||||
* sets the vector length to \p index + 1. Elements at [len, index) are set to zero.
|
||||
* Use rz_pvector_set() if you need sideeffect-less manipulation of the vector slots.
|
||||
*
|
||||
* \param vec The pvector to assign to.
|
||||
* \param index The index to assign the pointer to.
|
||||
* \param ptr The pointer to assign.
|
||||
*
|
||||
* \return The pointer stored at \p index before. Or NULL in case of failure.
|
||||
* \return The pointer stored at \p index before. NULL if index >= vec->len or in case of failure.
|
||||
*/
|
||||
RZ_API void *rz_pvector_assign_at(RZ_BORROW RZ_NONNULL RzPVector *vec, size_t index, RZ_OWN RZ_NONNULL void *ptr) {
|
||||
rz_return_val_if_fail(vec && ptr, NULL);
|
||||
void **p = rz_vector_index_ptr(&vec->v, index);
|
||||
if (!p) {
|
||||
if (vec->v.free_user) {
|
||||
RZ_API void *rz_pvector_assign_at(RZ_BORROW RZ_NONNULL RzPVector *vec, size_t index, RZ_OWN RZ_NULLABLE void *ptr) {
|
||||
rz_return_val_if_fail(vec, NULL);
|
||||
if (index >= rz_pvector_capacity(vec)) {
|
||||
if (vec->v.free_user && ptr) {
|
||||
RzPVectorFree free_fn = (RzPVectorFree)vec->v.free_user;
|
||||
free_fn(ptr);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
void *prev = *p;
|
||||
rz_vector_assign_at(&vec->v, index, ptr);
|
||||
bool increased_len = index >= rz_pvector_len(vec);
|
||||
void **p = rz_vector_index_ptr(&vec->v, index);
|
||||
void *prev = !p || increased_len ? NULL : *p;
|
||||
rz_vector_assign_at(&vec->v, index, &ptr);
|
||||
return prev;
|
||||
}
|
||||
|
||||
|
||||
+45
-15
@@ -817,18 +817,18 @@ static bool test_vector_reserve(void) {
|
||||
rz_vector_init(&v, 4, NULL, NULL);
|
||||
|
||||
rz_vector_reserve(&v, 42);
|
||||
mu_assert_eq(v.capacity, 42UL, "rz_vector_reserve (empty) => capacity");
|
||||
mu_assert_eq(rz_vector_capacity(&v), 42UL, "rz_vector_reserve (empty) => capacity");
|
||||
mu_assert("rz_vector_reserve (empty) => a", v.a);
|
||||
size_t i;
|
||||
for (i = 0; i < v.capacity; i++) {
|
||||
for (i = 0; i < rz_vector_capacity(&v); i++) {
|
||||
*((ut32 *)rz_vector_index_ptr(&v, i)) = 1337;
|
||||
}
|
||||
v.len = 20;
|
||||
|
||||
rz_vector_reserve(&v, 100);
|
||||
mu_assert_eq(v.capacity, 100UL, "rz_vector_reserve => capacity");
|
||||
mu_assert_eq(rz_vector_capacity(&v), 100UL, "rz_vector_reserve => capacity");
|
||||
mu_assert("rz_vector_reserve => a", v.a);
|
||||
for (i = 0; i < v.capacity; i++) {
|
||||
for (i = 0; i < rz_vector_capacity(&v); i++) {
|
||||
*((ut32 *)rz_vector_index_ptr(&v, i)) = 1337;
|
||||
}
|
||||
|
||||
@@ -843,14 +843,14 @@ static bool test_vector_shrink(void) {
|
||||
void *a = rz_vector_shrink(&v);
|
||||
mu_assert_ptreq(a, v.a, "rz_vector_shrink ret");
|
||||
mu_assert_eq(v.len, 5UL, "rz_vector_shrink => len");
|
||||
mu_assert_eq(v.capacity, 5UL, "rz_vector_shrink => capacity");
|
||||
mu_assert_eq(rz_vector_capacity(&v), 5UL, "rz_vector_shrink => capacity");
|
||||
rz_vector_fini(&v);
|
||||
|
||||
init_test_vector(&v, 5, 0, NULL, NULL);
|
||||
a = rz_vector_shrink(&v);
|
||||
mu_assert_ptreq(a, v.a, "rz_vector_shrink (already minimal) ret");
|
||||
mu_assert_eq(v.len, 5UL, "rz_vector_shrink (already minimal) => len");
|
||||
mu_assert_eq(v.capacity, 5UL, "rz_vector_shrink (already minimal) => capacity");
|
||||
mu_assert_eq(rz_vector_capacity(&v), 5UL, "rz_vector_shrink (already minimal) => capacity");
|
||||
rz_vector_fini(&v);
|
||||
|
||||
init_test_vector(&v, 0, 8, NULL, NULL);
|
||||
@@ -863,7 +863,7 @@ static bool test_vector_shrink(void) {
|
||||
static bool test_vector_flush(void) {
|
||||
RzVector v;
|
||||
init_test_vector(&v, 5, 5, NULL, NULL);
|
||||
ut32 *r = rz_vector_flush(&v);
|
||||
ut32 *r = rz_vector_take_array(&v);
|
||||
rz_vector_fini(&v);
|
||||
for (size_t i = 0; i < 5; i++) {
|
||||
mu_assert_eq(r[i], i, "flushed contents");
|
||||
@@ -975,7 +975,7 @@ static bool test_pvector_init(void) {
|
||||
mu_assert_eq(v.v.elem_size, sizeof(void *), "elem_size");
|
||||
mu_assert_eq(v.v.len, 0UL, "len");
|
||||
mu_assert_null(v.v.a, "a");
|
||||
mu_assert_eq(v.v.capacity, 0UL, "capacity");
|
||||
mu_assert_eq(rz_pvector_capacity(&v), 0UL, "capacity");
|
||||
mu_assert_eq((size_t)v.v.free_user, 1337, "free");
|
||||
mu_end;
|
||||
}
|
||||
@@ -997,11 +997,11 @@ static bool test_pvector_clear(void) {
|
||||
init_test_pvector(&v, 5, 5);
|
||||
mu_assert_eq(v.v.len, 5UL, "initial len");
|
||||
mu_assert("initial a", v.v.a);
|
||||
mu_assert_eq(v.v.capacity, 10UL, "initial capacity");
|
||||
mu_assert_eq(rz_pvector_capacity(&v), 10UL, "initial capacity");
|
||||
rz_pvector_clear(&v);
|
||||
mu_assert_eq(v.v.len, 0UL, "len");
|
||||
mu_assert_null(v.v.a, "a");
|
||||
mu_assert_eq(v.v.capacity, 0UL, "capacity");
|
||||
mu_assert_eq(rz_pvector_capacity(&v), 0UL, "capacity");
|
||||
mu_end;
|
||||
}
|
||||
|
||||
@@ -1107,7 +1107,7 @@ static bool test_pvector_assign_at(void) {
|
||||
init_test_pvector(&v, 5, 0);
|
||||
ut32 *x = malloc(sizeof(ut32));
|
||||
*x = 123467890;
|
||||
ut32 *e = rz_pvector_assign_at(&v, 3, &x);
|
||||
ut32 *e = rz_pvector_assign_at(&v, 3, x);
|
||||
mu_assert_eq(*e, 3, "assign_at ret");
|
||||
free(e);
|
||||
mu_assert_eq(v.v.len, 5UL, "assign_at => len");
|
||||
@@ -1116,6 +1116,36 @@ static bool test_pvector_assign_at(void) {
|
||||
mu_assert_eq(*((ut32 **)v.v.a)[2], 2, "assign_at => content at 2");
|
||||
mu_assert_eq(*((ut32 **)v.v.a)[3], 123467890, "assign_at => content at 3");
|
||||
mu_assert_eq(*((ut32 **)v.v.a)[4], 4, "assign_at => content at 4");
|
||||
|
||||
x = malloc(sizeof(ut32));
|
||||
e = rz_pvector_assign_at(&v, 5, x);
|
||||
mu_assert_null(e, "Was not NULL");
|
||||
|
||||
rz_pvector_reserve(&v, 10);
|
||||
mu_assert_eq(rz_pvector_capacity(&v), 10, "Reserve failed");
|
||||
// Test lengthening the vector.
|
||||
rz_pvector_assign_at(&v, 6, NULL);
|
||||
mu_assert_eq(rz_pvector_len(&v), 7, "Length was not updated.");
|
||||
|
||||
ut32 *zeroed[1] = { 0 };
|
||||
mu_assert_memeq(v.v.a + sizeof(ut32 *) * 5, (ut8 *)zeroed, sizeof(ut32 *), "Memory was not zeroed");
|
||||
// If this line fails on a machine, it might be because NULL != 0 on it.
|
||||
mu_assert_memeq(v.v.a + sizeof(ut32 *) * 6, (ut8 *)zeroed, sizeof(ut32 *), "Memory was not zeroed");
|
||||
|
||||
x = malloc(sizeof(ut32));
|
||||
*x = 9;
|
||||
e = rz_pvector_assign_at(&v, 9, x);
|
||||
mu_assert_null(e, "No element at this index before, should be NULL.");
|
||||
mu_assert_eq(rz_pvector_len(&v), 10, "Length was not updated.");
|
||||
mu_assert_eq(*((ut32 **)v.v.a)[9], 9, "Value was not set.");
|
||||
|
||||
mu_assert_memeq(v.v.a + sizeof(ut32 *) * 7, (ut8 *)zeroed, sizeof(ut32 *), "Memory was not zeroed");
|
||||
mu_assert_memeq(v.v.a + sizeof(ut32 *) * 8, (ut8 *)zeroed, sizeof(ut32 *), "Memory was not zeroed");
|
||||
|
||||
rz_pvector_purge(&v);
|
||||
mu_assert_eq(rz_pvector_len(&v), 0, "Length after purge.");
|
||||
mu_assert_eq(rz_pvector_capacity(&v), 10, "Capacity stays the same after purge.");
|
||||
|
||||
rz_pvector_clear(&v);
|
||||
mu_end;
|
||||
}
|
||||
@@ -1154,7 +1184,7 @@ static bool test_pvector_insert(void) {
|
||||
init_test_pvector2(&v, 4, 0);
|
||||
e = (void *)1337;
|
||||
e = *rz_pvector_insert(&v, 1, e);
|
||||
mu_assert("insert (resize) => capacity", v.v.capacity >= 5);
|
||||
mu_assert("insert (resize) => capacity", rz_pvector_capacity(&v) >= 5);
|
||||
mu_assert_eq(v.v.len, 5UL, "insert (resize) => len");
|
||||
mu_assert_eq((size_t)e, 1337, "insert (resize) => content at returned ptr");
|
||||
mu_assert_null(*((void **)rz_vector_index_ptr(&v.v, 0)), "insert (resize) => old content");
|
||||
@@ -1179,7 +1209,7 @@ static bool test_pvector_insert(void) {
|
||||
init_test_pvector2(&v, 4, 2);
|
||||
e = (void *)1337;
|
||||
e = *rz_pvector_insert(&v, 4, e);
|
||||
mu_assert("rz_vector_insert (resize, resize) => capacity", v.v.capacity >= 5);
|
||||
mu_assert("rz_vector_insert (resize, resize) => capacity", rz_pvector_capacity(&v) >= 5);
|
||||
mu_assert_eq(v.v.len, 5UL, "rz_vector_insert (end, resize) => len");
|
||||
mu_assert_eq((size_t)e, 1337, "rz_vector_insert (end, resize) => content at returned ptr");
|
||||
mu_assert_null(*((void **)rz_vector_index_ptr(&v.v, 0)), "rz_vector_insert (end, resize) => old content");
|
||||
@@ -1329,7 +1359,7 @@ static bool test_pvector_push(void) {
|
||||
init_test_pvector2(&v, 5, 0);
|
||||
e = (void *)1337;
|
||||
e = *rz_pvector_push(&v, e);
|
||||
mu_assert("push (resize) => capacity", v.v.capacity >= 6);
|
||||
mu_assert("push (resize) => capacity", rz_pvector_capacity(&v) >= 6);
|
||||
mu_assert_eq(v.v.len, 6UL, "push (resize) => len");
|
||||
mu_assert_eq((size_t)e, 1337, "push (empty) => content at returned ptr");
|
||||
|
||||
@@ -1382,7 +1412,7 @@ static bool test_pvector_push_front(void) {
|
||||
init_test_pvector2(&v, 5, 0);
|
||||
e = (void *)1337;
|
||||
e = *rz_pvector_push_front(&v, e);
|
||||
mu_assert("push_front (resize) => capacity", v.v.capacity >= 6);
|
||||
mu_assert("push_front (resize) => capacity", rz_pvector_capacity(&v) >= 6);
|
||||
mu_assert_eq(v.v.len, 6UL, "push_front (resize) => len");
|
||||
mu_assert_eq((size_t)e, 1337, "push_front (empty) => content at returned ptr");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user