bf: add basic documentation

pull/1286/head
Vitalie Ciubotaru 2019-07-24 01:29:04 +09:00 committed by Alexander Medvednikov
parent 732099fa08
commit bd95f5bf8f
1 changed files with 80 additions and 0 deletions

View File

@ -1,5 +1,18 @@
module bf module bf
/*
bf (BitField) is a module (shared library for V programming language) for
manipulating arrays of bits, i.e. series of zeroes and ones spread across an
array of storage units (unsigned 32-bit integers).
BitField structure
------------------
Bit arrays are stored in data structures called 'BitField'. The structure is
'opaque', i.e. its internals are not available to the end user. This module
provides API (functions and methods) for accessing and modifying bit arrays.
*/
struct BitField { struct BitField {
mut: mut:
size int size int
@ -64,6 +77,9 @@ fn cleartail(instance BitField) {
// public functions // public functions
// str2bf() converts a string of characters ('0' and '1') to a bit
// array. Any character different from '0' is treated as '1'.
pub fn str2bf(input string) BitField { pub fn str2bf(input string) BitField {
mut output := new(input.len) mut output := new(input.len)
for i := 0; i < input.len; i++ { for i := 0; i < input.len; i++ {
@ -74,6 +90,9 @@ pub fn str2bf(input string) BitField {
return output return output
} }
// string() converts the bit array to a string of characters ('0' and '1') and
// return the string
pub fn (input BitField) string() string { pub fn (input BitField) string() string {
mut output := '' mut output := ''
for i := 0; i < input.size; i++ { for i := 0; i < input.size; i++ {
@ -87,6 +106,8 @@ pub fn (input BitField) string() string {
return output return output
} }
//new() creates an empty bit array of capable of storing 'size' bits.
pub fn new(size int) BitField { pub fn new(size int) BitField {
output := BitField{ output := BitField{
size: size size: size
@ -101,21 +122,31 @@ pub fn del(instance *BitField) {
free(instance) free(instance)
} }
*/ */
// getbit() returns the value (0 or 1) of bit number 'bit_nr' (count from
// 0)
pub fn (instance BitField) getbit(bitnr int) int { pub fn (instance BitField) getbit(bitnr int) int {
if bitnr >= instance.size {return 0} if bitnr >= instance.size {return 0}
return bitget(instance, bitnr) return bitget(instance, bitnr)
} }
// setbit() set bit number 'bit_nr' to 1 (count from 0)
pub fn (instance mut BitField) setbit(bitnr int) { pub fn (instance mut BitField) setbit(bitnr int) {
if bitnr >= instance.size {return} if bitnr >= instance.size {return}
bitset(instance, bitnr) bitset(instance, bitnr)
} }
// clearbit() clears (sets to zero) bit number 'bit_nr' (count from 0)
pub fn (instance mut BitField) clearbit(bitnr int) { pub fn (instance mut BitField) clearbit(bitnr int) {
if bitnr >= instance.size {return} if bitnr >= instance.size {return}
bitclear(instance, bitnr) bitclear(instance, bitnr)
} }
// setall() sets all bits in the array to 1
pub fn (instance mut BitField) setall() { pub fn (instance mut BitField) setall() {
for i := 0; i < bitnslots(instance.size); i++ { for i := 0; i < bitnslots(instance.size); i++ {
instance.field[i] = u32(-1) instance.field[i] = u32(-1)
@ -123,17 +154,26 @@ pub fn (instance mut BitField) setall() {
cleartail(instance) cleartail(instance)
} }
// clearall() clears (sets to zero) all bits in the array
pub fn (instance mut BitField) clearall() { pub fn (instance mut BitField) clearall() {
for i := 0; i < bitnslots(instance.size); i++ { for i := 0; i < bitnslots(instance.size); i++ {
instance.field[i] = u32(0) instance.field[i] = u32(0)
} }
} }
// togglebit() change the value (from 0 to 1 or from 1 to 0) of bit
// number 'bit_nr'
pub fn (instance mut BitField) togglebit(bitnr int) { pub fn (instance mut BitField) togglebit(bitnr int) {
if bitnr >= instance.size {return} if bitnr >= instance.size {return}
bittoggle(instance, bitnr) bittoggle(instance, bitnr)
} }
// bfand() perform logical AND operation on every pair of bits from 'input1'
// and 'input2' and return the result as a new array. If inputs differ in size,
// the tail of the longer one is ignored.
pub fn bfand(input1 BitField, input2 BitField) BitField { pub fn bfand(input1 BitField, input2 BitField) BitField {
size := min(input1.size, input2.size) size := min(input1.size, input2.size)
bitnslots := bitnslots(size) bitnslots := bitnslots(size)
@ -147,6 +187,8 @@ pub fn bfand(input1 BitField, input2 BitField) BitField {
return output return output
} }
// bfnot() toggle all bits in a bit array and return the result as a new array
pub fn bfnot(input BitField) BitField { pub fn bfnot(input BitField) BitField {
size := input.size size := input.size
bitnslots := bitnslots(size) bitnslots := bitnslots(size)
@ -160,6 +202,10 @@ pub fn bfnot(input BitField) BitField {
return output return output
} }
// bfor() perform logical OR operation on every pair of bits from 'input1' and
// 'input2' and return the result as a new array. If inputs differ in size, the
// tail of the longer one is ignored.
pub fn bfor(input1 BitField, input2 BitField) BitField { pub fn bfor(input1 BitField, input2 BitField) BitField {
size := min(input1.size, input2.size) size := min(input1.size, input2.size)
bitnslots := bitnslots(size) bitnslots := bitnslots(size)
@ -173,6 +219,10 @@ pub fn bfor(input1 BitField, input2 BitField) BitField {
return output return output
} }
// bfxor(input1 BitField, input2 BitField) perform logical XOR operation on
// every pair of bits from 'input1' and 'input2' and return the result as a new
// array. If inputs differ in size, the tail of the longer one is ignored.
pub fn bfxor(input1 BitField, input2 BitField) BitField { pub fn bfxor(input1 BitField, input2 BitField) BitField {
size := min(input1.size, input2.size) size := min(input1.size, input2.size)
bitnslots := bitnslots(size) bitnslots := bitnslots(size)
@ -186,6 +236,8 @@ pub fn bfxor(input1 BitField, input2 BitField) BitField {
return output return output
} }
// join() concatenates two bit arrays and return the result as a new array.
pub fn join(input1 BitField, input2 BitField) BitField { pub fn join(input1 BitField, input2 BitField) BitField {
output_size := input1.size + input2.size output_size := input1.size + input2.size
mut output := new(output_size) mut output := new(output_size)
@ -233,6 +285,9 @@ pub fn join(input1 BitField, input2 BitField) BitField {
return output return output
} }
// print(instance BitField) send the content of a bit array to stdout as a
// string of characters ('0' and '1').
pub fn print(instance BitField) { pub fn print(instance BitField) {
mut i := 0 mut i := 0
for i < instance.size { for i < instance.size {
@ -246,10 +301,14 @@ pub fn print(instance BitField) {
} }
} }
// getsize() returns the number of bits the array can hold
pub fn (instance BitField) getsize() int { pub fn (instance BitField) getsize() int {
return instance.size return instance.size
} }
// clone() create a copy of a bit array
pub fn clone(input BitField) BitField { pub fn clone(input BitField) BitField {
bitnslots := bitnslots(input.size) bitnslots := bitnslots(input.size)
mut output := new(input.size) mut output := new(input.size)
@ -261,6 +320,9 @@ pub fn clone(input BitField) BitField {
return output return output
} }
// cmp() compare two bit arrays bit by bit and return 'true' if they are
// identical by length and contents and 'false' otherwise.
pub fn cmp(input1 BitField, input2 BitField) bool { pub fn cmp(input1 BitField, input2 BitField) bool {
if input1.size != input2.size {return false} if input1.size != input2.size {return false}
for i := 0; i < bitnslots(input1.size); i++ { for i := 0; i < bitnslots(input1.size); i++ {
@ -269,6 +331,8 @@ pub fn cmp(input1 BitField, input2 BitField) bool {
return true return true
} }
// popcount() returns the number of set bits (ones) in the array
pub fn (instance BitField) popcount() int { pub fn (instance BitField) popcount() int {
size := instance.size size := instance.size
bitnslots := bitnslots(size) bitnslots := bitnslots(size)
@ -289,11 +353,16 @@ pub fn (instance BitField) popcount() int {
return count return count
} }
// hamming () compute the Hamming distance between two bit arrays.
pub fn hamming (input1 BitField, input2 BitField) int { pub fn hamming (input1 BitField, input2 BitField) int {
input_xored := bfxor(input1, input2) input_xored := bfxor(input1, input2)
return input_xored.popcount() return input_xored.popcount()
} }
// pos() checks if the array contains a sub-array 'needle' and returns its
// position if it does, -1 if it does not, and -2 on error.
pub fn (haystack BitField) pos(needle BitField) int { pub fn (haystack BitField) pos(needle BitField) int {
heystack_size := haystack.size heystack_size := haystack.size
needle_size := needle.size needle_size := needle.size
@ -314,6 +383,9 @@ pub fn (haystack BitField) pos(needle BitField) int {
return -1 return -1
} }
// slice() return a sub-array of bits between 'start_bit_nr' (included) and
// 'end_bit_nr' (excluded)
pub fn (input BitField) slice(_start int, _end int) BitField { pub fn (input BitField) slice(_start int, _end int) BitField {
// boundary checks // boundary checks
mut start := _start mut start := _start
@ -381,6 +453,9 @@ pub fn (input BitField) slice(_start int, _end int) BitField {
return output return output
} }
// reverse() reverses the order of bits in the array (swap the first with the
// last, the second with the last but one and so on)
pub fn (instance mut BitField) reverse() BitField { pub fn (instance mut BitField) reverse() BitField {
size := instance.size size := instance.size
bitnslots := bitnslots(size) bitnslots := bitnslots(size)
@ -401,6 +476,8 @@ pub fn (instance mut BitField) reverse() BitField {
return output return output
} }
// resize() changes the size of the bit array to 'new_size'
pub fn (instance mut BitField) resize(size int) { pub fn (instance mut BitField) resize(size int) {
bitnslots := bitnslots(size) bitnslots := bitnslots(size)
old_size := instance.size old_size := instance.size
@ -416,6 +493,9 @@ pub fn (instance mut BitField) resize(size int) {
} }
} }
// rotate(offset int) circular-shift the bits by 'offset' positions (move
// 'offset' bit to 0, 'offset+1' bit to 1, and so on)
pub fn (instance BitField) rotate(offset int) BitField { pub fn (instance BitField) rotate(offset int) BitField {
/** /**
* This function "cuts" the bitfield into two and swaps them. * This function "cuts" the bitfield into two and swaps them.