github.com/haraldrudell/parl@v0.4.176/iters/slice1.go (about) 1 /* 2 © 2023–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/) 3 ISC License 4 */ 5 6 package iters 7 8 import ( 9 "github.com/haraldrudell/parl/internal/cyclebreaker" 10 ) 11 12 // Slice traverses a slice container. thread-safe 13 type Slice1[T any] struct { 14 slice []T // the slice providing values 15 // index is next slice-index to return 16 // - if index == len(slice) there are no more values 17 index int 18 } 19 20 // NewSliceIterator returns an iterator iterating over slice T values 21 // - thread-safe 22 // - uses non-pointer atomics 23 func NewSlice1Iterator[T any](slice []T) (iterator Iterator[T]) { return &Slice[T]{slice: slice} } 24 25 // Init implements the right-hand side of a short variable declaration in 26 // the init statement for a Go “for” clause 27 // 28 // Usage: 29 // 30 // for i, iterator := NewSlicePointerIterator(someSlice).Init(); iterator.Cond(&i); { 31 // // i is pointer to slice element 32 func (i *Slice1[T]) Init() (iterationVariable T, iterator Iterator[T]) { 33 iterator = i 34 return 35 } 36 37 // Cond implements the condition statement of a Go “for” clause 38 // - the iterationVariable is updated by being provided as a pointer. 39 // iterationVariable cannot be nil 40 // - errp is an optional error pointer receiving any errors during iterator execution 41 // - condition is true if iterationVariable was assigned a value and the iteration should continue 42 // 43 // Usage: 44 // 45 // for i, iterator := NewSlicePointerIterator(someSlice).Init(); iterator.Cond(&i); { 46 // // i is pointer to slice element 47 func (i *Slice1[T]) Cond(iterationVariablep *T, errp ...*error) (condition bool) { 48 if iterationVariablep == nil { 49 cyclebreaker.NilError("iterationVariablep") 50 } 51 52 // check for next value 53 var value T 54 if value, condition = i.Next(); condition { 55 *iterationVariablep = value 56 } 57 58 return // condition and iterationVariablep updated, errp unchanged 59 } 60 61 // Next advances to next item and returns it 62 // - if hasValue true, value contains the next value 63 // - otherwise, no more items exist and value is the data type zero-value 64 func (i *Slice1[T]) Next() (value T, hasValue bool) { 65 var index = i.index 66 if hasValue = index < len(i.slice); !hasValue { 67 return // no more values 68 } 69 value = i.slice[index] 70 i.index++ 71 72 return 73 } 74 75 // Cancel release resources for this iterator. Thread-safe 76 // - not every iterator requires a Cancel invocation 77 func (i *Slice1[T]) Cancel(errp ...*error) (err error) { 78 i.slice = nil 79 return 80 }