github.com/alexandrestein/gods@v1.0.1/lists/doublylinkedlist/iterator.go (about) 1 // Copyright (c) 2015, 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 doublylinkedlist 6 7 import "github.com/alexandrestein/gods/containers" 8 9 func assertIteratorImplementation() { 10 var _ containers.ReverseIteratorWithIndex = (*Iterator)(nil) 11 } 12 13 // Iterator holding the iterator's state 14 type Iterator struct { 15 list *List 16 index int 17 element *element 18 } 19 20 // Iterator returns a stateful iterator whose values can be fetched by an index. 21 func (list *List) Iterator() Iterator { 22 return Iterator{list: list, index: -1, element: nil} 23 } 24 25 // Next moves the iterator to the next element and returns true if there was a next element in the container. 26 // If Next() returns true, then next element's index and value can be retrieved by Index() and Value(). 27 // If Next() was called for the first time, then it will point the iterator to the first element if it exists. 28 // Modifies the state of the iterator. 29 func (iterator *Iterator) Next() bool { 30 if iterator.index < iterator.list.size { 31 iterator.index++ 32 } 33 if !iterator.list.withinRange(iterator.index) { 34 iterator.element = nil 35 return false 36 } 37 if iterator.index != 0 { 38 iterator.element = iterator.element.next 39 } else { 40 iterator.element = iterator.list.first 41 } 42 return true 43 } 44 45 // Prev moves the iterator to the previous element and returns true if there was a previous element in the container. 46 // If Prev() returns true, then previous element's index and value can be retrieved by Index() and Value(). 47 // Modifies the state of the iterator. 48 func (iterator *Iterator) Prev() bool { 49 if iterator.index >= 0 { 50 iterator.index-- 51 } 52 if !iterator.list.withinRange(iterator.index) { 53 iterator.element = nil 54 return false 55 } 56 if iterator.index == iterator.list.size-1 { 57 iterator.element = iterator.list.last 58 } else { 59 iterator.element = iterator.element.prev 60 } 61 return iterator.list.withinRange(iterator.index) 62 } 63 64 // Value returns the current element's value. 65 // Does not modify the state of the iterator. 66 func (iterator *Iterator) Value() interface{} { 67 return iterator.element.value 68 } 69 70 // Index returns the current element's index. 71 // Does not modify the state of the iterator. 72 func (iterator *Iterator) Index() int { 73 return iterator.index 74 } 75 76 // Begin resets the iterator to its initial state (one-before-first) 77 // Call Next() to fetch the first element if any. 78 func (iterator *Iterator) Begin() { 79 iterator.index = -1 80 iterator.element = nil 81 } 82 83 // End moves the iterator past the last element (one-past-the-end). 84 // Call Prev() to fetch the last element if any. 85 func (iterator *Iterator) End() { 86 iterator.index = iterator.list.size 87 iterator.element = iterator.list.last 88 } 89 90 // First moves the iterator to the first element and returns true if there was a first element in the container. 91 // If First() returns true, then first element's index and value can be retrieved by Index() and Value(). 92 // Modifies the state of the iterator. 93 func (iterator *Iterator) First() bool { 94 iterator.Begin() 95 return iterator.Next() 96 } 97 98 // Last moves the iterator to the last element and returns true if there was a last element in the container. 99 // If Last() returns true, then last element's index and value can be retrieved by Index() and Value(). 100 // Modifies the state of the iterator. 101 func (iterator *Iterator) Last() bool { 102 iterator.End() 103 return iterator.Prev() 104 }