gonum.org/v1/gonum@v0.15.1-0.20240517103525-f853624cb1bb/graph/iterator/lines_map_safe.go (about) 1 // Copyright ©2021 The Gonum Authors. 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 //go:build safe 6 // +build safe 7 8 package iterator 9 10 import ( 11 "reflect" 12 13 "gonum.org/v1/gonum/graph" 14 ) 15 16 // Lines implements the graph.Lines interfaces. 17 // The iteration order of Lines is randomized. 18 type Lines struct { 19 lines reflect.Value 20 iter reflect.MapIter 21 pos int 22 curr graph.Line 23 } 24 25 // NewLines returns a Lines initialized with the provided lines, a 26 // map of line IDs to graph.Lines. No check is made that the keys 27 // match the graph.Line IDs, and the map keys are not used. 28 // 29 // Behavior of the Lines is unspecified if lines is mutated after 30 // the call to NewLines. 31 func NewLines(lines map[int64]graph.Line) *Lines { 32 rv := reflect.ValueOf(lines) 33 l := &Lines{lines: rv} 34 l.iter.Reset(rv) 35 return l 36 } 37 38 // Len returns the remaining number of lines to be iterated over. 39 func (l *Lines) Len() int { 40 return l.lines.Len() - l.pos 41 } 42 43 // Next returns whether the next call of Line will return a valid line. 44 func (l *Lines) Next() bool { 45 if l.pos >= l.lines.Len() { 46 return false 47 } 48 ok := l.iter.Next() 49 if ok { 50 l.pos++ 51 l.curr = l.iter.Value().Interface().(graph.Line) 52 } 53 return ok 54 } 55 56 // Line returns the current line of the iterator. Next must have been 57 // called prior to a call to Line. 58 func (l *Lines) Line() graph.Line { 59 return l.curr 60 } 61 62 // Reset returns the iterator to its initial state. 63 func (l *Lines) Reset() { 64 l.curr = nil 65 l.pos = 0 66 l.iter.Reset(l.lines) 67 } 68 69 // LineSlice returns all the remaining lines in the iterator and advances 70 // the iterator. The order of lines within the returned slice is not 71 // specified. 72 func (l *Lines) LineSlice() []graph.Line { 73 if l.Len() == 0 { 74 return nil 75 } 76 lines := make([]graph.Line, 0, l.Len()) 77 for l.iter.Next() { 78 lines = append(lines, l.iter.Value().Interface().(graph.Line)) 79 } 80 l.pos = l.lines.Len() 81 return lines 82 } 83 84 // WeightedLines implements the graph.WeightedLines interfaces. 85 // The iteration order of WeightedLines is randomized. 86 type WeightedLines struct { 87 lines reflect.Value 88 iter reflect.MapIter 89 pos int 90 curr graph.WeightedLine 91 } 92 93 // NewWeightedLines returns a WeightedLines initialized with the provided lines, a 94 // map of line IDs to graph.WeightedLines. No check is made that the keys 95 // match the graph.WeightedLine IDs, and the map keys are not used. 96 // 97 // Behavior of the WeightedLines is unspecified if lines is mutated after 98 // the call to NewWeightedLines. 99 func NewWeightedLines(lines map[int64]graph.WeightedLine) *WeightedLines { 100 rv := reflect.ValueOf(lines) 101 l := &WeightedLines{lines: rv} 102 l.iter.Reset(rv) 103 return l 104 } 105 106 // Len returns the remaining number of lines to be iterated over. 107 func (l *WeightedLines) Len() int { 108 return l.lines.Len() - l.pos 109 } 110 111 // Next returns whether the next call of WeightedLine will return a valid line. 112 func (l *WeightedLines) Next() bool { 113 if l.pos >= l.lines.Len() { 114 return false 115 } 116 ok := l.iter.Next() 117 if ok { 118 l.pos++ 119 l.curr = l.iter.Value().Interface().(graph.WeightedLine) 120 } 121 return ok 122 } 123 124 // WeightedLine returns the current line of the iterator. Next must have been 125 // called prior to a call to WeightedLine. 126 func (l *WeightedLines) WeightedLine() graph.WeightedLine { 127 return l.curr 128 } 129 130 // Reset returns the iterator to its initial state. 131 func (l *WeightedLines) Reset() { 132 l.curr = nil 133 l.pos = 0 134 l.iter.Reset(l.lines) 135 } 136 137 // WeightedLineSlice returns all the remaining lines in the iterator and advances 138 // the iterator. The order of lines within the returned slice is not 139 // specified. 140 func (l *WeightedLines) WeightedLineSlice() []graph.WeightedLine { 141 if l.Len() == 0 { 142 return nil 143 } 144 lines := make([]graph.WeightedLine, 0, l.Len()) 145 for l.iter.Next() { 146 lines = append(lines, l.iter.Value().Interface().(graph.WeightedLine)) 147 } 148 l.pos = l.lines.Len() 149 return lines 150 }