github.com/songzhibin97/go-baseutils@v0.0.2-0.20240302024150-487d8ce9c082/structure/queues/circularbuffer/iterator.go (about) 1 // Copyright (c) 2021, Emir Pasic. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package circularbuffer 6 7 import "github.com/songzhibin97/go-baseutils/structure/containers" 8 9 // Assert Iterator implementation 10 var _ containers.ReverseIteratorWithIndex[any] = (*Iterator[any])(nil) 11 12 // Iterator returns a stateful iterator whose values can be fetched by an index. 13 type Iterator[E any] struct { 14 queue *Queue[E] 15 index int 16 } 17 18 // Iterator returns a stateful iterator whose values can be fetched by an index. 19 func (queue *Queue[E]) Iterator() Iterator[E] { 20 return Iterator[E]{queue: queue, index: -1} 21 } 22 23 // Next moves the iterator to the next element and returns true if there was a next element in the container. 24 // If Next() returns true, then next element's index and value can be retrieved by Index() and Value(). 25 // If Next() was called for the first time, then it will point the iterator to the first element if it exists. 26 // Modifies the state of the iterator. 27 func (iterator *Iterator[E]) Next() bool { 28 if iterator.index < iterator.queue.size { 29 iterator.index++ 30 } 31 return iterator.queue.withinRange(iterator.index) 32 } 33 34 // Prev moves the iterator to the previous element and returns true if there was a previous element in the container. 35 // If Prev() returns true, then previous element's index and value can be retrieved by Index() and Value(). 36 // Modifies the state of the iterator. 37 func (iterator *Iterator[E]) Prev() bool { 38 if iterator.index >= 0 { 39 iterator.index-- 40 } 41 return iterator.queue.withinRange(iterator.index) 42 } 43 44 // Value returns the current element's value. 45 // Does not modify the state of the iterator. 46 func (iterator *Iterator[E]) Value() E { 47 index := (iterator.index + iterator.queue.start) % iterator.queue.maxSize 48 value := iterator.queue.values[index] 49 return value 50 } 51 52 // Index returns the current element's index. 53 // Does not modify the state of the iterator. 54 func (iterator *Iterator[E]) Index() int { 55 return iterator.index 56 } 57 58 // Begin resets the iterator to its initial state (one-before-first) 59 // Call Next() to fetch the first element if any. 60 func (iterator *Iterator[E]) Begin() { 61 iterator.index = -1 62 } 63 64 // End moves the iterator past the last element (one-past-the-end). 65 // Call Prev() to fetch the last element if any. 66 func (iterator *Iterator[E]) End() { 67 iterator.index = iterator.queue.size 68 } 69 70 // First moves the iterator to the first element and returns true if there was a first element in the container. 71 // If First() returns true, then first element's index and value can be retrieved by Index() and Value(). 72 // Modifies the state of the iterator. 73 func (iterator *Iterator[E]) First() bool { 74 iterator.Begin() 75 return iterator.Next() 76 } 77 78 // Last moves the iterator to the last element and returns true if there was a last element in the container. 79 // If Last() returns true, then last element's index and value can be retrieved by Index() and Value(). 80 // Modifies the state of the iterator. 81 func (iterator *Iterator[E]) Last() bool { 82 iterator.End() 83 return iterator.Prev() 84 } 85 86 // NextTo moves the iterator to the next element from current position that satisfies the condition given by the 87 // passed function, and returns true if there was a next element in the container. 88 // If NextTo() returns true, then next element's index and value can be retrieved by Index() and Value(). 89 // Modifies the state of the iterator. 90 func (iterator *Iterator[E]) NextTo(f func(index int, value E) bool) bool { 91 for iterator.Next() { 92 index, value := iterator.Index(), iterator.Value() 93 if f(index, value) { 94 return true 95 } 96 } 97 return false 98 } 99 100 // PrevTo moves the iterator to the previous element from current position that satisfies the condition given by the 101 // passed function, and returns true if there was a next element in the container. 102 // If PrevTo() returns true, then next element's index and value can be retrieved by Index() and Value(). 103 // Modifies the state of the iterator. 104 func (iterator *Iterator[E]) PrevTo(f func(index int, value E) bool) bool { 105 for iterator.Prev() { 106 index, value := iterator.Index(), iterator.Value() 107 if f(index, value) { 108 return true 109 } 110 } 111 return false 112 }