mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-12-23 03:41:34 +00:00
9cce148d83
Testing for equality has never been easier. Signed-off-by: Roman Khimov <roman@nspcc.ru>
70 lines
1.7 KiB
Go
70 lines
1.7 KiB
Go
/*
|
|
Package bitfield provides a simple and efficient arbitrary size bit field implementation.
|
|
It doesn't attempt to cover everything that could be done with bit fields,
|
|
providing only things used by neo-go.
|
|
*/
|
|
package bitfield
|
|
|
|
import "slices"
|
|
|
|
// Field is a bit field represented as a slice of uint64 values.
|
|
type Field []uint64
|
|
|
|
// Bits and bytes count in a basic element of Field.
|
|
const elemBits = 64
|
|
|
|
// New creates a new bit field of the specified length. Actual field length
|
|
// can be rounded to the next multiple of 64, so it's a responsibility
|
|
// of the user to deal with that.
|
|
func New(n int) Field {
|
|
return make(Field, 1+(n-1)/elemBits)
|
|
}
|
|
|
|
// Set sets one bit at the specified offset. No bounds checking is done.
|
|
func (f Field) Set(i int) {
|
|
addr, offset := (i / elemBits), (i % elemBits)
|
|
f[addr] |= (1 << offset)
|
|
}
|
|
|
|
// IsSet returns true if the bit with the specified offset is set.
|
|
func (f Field) IsSet(i int) bool {
|
|
addr, offset := (i / elemBits), (i % elemBits)
|
|
return (f[addr] & (1 << offset)) != 0
|
|
}
|
|
|
|
// Copy makes a copy of the current Field.
|
|
func (f Field) Copy() Field {
|
|
return slices.Clone(f)
|
|
}
|
|
|
|
// And implements logical AND between f's and m's bits saving the result into f.
|
|
func (f Field) And(m Field) {
|
|
l := len(m)
|
|
for i := range f {
|
|
if i >= l {
|
|
f[i] = 0
|
|
continue
|
|
}
|
|
f[i] &= m[i]
|
|
}
|
|
}
|
|
|
|
// Equals compares two Fields and returns true if they're equal.
|
|
func (f Field) Equals(o Field) bool {
|
|
return slices.Equal(f, o)
|
|
}
|
|
|
|
// IsSubset returns true when f is a subset of o (only has bits set that are
|
|
// set in o).
|
|
func (f Field) IsSubset(o Field) bool {
|
|
if len(f) > len(o) {
|
|
return false
|
|
}
|
|
for i := range f {
|
|
r := f[i] & o[i]
|
|
if r != f[i] {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|