#ifndef INCLUDE_bitvec_h__
#define INCLUDE_bitvec_h__
#include "common.h"
typedef
struct
{
size_t
length;
union
{
uint64_t *words;
uint64_t bits;
} u;
} git_bitvec;
GIT_INLINE(
int
) git_bitvec_init(git_bitvec *bv,
size_t
capacity)
{
memset
(bv, 0x0,
sizeof
(*bv));
if
(capacity >= 64) {
bv->length = (capacity / 64) + 1;
bv->u.words = git__calloc(bv->length,
sizeof
(uint64_t));
if
(!bv->u.words)
return
-1;
}
return
0;
}
#define GIT_BITVEC_MASK(BIT) ((uint64_t)1 << (BIT % 64))
#define GIT_BITVEC_WORD(BV, BIT) (BV->length ? &BV->u.words[BIT / 64] : &BV->u.bits)
GIT_INLINE(
void
) git_bitvec_set(git_bitvec *bv,
size_t
bit,
bool
on)
{
uint64_t *word = GIT_BITVEC_WORD(bv, bit);
uint64_t mask = GIT_BITVEC_MASK(bit);
if
(on)
*word |= mask;
else
*word &= ~mask;
}
GIT_INLINE(
bool
) git_bitvec_get(git_bitvec *bv,
size_t
bit)
{
uint64_t *word = GIT_BITVEC_WORD(bv, bit);
return
(*word & GIT_BITVEC_MASK(bit)) != 0;
}
GIT_INLINE(
void
) git_bitvec_clear(git_bitvec *bv)
{
if
(!bv->length)
bv->u.bits = 0;
else
memset
(bv->u.words, 0x0, bv->length *
sizeof
(uint64_t));
}
GIT_INLINE(
void
) git_bitvec_free(git_bitvec *bv)
{
if
(bv->length)
git__free(bv->u.words);
}
#endif