bitfield: add methods `insert` and `extract` (#9612)
parent
38c517c1a2
commit
e66de8e824
|
@ -137,6 +137,75 @@ pub fn (mut instance BitField) clear_bit(bitnr int) {
|
|||
instance.field[bitslot(bitnr)] &= ~bitmask(bitnr)
|
||||
}
|
||||
|
||||
// extract returns the value converted from a slice of bit numbers
|
||||
// from 'start' by the length of 'len'.
|
||||
// 0101 (1, 2) => 0b10
|
||||
pub fn (instance BitField) extract(start int, len int) u64 {
|
||||
// panic?
|
||||
if start < 0 {
|
||||
return 0
|
||||
}
|
||||
mut output := u64(0)
|
||||
for i in 0 .. len {
|
||||
output |= u64(instance.get_bit(start + len - i - 1)) << i
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
// insert sets bit numbers from 'start' to 'len' length with
|
||||
// the value converted from the number 'value'.
|
||||
// 0000 (1, 2, 0b10) => 0100
|
||||
pub fn (mut instance BitField) insert<T>(start int, len int, _value T) {
|
||||
// panic?
|
||||
if start < 0 {
|
||||
return
|
||||
}
|
||||
mut value := _value
|
||||
for i in 0 .. len {
|
||||
pos := start + len - i - 1
|
||||
if value & 1 == 1 {
|
||||
instance.set_bit(pos)
|
||||
} else {
|
||||
instance.clear_bit(pos)
|
||||
}
|
||||
value >>= 1
|
||||
}
|
||||
}
|
||||
|
||||
// extract returns the value converted from a slice of bit numbers
|
||||
// from 'start' by the length of 'len'.
|
||||
// 0101 (1, 2) => 0b01
|
||||
pub fn (instance BitField) extract_lowest_bits_first(start int, len int) u64 {
|
||||
// panic?
|
||||
if start < 0 {
|
||||
return 0
|
||||
}
|
||||
mut output := u64(0)
|
||||
for i in 0 .. len {
|
||||
output |= u64(instance.get_bit(start + i)) << i
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
// insert sets bit numbers from 'start' to 'len' length with
|
||||
// the value converted from the number 'value'.
|
||||
// 0000 (1, 2, 0b10) => 0010
|
||||
pub fn (mut instance BitField) insert_lowest_bits_first<T>(start int, len int, _value T) {
|
||||
// panic?
|
||||
if start < 0 {
|
||||
return
|
||||
}
|
||||
mut value := _value
|
||||
for pos in start .. start + len {
|
||||
if value & 1 == 1 {
|
||||
instance.set_bit(pos)
|
||||
} else {
|
||||
instance.clear_bit(pos)
|
||||
}
|
||||
value >>= 1
|
||||
}
|
||||
}
|
||||
|
||||
// set_all sets all bits in the array to 1.
|
||||
pub fn (mut instance BitField) set_all() {
|
||||
for i in 0 .. zbitnslots(instance.size) {
|
||||
|
|
|
@ -16,6 +16,20 @@ fn test_bf_set_clear_toggle_get() {
|
|||
assert instance.get_bit(47) == 1
|
||||
}
|
||||
|
||||
fn test_bf_insert_extract() {
|
||||
mut instance := bitfield.new(11)
|
||||
instance.set_all()
|
||||
instance.insert(2, 9, 3)
|
||||
assert instance.extract(2, 1) == 0
|
||||
assert instance.extract(2, 8) == 1
|
||||
assert instance.extract(10, 1) == 1
|
||||
instance.set_all()
|
||||
instance.insert_lowest_bits_first(2, 9, 3)
|
||||
assert instance.extract_lowest_bits_first(2, 1) == 1
|
||||
assert instance.extract_lowest_bits_first(2, 8) == 3
|
||||
assert instance.extract_lowest_bits_first(10, 1) == 0
|
||||
}
|
||||
|
||||
fn test_bf_and_not_or_xor() {
|
||||
len := 80
|
||||
mut input1 := bitfield.new(len)
|
||||
|
|
Loading…
Reference in New Issue