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  }