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 }