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() }