github.com/tunabay/go-bitarray@v1.3.1/bitarray_concat.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 // Join concatenates the elements of its first parameter to create a single 8 // bit array. The separator sep is placed between elements in the result. 9 func Join(elems []*BitArray, sep BitArrayer) *BitArray { 10 var basep *BitArray 11 if sep != nil { 12 basep = sep.BitArray() 13 } 14 switch len(elems) { 15 case 0: 16 return zeroBitArray 17 case 1: 18 return elems[0] 19 } 20 bb := NewBuilder() 21 for i, elem := range elems { 22 if i != 0 && basep != nil { 23 _, _ = bb.WriteBitArray(basep) 24 } 25 _, _ = bb.WriteBitArray(elem) 26 } 27 28 return bb.BitArray() 29 } 30 31 // JoinBitArrayer is identical to Join except that it accepts elems in 32 // []BitArrayer type instead of []*BitArray type. 33 func JoinBitArrayer(elems []BitArrayer, sep BitArrayer) *BitArray { 34 var basep *BitArray 35 if sep != nil { 36 basep = sep.BitArray() 37 } 38 switch len(elems) { 39 case 0: 40 return zeroBitArray 41 case 1: 42 if elems[0] == nil { 43 return zeroBitArray 44 } 45 return elems[0].BitArray() 46 } 47 bb := NewBuilder() 48 for i, elem := range elems { 49 if i != 0 && basep != nil { 50 _, _ = bb.WriteBitArray(basep) 51 } 52 if elem != nil { 53 _, _ = bb.WriteBitArray(elem) 54 } 55 } 56 57 return bb.BitArray() 58 } 59 60 // Append returns the new BitArray resulting from appending the passed elements 61 // to the current bit array. 62 func (ba *BitArray) Append(bas ...BitArrayer) *BitArray { 63 switch len(bas) { 64 case 0: 65 if ba.IsZero() { 66 return zeroBitArray 67 } 68 return ba 69 case 1: 70 if bas[0] == nil { 71 return ba 72 } 73 return ba.append1(bas[0]) 74 } 75 76 bb := NewBuilder(ba) 77 for _, bai := range bas { 78 _, _ = bb.WriteBitArray(bai) 79 } 80 81 return bb.BitArray() 82 } 83 84 func (ba *BitArray) append1(x BitArrayer) *BitArray { 85 var bax *BitArray 86 if x != nil { 87 bax = x.BitArray() 88 } 89 switch { 90 case ba.IsZero(): 91 if bax.IsZero() { 92 return zeroBitArray 93 } 94 return bax 95 case bax.IsZero(): 96 return ba 97 } 98 if bax.b == nil { 99 nBits := ba.nBits + bax.nBits 100 if ba.b == nil { 101 return &BitArray{nBits: nBits} 102 } 103 nBytes := (nBits + 7) >> 3 104 if nBytes <= cap(ba.b) { 105 return &BitArray{b: ba.b[:nBytes], nBits: nBits} 106 } 107 buf := allocByteSlice(nBytes) 108 copy(buf, ba.b) 109 return &BitArray{b: buf, nBits: nBits} 110 } 111 nBits := ba.nBits + bax.nBits 112 buf := allocByteSlice((nBits + 7) >> 3) 113 copy(buf, ba.b) 114 if copyBits(buf, bax.b, ba.nBits, 0, bax.nBits) && ba.b == nil { 115 return &BitArray{nBits: nBits} 116 } 117 return &BitArray{b: buf, nBits: nBits} 118 } 119 120 // Repeat returns a bit array consisting of count copies of the bit array ba. 121 func (ba *BitArray) Repeat(count int) *BitArray { 122 switch { 123 case count < 0: 124 panicf("invalid count: %d < 0", count) 125 case ba.IsZero(), count == 0: 126 return zeroBitArray 127 case count == 1: 128 return ba 129 case ba.b == nil: 130 return &BitArray{nBits: ba.nBits * count} 131 } 132 bb := NewBuilder() 133 for i := 0; i < count; i++ { 134 _, _ = bb.WriteBitArray(ba) 135 } 136 137 return bb.BitArray() 138 }