github.com/tunabay/go-bitarray@v1.3.1/bitarray_iterate.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  import (
     8  	"errors"
     9  )
    10  
    11  // BreakIteration is used as a return value from IterateFunc to indicate the
    12  // current iteration is to be terminated without error.
    13  //nolint:revive,stylecheck,errname // this is not an error
    14  var BreakIteration = errors.New("break iteration")
    15  
    16  // IterateFunc is the type of the function called by Iterate to process each bit
    17  // of a BitArray. The i argument contains the offset from the beginning. The b
    18  // argument is the actual bit value, 0 or 1.
    19  //
    20  // If the function returns the special error BreakIteration, Iterate breaks the
    21  // current iteration without error. Otherwise, if the function returns a non-nil
    22  // error, Iterate stops the current iteration and returns that error.
    23  type IterateFunc func(i, b int) error
    24  
    25  // Iterate iterates calling the function fn for each bit in order from the
    26  // beginning of the bit array. Iterate returns an error only if the function fn
    27  // returns an error that is not BreakIteration. Otherwise, it returns nil after
    28  // calling fn for the last bit.
    29  func (ba *BitArray) Iterate(fn IterateFunc) error {
    30  	switch {
    31  	case ba.IsZero():
    32  		return nil
    33  	case ba.b == nil:
    34  		for i := 0; i < ba.nBits; i++ {
    35  			if err := fn(i, 0); err != nil {
    36  				if errors.Is(err, BreakIteration) {
    37  					return nil
    38  				}
    39  				return err
    40  			}
    41  		}
    42  		return nil
    43  	}
    44  	for i := 0; i < ba.nBits; i++ {
    45  		b := int(ba.b[i>>3] >> (7 - i&7) & 1)
    46  		if err := fn(i, b); err != nil {
    47  			if errors.Is(err, BreakIteration) {
    48  				return nil
    49  			}
    50  			return err
    51  		}
    52  	}
    53  
    54  	return nil
    55  }