| // Copyright ©2018 The Gonum Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| //go:build safe |
| // +build safe |
| |
| package iterator |
| |
| import ( |
| "reflect" |
| |
| "gonum.org/v1/gonum/graph" |
| ) |
| |
| // Nodes implements the graph.Nodes interfaces. |
| // The iteration order of Nodes is randomized. |
| type Nodes struct { |
| iter reflect.MapIter |
| pos, len int |
| curr graph.Node |
| value reflect.Value |
| nodes reflect.Value |
| } |
| |
| // NewNodes returns a Nodes initialized with the provided nodes, a |
| // map of node IDs to graph.Nodes. No check is made that the keys |
| // match the graph.Node IDs, and the map keys are not used. |
| // |
| // Behavior of the Nodes is unspecified if nodes is mutated after |
| // the call to NewNodes. |
| func NewNodes(nodes map[int64]graph.Node) *Nodes { |
| rv := reflect.ValueOf(nodes) |
| n := &Nodes{nodes: rv, len: len(nodes)} |
| n.iter.Reset(rv) |
| n.value = reflect.ValueOf(&n.curr).Elem() |
| return n |
| } |
| |
| // Len returns the remaining number of nodes to be iterated over. |
| func (n *Nodes) Len() int { |
| return n.len - n.pos |
| } |
| |
| // Next returns whether the next call of Node will return a valid node. |
| func (n *Nodes) Next() bool { |
| if n.pos >= n.len { |
| return false |
| } |
| ok := n.iter.Next() |
| if ok { |
| n.pos++ |
| n.value.SetIterValue(&n.iter) |
| } |
| return ok |
| } |
| |
| // Node returns the current node of the iterator. Next must have been |
| // called prior to a call to Node. |
| func (n *Nodes) Node() graph.Node { |
| return n.curr |
| } |
| |
| // Reset returns the iterator to its initial state. |
| func (n *Nodes) Reset() { |
| n.curr = nil |
| n.pos = 0 |
| n.iter.Reset(n.nodes) |
| } |
| |
| // NodeSlice returns all the remaining nodes in the iterator and advances |
| // the iterator. The order of nodes within the returned slice is not |
| // specified. |
| func (n *Nodes) NodeSlice() []graph.Node { |
| if n.Len() == 0 { |
| return nil |
| } |
| nodes := make([]graph.Node, 0, n.Len()) |
| for n.iter.Next() { |
| n.value.SetIterValue(&n.iter) |
| nodes = append(nodes, n.curr) |
| } |
| n.pos = n.len |
| return nodes |
| } |
| |
| // NodesByEdge implements the graph.Nodes interfaces. |
| // The iteration order of Nodes is randomized. |
| type NodesByEdge struct { |
| iter reflect.MapIter |
| pos, len int |
| edges reflect.Value |
| curr graph.Node |
| nodes map[int64]graph.Node |
| } |
| |
| // NewNodesByEdge returns a NodesByEdge initialized with the |
| // provided nodes, a map of node IDs to graph.Nodes, and the set |
| // of edges, a map of to-node IDs to graph.Edge, that can be |
| // traversed to reach the nodes that the NodesByEdge will iterate |
| // over. No check is made that the keys match the graph.Node IDs, |
| // and the map keys are not used. |
| // |
| // Behavior of the NodesByEdge is unspecified if nodes or edges |
| // is mutated after the call to NewNodes. |
| func NewNodesByEdge(nodes map[int64]graph.Node, edges map[int64]graph.Edge) *NodesByEdge { |
| rv := reflect.ValueOf(edges) |
| n := &NodesByEdge{nodes: nodes, len: len(edges), edges: rv} |
| n.iter.Reset(rv) |
| return n |
| } |
| |
| // NewNodesByWeightedEdge returns a NodesByEdge initialized with the |
| // provided nodes, a map of node IDs to graph.Nodes, and the set |
| // of edges, a map of to-node IDs to graph.WeightedEdge, that can be |
| // traversed to reach the nodes that the NodesByEdge will iterate |
| // over. No check is made that the keys match the graph.Node IDs, |
| // and the map keys are not used. |
| // |
| // Behavior of the NodesByEdge is unspecified if nodes or edges |
| // is mutated after the call to NewNodes. |
| func NewNodesByWeightedEdge(nodes map[int64]graph.Node, edges map[int64]graph.WeightedEdge) *NodesByEdge { |
| rv := reflect.ValueOf(edges) |
| n := &NodesByEdge{nodes: nodes, len: len(edges), edges: rv} |
| n.iter.Reset(rv) |
| return n |
| } |
| |
| // NewNodesByLines returns a NodesByEdge initialized with the |
| // provided nodes, a map of node IDs to graph.Nodes, and the set |
| // of lines, a map to-node IDs to map of graph.Line, that can be |
| // traversed to reach the nodes that the NodesByEdge will iterate |
| // over. No check is made that the keys match the graph.Node IDs, |
| // and the map keys are not used. |
| // |
| // Behavior of the NodesByEdge is unspecified if nodes or lines |
| // is mutated after the call to NewNodes. |
| func NewNodesByLines(nodes map[int64]graph.Node, lines map[int64]map[int64]graph.Line) *NodesByEdge { |
| rv := reflect.ValueOf(lines) |
| n := &NodesByEdge{nodes: nodes, len: len(lines), edges: rv} |
| n.iter.Reset(rv) |
| return n |
| } |
| |
| // NewNodesByWeightedLines returns a NodesByEdge initialized with the |
| // provided nodes, a map of node IDs to graph.Nodes, and the set |
| // of lines, a map to-node IDs to map of graph.WeightedLine, that can be |
| // traversed to reach the nodes that the NodesByEdge will iterate |
| // over. No check is made that the keys match the graph.Node IDs, |
| // and the map keys are not used. |
| // |
| // Behavior of the NodesByEdge is unspecified if nodes or lines |
| // is mutated after the call to NewNodes. |
| func NewNodesByWeightedLines(nodes map[int64]graph.Node, lines map[int64]map[int64]graph.WeightedLine) *NodesByEdge { |
| rv := reflect.ValueOf(lines) |
| n := &NodesByEdge{nodes: nodes, len: len(lines), edges: rv} |
| n.iter.Reset(rv) |
| return n |
| } |
| |
| // Len returns the remaining number of nodes to be iterated over. |
| func (n *NodesByEdge) Len() int { |
| return n.len - n.pos |
| } |
| |
| // Next returns whether the next call of Node will return a valid node. |
| func (n *NodesByEdge) Next() bool { |
| if n.pos >= n.len { |
| return false |
| } |
| ok := n.iter.Next() |
| if ok { |
| n.pos++ |
| n.curr = n.nodes[n.iter.Key().Int()] |
| } |
| return ok |
| } |
| |
| // Node returns the current node of the iterator. Next must have been |
| // called prior to a call to Node. |
| func (n *NodesByEdge) Node() graph.Node { |
| return n.curr |
| } |
| |
| // Reset returns the iterator to its initial state. |
| func (n *NodesByEdge) Reset() { |
| n.curr = nil |
| n.pos = 0 |
| n.iter.Reset(n.edges) |
| } |
| |
| // NodeSlice returns all the remaining nodes in the iterator and advances |
| // the iterator. The order of nodes within the returned slice is not |
| // specified. |
| func (n *NodesByEdge) NodeSlice() []graph.Node { |
| if n.Len() == 0 { |
| return nil |
| } |
| nodes := make([]graph.Node, 0, n.Len()) |
| for n.iter.Next() { |
| n.curr = n.nodes[n.iter.Key().Int()] |
| nodes = append(nodes, n.curr) |
| } |
| n.pos = n.len |
| return nodes |
| } |