bitfield: add methods `insert` and `extract` (#9612)

pull/9670/head
れもん 2021-04-10 23:42:09 +09:00 committed by GitHub
parent 38c517c1a2
commit e66de8e824
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 83 additions and 0 deletions

View File

@ -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) {

View File

@ -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)