github.com/tunabay/go-bitarray@v1.3.1/buffer_bitwise.go (about)

     1  // Copyright (c) 2021 Hirotsuna Mizuno. All rights reserved.
     2  // Use of this source code is governed by the MIT license that can be found in
     3  // the LICENSE file.
     4  
     5  package bitarray
     6  
     7  // ToggleBitAt flips a single bit at the position specified by off in the
     8  // buffer.
     9  func (buf *Buffer) ToggleBitAt(off int) {
    10  	switch {
    11  	case off < 0:
    12  		panicf("ToggleBitAt: negative off %d.", off)
    13  	case buf.nBits <= off:
    14  		panicf("ToggleBitAt: out of range: off=%d >= len=%d.", off, buf.nBits)
    15  	}
    16  	off += buf.off
    17  	buf.b[off>>3] ^= byte(0x80) >> (off & 7)
    18  }
    19  
    20  // ToggleBitsAt inverts the nBits bits starting at off.
    21  func (buf *Buffer) ToggleBitsAt(off, nBits int) {
    22  	switch {
    23  	case off < 0:
    24  		panicf("ToggleBitsAt: negative off %d.", off)
    25  	case nBits < 0:
    26  		panicf("ToggleBitsAt: negative nBits %d.", nBits)
    27  	case buf.nBits < off+nBits:
    28  		panicf("ToggleBitsAt: out of range: off=%d + nBits=%d > len=%d.", off, nBits, buf.nBits)
    29  	case nBits == 0:
    30  		// no-op
    31  	default:
    32  		toggleBits(buf.b, buf.off+off, nBits)
    33  	}
    34  }
    35  
    36  // AndAt applies a bitwise AND operation with x at the offset off. AND is
    37  // applied only to the range from off to off+x.Len(), and other bits are
    38  // preserved.
    39  func (buf *Buffer) AndAt(off int, x BitArrayer) {
    40  	var bax *BitArray
    41  	if x != nil {
    42  		bax = x.BitArray()
    43  	}
    44  	switch {
    45  	case off < 0:
    46  		panicf("AndAt: negative off %d.", off)
    47  	case buf.nBits < off+bax.Len():
    48  		panicf("AndAt: out of range: off=%d + x.len=%d > len=%d.", off, bax.Len(), buf.nBits)
    49  	case bax.IsZero():
    50  		// no-op
    51  	case bax.b == nil:
    52  		clearBits(buf.b, buf.off+off, bax.nBits)
    53  	default:
    54  		andBits(buf.b, bax.b, buf.off+off, 0, bax.nBits)
    55  	}
    56  }
    57  
    58  // OrAt applies a bitwise OR operation with x at the offset off. OR is applied
    59  // only to the range from off to off+x.Len(), and other bits are preserved.
    60  func (buf *Buffer) OrAt(off int, x BitArrayer) {
    61  	var bax *BitArray
    62  	if x != nil {
    63  		bax = x.BitArray()
    64  	}
    65  	switch {
    66  	case off < 0:
    67  		panicf("OrAt: negative off %d.", off)
    68  	case buf.nBits < off+bax.Len():
    69  		panicf("OrAt: out of range: off=%d + x.len=%d > len=%d.", off, bax.Len(), buf.nBits)
    70  	case bax.IsZero(), bax.b == nil:
    71  		// no-op
    72  	default:
    73  		orBits(buf.b, bax.b, buf.off+off, 0, bax.nBits)
    74  	}
    75  }
    76  
    77  // XorAt applies a bitwise XOR operation with x at the offset off. XOR is
    78  // applied only to the range from off to off+x.Len(), and other bits are
    79  // preserved.
    80  func (buf *Buffer) XorAt(off int, x BitArrayer) {
    81  	var bax *BitArray
    82  	if x != nil {
    83  		bax = x.BitArray()
    84  	}
    85  	switch {
    86  	case off < 0:
    87  		panicf("XorAt: negative off %d.", off)
    88  	case buf.nBits < off+bax.Len():
    89  		panicf("XorAt: out of range: off=%d + x.len=%d > len=%d.", off, bax.Len(), buf.nBits)
    90  	case bax.IsZero(), bax.b == nil:
    91  		// no-op
    92  	default:
    93  		xorBits(buf.b, bax.b, buf.off+off, 0, bax.nBits)
    94  	}
    95  }
    96  
    97  // LeadingZeros returns the number of leading zero bits in the Buffer.
    98  func (buf *Buffer) LeadingZeros() int { return buf.BitArray().LeadingZeros() }
    99  
   100  // TrailingZeros returns the number of trailing zero bits in the Buffer.
   101  func (buf *Buffer) TrailingZeros() int { return buf.BitArray().TrailingZeros() }
   102  
   103  // OnesCount returns the number of one bits, population count, in the Buffer.
   104  func (buf *Buffer) OnesCount() int { return buf.BitArray().OnesCount() }