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  }