Add uc_bv_find_first_zero
This commit is contained in:
@@ -68,11 +68,16 @@ void uc_bv_set_all(struct UCBitVec *v);
|
||||
/** Initialize bits from a array of ints, each array element maps to one bit.
|
||||
* The bits are initialized from the int array so zero maps to zero and non-zero maps to one.
|
||||
* e..g to set the 5 first bits, to 01110:
|
||||
* int a[] = {0,1,1,1,0};
|
||||
* int a[] = {0,1,1,1,0};
|
||||
* set_bits_from_array(v,a,5);
|
||||
* */
|
||||
void uc_bv_set_bits_from_array(struct UCBitVec *v,const char *array,size_t array_len);
|
||||
|
||||
/** Find the index of the first zero bit in the bitvec.
|
||||
* @param v The bitvec to search
|
||||
* @return The index of the first zero bit, or -1 if all bits are set
|
||||
*/
|
||||
int uc_bv_find_first_zero(const struct UCBitVec *v);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "ucore/utils.h"
|
||||
#include "ucore/bitvec.h"
|
||||
|
||||
#ifdef __GNUC__
|
||||
@@ -12,6 +13,8 @@
|
||||
#define unlikely(expr) (expr)
|
||||
#endif
|
||||
|
||||
UC_STATIC_ASSERT(CHAR_BIT % 8 == 0);
|
||||
|
||||
static inline int bit_index(int b)
|
||||
{
|
||||
return b / (sizeof(uc_bv_integer) * CHAR_BIT);
|
||||
@@ -88,3 +91,18 @@ void uc_bv_set_all(struct UCBitVec *v)
|
||||
memset(v->vec,0xff,v->vec_len * sizeof(uc_bv_integer));
|
||||
}
|
||||
|
||||
int uc_bv_find_first_zero(const struct UCBitVec *v)
|
||||
{
|
||||
const size_t bits_per_word = sizeof(uc_bv_integer) * CHAR_BIT;
|
||||
|
||||
for (size_t i = 0; i < v->vec_len; i++) {
|
||||
uc_bv_integer inverted = ~v->vec[i];
|
||||
|
||||
if (inverted != 0) {
|
||||
int bit_pos = __builtin_ffsl(inverted) - 1; // ffsl returns 1-based index
|
||||
return (int)(i * bits_per_word + bit_pos);
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -79,6 +79,31 @@ START_TEST (test_bitvec_setall_clearall)
|
||||
|
||||
uc_bv_free(v);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
START_TEST (test_bitvec_find_first_zero)
|
||||
{
|
||||
uc_bv_integer buf[8];
|
||||
struct UCBitVec v = UC_BV_STATIC_INIT(buf);
|
||||
uc_bv_set_all(&v);
|
||||
|
||||
int bit = uc_bv_find_first_zero(&v);
|
||||
ck_assert_int_eq(bit, -1);
|
||||
|
||||
uc_bv_clr_bit(&v, 0);
|
||||
bit = uc_bv_find_first_zero(&v);
|
||||
ck_assert_int_eq(bit, 0);
|
||||
|
||||
uc_bv_set_bit(&v, 0);
|
||||
uc_bv_clr_bit(&v, 63);
|
||||
bit = uc_bv_find_first_zero(&v);
|
||||
ck_assert_int_eq(bit, 63);
|
||||
|
||||
uc_bv_set_bit(&v, 63);
|
||||
uc_bv_clr_bit(&v, sizeof buf * CHAR_BIT - 1);
|
||||
bit = uc_bv_find_first_zero(&v);
|
||||
ck_assert_int_eq(bit, sizeof buf * CHAR_BIT - 1);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
@@ -91,6 +116,8 @@ Suite *bitvec_suite(void)
|
||||
tcase_add_test(tc, test_bitvec_set_bits_from_array);
|
||||
tcase_add_test(tc, test_bitvec_clearbit);
|
||||
tcase_add_test(tc, test_bitvec_setall_clearall);
|
||||
tcase_add_test(tc, test_bitvec_find_first_zero);
|
||||
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
return s;
|
||||
|
||||
Reference in New Issue
Block a user