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.
|
/** 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.
|
* 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:
|
* 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);
|
* set_bits_from_array(v,a,5);
|
||||||
* */
|
* */
|
||||||
void uc_bv_set_bits_from_array(struct UCBitVec *v,const char *array,size_t array_len);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include "ucore/utils.h"
|
||||||
#include "ucore/bitvec.h"
|
#include "ucore/bitvec.h"
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
@@ -12,6 +13,8 @@
|
|||||||
#define unlikely(expr) (expr)
|
#define unlikely(expr) (expr)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
UC_STATIC_ASSERT(CHAR_BIT % 8 == 0);
|
||||||
|
|
||||||
static inline int bit_index(int b)
|
static inline int bit_index(int b)
|
||||||
{
|
{
|
||||||
return b / (sizeof(uc_bv_integer) * CHAR_BIT);
|
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));
|
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);
|
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
|
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_set_bits_from_array);
|
||||||
tcase_add_test(tc, test_bitvec_clearbit);
|
tcase_add_test(tc, test_bitvec_clearbit);
|
||||||
tcase_add_test(tc, test_bitvec_setall_clearall);
|
tcase_add_test(tc, test_bitvec_setall_clearall);
|
||||||
|
tcase_add_test(tc, test_bitvec_find_first_zero);
|
||||||
|
|
||||||
suite_add_tcase(s, tc);
|
suite_add_tcase(s, tc);
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
|
|||||||
Reference in New Issue
Block a user