Add rz_set_u_take(). (#6137)

This commit is contained in:
Rot127 2026-04-04 12:04:25 +00:00 committed by GitHub
parent 7226d50637
commit f84510dc08
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 34 additions and 0 deletions

View file

@ -30,6 +30,7 @@ typedef HtUP RzSetU;
RZ_API RZ_OWN RzSetU *rz_set_u_new(void);
RZ_API void rz_set_u_free(RZ_NULLABLE RzSetU *set);
RZ_API void rz_set_u_add(RZ_NONNULL RzSetU *set, ut64 u);
RZ_API ut64 rz_set_u_take(RZ_NONNULL RzSetU *set);
RZ_API bool rz_set_u_contains(const RZ_NONNULL RzSetU *set, ut64 u);
RZ_API void rz_set_u_delete(RZ_NONNULL RzSetU *set, ut64 u);
RZ_API void rz_set_u_clear(RZ_NONNULL RzSetU *set);

View file

@ -106,6 +106,32 @@ RZ_API void rz_set_u_add(RZ_NONNULL RzSetU *set, ut64 u) {
ht_up_insert(set, u, (void *)1);
}
static bool take_first(void *user, const ut64 k, const void *v) {
ut64 *out = user;
*out = k;
return false;
}
/**
* \brief Take an element from \p set.
* The element is removed from it.
* There is no indicator what element is taken, because a set is unordered.
*
* The set must have a size of 1+ elements.
* Otherwise a warning is printed and it returns UT64_MAX.
*/
RZ_API ut64 rz_set_u_take(RZ_NONNULL RzSetU *set) {
rz_return_val_if_fail(set, UT64_MAX);
if (rz_set_u_size(set) == 0) {
rz_warn_if_reached();
return UT64_MAX;
}
ut64 out = UT64_MAX;
ht_up_foreach(set, take_first, &out);
rz_set_u_delete(set, out);
return out;
}
/**
* \brief Check if hash set \p set contains element \p u.
*/

View file

@ -897,6 +897,13 @@ bool test_set_u(void) {
rz_iterator_free(it);
mu_assert_eq(x, 5, "Foreach hasn't iterated the correct number of times.");
rz_set_u_clear(set_u);
mu_assert_eq(rz_set_u_take(set_u), UT64_MAX, "Invalid take should return UT64_MAX");
rz_set_u_add(set_u, 100000000);
mu_assert_eq(rz_set_u_size(set_u), 1, "Add failed");
mu_assert_eq(rz_set_u_take(set_u), 100000000, "Take failed");
mu_assert_eq(rz_set_u_size(set_u), 0, "Take did not remove element");
rz_set_u_free(set_u);
mu_end;
}