github.com/m4gshm/gollections@v0.0.10/collection/mutable/slice_iter.go (about) 1 package mutable 2 3 import ( 4 "github.com/m4gshm/gollections/c" 5 "github.com/m4gshm/gollections/loop" 6 "github.com/m4gshm/gollections/slice" 7 ) 8 9 // NewHead instantiates Iter starting at the first element of a slice. 10 func NewHead[TS ~[]T, T any](elements *TS, del func(int) bool) SliceIter[T] { 11 return SliceIter[T]{elements: slice.UpcastRef(elements), current: slice.IterNoStarted, del: del} 12 } 13 14 // NewTail instantiates Iter starting at the last element of a slice. 15 func NewTail[TS ~[]T, T any](elements *TS, del func(int) bool) SliceIter[T] { 16 if elements == nil { 17 return SliceIter[T]{} 18 } 19 return SliceIter[T]{elements: slice.UpcastRef(elements), current: len(*elements), del: del} 20 } 21 22 // SliceIter is the Iterator implementation for mutable containers. 23 type SliceIter[T any] struct { 24 elements *[]T 25 current, step int 26 del func(index int) bool 27 } 28 29 var ( 30 _ c.Iterator[any] = (*SliceIter[any])(nil) 31 _ c.PrevIterator[any] = (*SliceIter[any])(nil) 32 _ c.DelIterator[any] = (*SliceIter[any])(nil) 33 ) 34 35 var _ c.IterFor[int, *SliceIter[int]] = (*SliceIter[int])(nil) 36 37 // For takes elements retrieved by the iterator. Can be interrupt by returning ErrBreak 38 func (i *SliceIter[T]) For(walker func(element T) error) error { 39 return loop.For(i.Next, walker) 40 } 41 42 // ForEach FlatIter all elements retrieved by the iterator 43 func (i *SliceIter[T]) ForEach(walker func(element T)) { 44 loop.ForEach(i.Next, walker) 45 } 46 47 // HasNext checks the next element existing 48 func (i *SliceIter[T]) HasNext() bool { 49 if i == nil || i.elements == nil { 50 return false 51 } 52 return slice.HasNext(*i.elements, i.current) 53 } 54 55 // HasPrev checks the previous element existing 56 func (i *SliceIter[T]) HasPrev() bool { 57 if i == nil || i.elements == nil { 58 return false 59 } 60 return slice.HasPrev(*i.elements, i.current) 61 } 62 63 // GetNext returns the next element 64 func (i *SliceIter[T]) GetNext() (t T) { 65 if i != nil { 66 t, _ = i.Next() 67 } 68 return 69 } 70 71 // GetPrev returns the previous element 72 func (i *SliceIter[T]) GetPrev() (t T) { 73 if i != nil { 74 t, _ = i.Prev() 75 } 76 return 77 } 78 79 // Next returns the next element. 80 // The ok result indicates whether the element was returned by the iterator. 81 // If ok == false, then the iteration must be completed. 82 func (i *SliceIter[T]) Next() (T, bool) { 83 if i.HasNext() { 84 i.current++ 85 i.step = 1 86 return slice.Get(*i.elements, i.current), true 87 } 88 var no T 89 return no, false 90 } 91 92 // Prev returns the previous element. 93 // The ok result indicates whether the element was returned by the iterator. 94 // If ok == false, then the iteration must be completed. 95 func (i *SliceIter[T]) Prev() (T, bool) { 96 if i.HasPrev() { 97 i.current-- 98 i.step = 0 99 return slice.Get(*i.elements, i.current), true 100 } 101 var no T 102 return no, false 103 } 104 105 // Get returns the current element. 106 // The ok result indicates whether the element was returned by the iterator. 107 // If ok == false, then the iteration must be completed. 108 func (i *SliceIter[T]) Get() (t T, ok bool) { 109 if i == nil || i.elements == nil { 110 return t, ok 111 } 112 current := i.current 113 elements := *i.elements 114 if slice.IsValidIndex(len(elements), current) { 115 return elements[current], true 116 } 117 return t, ok 118 } 119 120 // Cap returns the iterator capacity 121 func (i *SliceIter[T]) Cap() int { 122 if i == nil || i.elements == nil { 123 return 0 124 } 125 return len(*i.elements) 126 } 127 128 // Delete deletes the current element 129 func (i *SliceIter[T]) Delete() { 130 if i == nil { 131 return 132 } else if deleted := i.del(i.current); deleted { 133 i.current -= i.step 134 } 135 } 136 137 // DeleteNext deletes the next element if it exists 138 func (i *SliceIter[T]) DeleteNext() bool { 139 if i == nil { 140 return false 141 } 142 return i.del(i.current + 1) 143 } 144 145 // DeletePrev deletes the previos element if it exists 146 func (i *SliceIter[T]) DeletePrev() bool { 147 if i == nil { 148 return false 149 } else if deleted := i.del(i.current - 1); deleted { 150 i.current-- 151 return true 152 } 153 return false 154 } 155 156 // Start is used with for loop construct like 'for i, val, ok := i.Start(); ok; val, ok = i.Next() { }' 157 func (i *SliceIter[T]) Start() (*SliceIter[T], T, bool) { 158 n, ok := i.Next() 159 return i, n, ok 160 }