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 }