github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/util/bitfield/bitfield.go (about)

     1  /*
     2  Package bitfield provides a simple and efficient arbitrary size bit field implementation.
     3  It doesn't attempt to cover everything that could be done with bit fields,
     4  providing only things used by neo-go.
     5  */
     6  package bitfield
     7  
     8  // Field is a bit field represented as a slice of uint64 values.
     9  type Field []uint64
    10  
    11  // Bits and bytes count in a basic element of Field.
    12  const elemBits = 64
    13  
    14  // New creates a new bit field of the specified length. Actual field length
    15  // can be rounded to the next multiple of 64, so it's a responsibility
    16  // of the user to deal with that.
    17  func New(n int) Field {
    18  	return make(Field, 1+(n-1)/elemBits)
    19  }
    20  
    21  // Set sets one bit at the specified offset. No bounds checking is done.
    22  func (f Field) Set(i int) {
    23  	addr, offset := (i / elemBits), (i % elemBits)
    24  	f[addr] |= (1 << offset)
    25  }
    26  
    27  // IsSet returns true if the bit with the specified offset is set.
    28  func (f Field) IsSet(i int) bool {
    29  	addr, offset := (i / elemBits), (i % elemBits)
    30  	return (f[addr] & (1 << offset)) != 0
    31  }
    32  
    33  // Copy makes a copy of the current Field.
    34  func (f Field) Copy() Field {
    35  	fn := make(Field, len(f))
    36  	copy(fn, f)
    37  	return fn
    38  }
    39  
    40  // And implements logical AND between f's and m's bits saving the result into f.
    41  func (f Field) And(m Field) {
    42  	l := len(m)
    43  	for i := range f {
    44  		if i >= l {
    45  			f[i] = 0
    46  			continue
    47  		}
    48  		f[i] &= m[i]
    49  	}
    50  }
    51  
    52  // Equals compares two Fields and returns true if they're equal.
    53  func (f Field) Equals(o Field) bool {
    54  	if len(f) != len(o) {
    55  		return false
    56  	}
    57  	for i := range f {
    58  		if f[i] != o[i] {
    59  			return false
    60  		}
    61  	}
    62  	return true
    63  }
    64  
    65  // IsSubset returns true when f is a subset of o (only has bits set that are
    66  // set in o).
    67  func (f Field) IsSubset(o Field) bool {
    68  	if len(f) > len(o) {
    69  		return false
    70  	}
    71  	for i := range f {
    72  		r := f[i] & o[i]
    73  		if r != f[i] {
    74  			return false
    75  		}
    76  	}
    77  	return true
    78  }