127 lines
2.5 KiB
C
127 lines
2.5 KiB
C
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <assert.h>
|
|
#include <limits.h>
|
|
#include "ucore/bitvec.h"
|
|
|
|
#ifdef __GNUC__
|
|
#define likely(expr) __builtin_expect((expr), 1)
|
|
#define unlikely(expr) __builtin_expect((expr), 0)
|
|
#else
|
|
#define likely(expr) (expr)
|
|
#define unlikely(expr) (expr)
|
|
#endif
|
|
|
|
static inline int bit_index(int b)
|
|
{
|
|
return b / (sizeof(unsigned long) * CHAR_BIT);
|
|
}
|
|
|
|
static inline int bit_offset(int b)
|
|
{
|
|
return b % (sizeof(unsigned long) * CHAR_BIT);
|
|
}
|
|
|
|
struct UCBitVec *uc_bv_new(size_t nbits)
|
|
{
|
|
struct UCBitVec *v = malloc(sizeof *v);
|
|
|
|
if (v == NULL)
|
|
return NULL;
|
|
v->vec_len = UC_BV_LEN(nbits);
|
|
v->vec = malloc(v->vec_len * sizeof(unsigned long));
|
|
if (v->vec == NULL) {
|
|
free(v);
|
|
return NULL;
|
|
}
|
|
|
|
uc_bv_clr_all(v);
|
|
|
|
return v;
|
|
}
|
|
|
|
void uc_bv_free(struct UCBitVec *v)
|
|
{
|
|
if (v) {
|
|
free(v->vec);
|
|
free(v);
|
|
}
|
|
}
|
|
|
|
|
|
void uc_bv_clr_bit(struct UCBitVec *v,int b)
|
|
{
|
|
v->vec[bit_index(b)] &= ~(1UL << (bit_offset(b)));
|
|
}
|
|
|
|
int uc_bv_get_bit(const struct UCBitVec *v,int b)
|
|
{
|
|
return !!(v->vec[bit_index(b)] & (1UL << bit_offset(b)));
|
|
}
|
|
|
|
void uc_bv_set_bit(struct UCBitVec *v,int b)
|
|
{
|
|
v->vec[bit_index(b)] |= 1UL << (bit_offset(b));
|
|
}
|
|
|
|
void uc_bv_set_bit_s(struct UCBitVec *v,int b)
|
|
{
|
|
size_t idx = (size_t)bit_index(b);
|
|
assert(b >= 0);
|
|
assert(v->vec_len > (size_t)idx);
|
|
|
|
if (likely(idx < v->vec_len))
|
|
v->vec[idx] |= 1UL << (bit_offset(b));
|
|
}
|
|
|
|
void uc_bv_clear_bit_s(struct UCBitVec *v,int b)
|
|
{
|
|
size_t idx = (size_t)bit_index(b);
|
|
|
|
assert(b >= 0);
|
|
assert(v->vec_len > (size_t)idx);
|
|
|
|
if (likely(idx < v->vec_len))
|
|
v->vec[idx] &= ~(1UL << (bit_offset(b)));
|
|
}
|
|
|
|
int uc_bv_get_bit_s(const struct UCBitVec *v,int b)
|
|
{
|
|
size_t idx = (size_t)bit_index(b);
|
|
|
|
assert(b >= 0);
|
|
assert(v->vec_len > (size_t)idx);
|
|
|
|
if (likely(idx < v->vec_len))
|
|
return !!(v->vec[idx] & (1UL << bit_offset(b)));
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
void uc_bv_set_bits_from_array(struct UCBitVec *v,char *array,size_t array_len)
|
|
{
|
|
size_t i;
|
|
|
|
for (i = 0; i < array_len; i++) {
|
|
size_t idx = (size_t)bit_index(array_len);
|
|
if (unlikely(idx >= v->vec_len))
|
|
break;
|
|
|
|
if (array[i])
|
|
uc_bv_set_bit(v,i);
|
|
else
|
|
uc_bv_clr_bit(v,i);
|
|
}
|
|
}
|
|
|
|
void uc_bv_clr_all(struct UCBitVec *v)
|
|
{
|
|
memset(v->vec,0, v->vec_len * sizeof(unsigned long));
|
|
}
|
|
|
|
void uc_bv_set_all(struct UCBitVec *v)
|
|
{
|
|
memset(v->vec,0xff,v->vec_len * sizeof(unsigned long));
|
|
}
|
|
|