1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00
v/vlib/bf/bf.v
2019-07-10 22:05:50 +02:00

181 lines
3.5 KiB
Go

module bf
struct BitField {
mut:
size int
//field *u32
field []u32
}
// helper functions
const (
SLOT_SIZE = 32
)
fn bitmask(bitnr int) u32 {
return u32(1 << (bitnr % SLOT_SIZE))
}
fn bitslot(size int) int {
return size / SLOT_SIZE
}
fn bitget(instance BitField, bitnr int) int {
return (instance.field[bitslot(bitnr)] >> u32(bitnr % SLOT_SIZE)) & 1
}
fn bitset(instance BitField, bitnr int) {
instance.field[bitslot(bitnr)] = instance.field[bitslot(bitnr)] | bitmask(bitnr)
}
fn bitclear(instance BitField, bitnr int) {
instance.field[bitslot(bitnr)] = instance.field[bitslot(bitnr)] & ~bitmask(bitnr)
}
fn bittoggle(instance BitField, bitnr int) {
instance.field[bitslot(bitnr)] = instance.field[bitslot(bitnr)] ^ bitmask(bitnr)
}
/*
#define BITTEST(a, b) ((a)->field[BITSLOT(b)] & BITMASK(b))
*/
fn min(input1 int, input2 int) int {
if input1 < input2 {
return input1
}
else {
return input2
}
}
fn bitnslots(length int) int {
return (length - 1) / SLOT_SIZE + 1
}
fn cleartail(instance BitField) {
tail := instance.size % SLOT_SIZE
if tail != 0 {
// create a mask for the tail
mask := u32((1 << tail) - 1)
// clear the extra bits
instance.field[bitnslots(instance.size) - 1] = instance.field[bitnslots(instance.size) - 1] & mask
}
}
// public functions
pub fn new(size int) BitField {
output := BitField{
size: size
//field: *u32(calloc(bitnslots(size) * SLOT_SIZE / 8))
field: [u32(0); bitnslots(size)]
}
return output
}
/*
pub fn del(instance *BitField) {
free(instance.field)
free(instance)
}
*/
pub fn (instance BitField) getbit(bitnr int) int {
if bitnr >= instance.size {return 0}
return bitget(instance, bitnr)
}
pub fn (instance mut BitField) setbit(bitnr int) {
if bitnr >= instance.size {return}
bitset(instance, bitnr)
}
pub fn (instance mut BitField) clearbit(bitnr int) {
if bitnr >= instance.size {return}
bitclear(instance, bitnr)
}
pub fn (instance mut BitField) togglebit(bitnr int) {
if bitnr >= instance.size {return}
bittoggle(instance, bitnr)
}
pub fn bfand(input1 BitField, input2 BitField) BitField {
size := min(input1.size, input2.size)
bitnslots := bitnslots(size)
mut output := new(size)
mut i := 0
for i < bitnslots {
output.field[i] = input1.field[i] & input2.field[i]
i++
}
cleartail(output)
return output
}
pub fn bfnot(input BitField) BitField {
size := input.size
bitnslots := bitnslots(size)
mut output := new(size)
mut i := 0
for i < bitnslots {
output.field[i] = ~input.field[i]
i++
}
cleartail(output)
return output
}
pub fn bfor(input1 BitField, input2 BitField) BitField {
size := min(input1.size, input2.size)
bitnslots := bitnslots(size)
mut output := new(size)
mut i := 0
for i < bitnslots {
output.field[i] = input1.field[i] | input2.field[i]
i++
}
cleartail(output)
return output
}
pub fn bfxor(input1 BitField, input2 BitField) BitField {
size := min(input1.size, input2.size)
bitnslots := bitnslots(size)
mut output := new(size)
mut i := 0
for i < bitnslots {
output.field[i] = input1.field[i] ^ input2.field[i]
i++
}
cleartail(output)
return output
}
pub fn print(instance BitField) {
mut i := 0
for i < instance.size {
if instance.getbit(i) == 1 {
print('1')
}
else {
print('0')
}
i++
}
}
pub fn (instance BitField) getsize() int {
return instance.size
}
pub fn clone(input BitField) BitField {
bitnslots := bitnslots(input.size)
mut output := new(input.size)
mut i := 0
for i < bitnslots {
output.field[i] = input.field[i]
i++
}
return output
}