nodes_edges.go 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. // Copyright ©2018 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. package graph
  5. // Iterator is an item iterator.
  6. type Iterator interface {
  7. // Next advances the iterator and returns whether
  8. // the next call to the item method will return a
  9. // non-nil item.
  10. //
  11. // Next should be called prior to any call to the
  12. // iterator's item retrieval method after the
  13. // iterator has been obtained or reset.
  14. //
  15. // The order of iteration is implementation
  16. // dependent.
  17. Next() bool
  18. // Len returns the number of items remaining in the
  19. // iterator.
  20. //
  21. // If the number of items in the iterator is unknown,
  22. // too large to materialize or too costly to calculate
  23. // then Len may return a negative value.
  24. // In this case the consuming function must be able
  25. // to operate on the items of the iterator directly
  26. // without materializing the items into a slice.
  27. // The magnitude of a negative length has
  28. // implementation-dependent semantics.
  29. Len() int
  30. // Reset returns the iterator to its start position.
  31. Reset()
  32. }
  33. // Nodes is a Node iterator.
  34. type Nodes interface {
  35. Iterator
  36. // Node returns the current Node from the iterator.
  37. Node() Node
  38. }
  39. // NodeSlicer wraps the NodeSlice method.
  40. type NodeSlicer interface {
  41. // NodeSlice returns the set of nodes remaining
  42. // to be iterated by a Nodes iterator.
  43. // The holder of the iterator may arbitrarily
  44. // change elements in the returned slice, but
  45. // those changes may be reflected to other
  46. // iterators.
  47. NodeSlice() []Node
  48. }
  49. // NodesOf returns it.Len() nodes from it. If it is a NodeSlicer, the NodeSlice method
  50. // is used to obtain the nodes. It is safe to pass a nil Nodes to NodesOf.
  51. //
  52. // If the Nodes has an indeterminate length, NodesOf will panic.
  53. func NodesOf(it Nodes) []Node {
  54. if it == nil {
  55. return nil
  56. }
  57. len := it.Len()
  58. switch {
  59. case len == 0:
  60. return nil
  61. case len < 0:
  62. panic("graph: called NodesOf on indeterminate iterator")
  63. }
  64. switch it := it.(type) {
  65. case NodeSlicer:
  66. return it.NodeSlice()
  67. }
  68. n := make([]Node, 0, len)
  69. for it.Next() {
  70. n = append(n, it.Node())
  71. }
  72. return n
  73. }
  74. // Edges is an Edge iterator.
  75. type Edges interface {
  76. Iterator
  77. // Edge returns the current Edge from the iterator.
  78. Edge() Edge
  79. }
  80. // EdgeSlicer wraps the EdgeSlice method.
  81. type EdgeSlicer interface {
  82. // EdgeSlice returns the set of edges remaining
  83. // to be iterated by an Edges iterator.
  84. // The holder of the iterator may arbitrarily
  85. // change elements in the returned slice, but
  86. // those changes may be reflected to other
  87. // iterators.
  88. EdgeSlice() []Edge
  89. }
  90. // EdgesOf returns it.Len() nodes from it. If it is an EdgeSlicer, the EdgeSlice method is used
  91. // to obtain the edges. It is safe to pass a nil Edges to EdgesOf.
  92. //
  93. // If the Edges has an indeterminate length, EdgesOf will panic.
  94. func EdgesOf(it Edges) []Edge {
  95. if it == nil {
  96. return nil
  97. }
  98. len := it.Len()
  99. switch {
  100. case len == 0:
  101. return nil
  102. case len < 0:
  103. panic("graph: called EdgesOf on indeterminate iterator")
  104. }
  105. switch it := it.(type) {
  106. case EdgeSlicer:
  107. return it.EdgeSlice()
  108. }
  109. e := make([]Edge, 0, len)
  110. for it.Next() {
  111. e = append(e, it.Edge())
  112. }
  113. return e
  114. }
  115. // WeightedEdges is a WeightedEdge iterator.
  116. type WeightedEdges interface {
  117. Iterator
  118. // Edge returns the current Edge from the iterator.
  119. WeightedEdge() WeightedEdge
  120. }
  121. // WeightedEdgeSlicer wraps the WeightedEdgeSlice method.
  122. type WeightedEdgeSlicer interface {
  123. // EdgeSlice returns the set of edges remaining
  124. // to be iterated by an Edges iterator.
  125. // The holder of the iterator may arbitrarily
  126. // change elements in the returned slice, but
  127. // those changes may be reflected to other
  128. // iterators.
  129. WeightedEdgeSlice() []WeightedEdge
  130. }
  131. // WeightedEdgesOf returns it.Len() weighted edge from it. If it is a WeightedEdgeSlicer, the
  132. // WeightedEdgeSlice method is used to obtain the edges. It is safe to pass a nil WeightedEdges
  133. // to WeightedEdgesOf.
  134. //
  135. // If the WeightedEdges has an indeterminate length, WeightedEdgesOf will panic.
  136. func WeightedEdgesOf(it WeightedEdges) []WeightedEdge {
  137. if it == nil {
  138. return nil
  139. }
  140. len := it.Len()
  141. switch {
  142. case len == 0:
  143. return nil
  144. case len < 0:
  145. panic("graph: called WeightedEdgesOf on indeterminate iterator")
  146. }
  147. switch it := it.(type) {
  148. case WeightedEdgeSlicer:
  149. return it.WeightedEdgeSlice()
  150. }
  151. e := make([]WeightedEdge, 0, len)
  152. for it.Next() {
  153. e = append(e, it.WeightedEdge())
  154. }
  155. return e
  156. }
  157. // Lines is a Line iterator.
  158. type Lines interface {
  159. Iterator
  160. // Line returns the current Line from the iterator.
  161. Line() Line
  162. }
  163. // LineSlicer wraps the LineSlice method.
  164. type LineSlicer interface {
  165. // LineSlice returns the set of lines remaining
  166. // to be iterated by an Lines iterator.
  167. // The holder of the iterator may arbitrarily
  168. // change elements in the returned slice, but
  169. // those changes may be reflected to other
  170. // iterators.
  171. LineSlice() []Line
  172. }
  173. // LinesOf returns it.Len() nodes from it. If it is a LineSlicer, the LineSlice method is used
  174. // to obtain the lines. It is safe to pass a nil Lines to LinesOf.
  175. //
  176. // If the Lines has an indeterminate length, LinesOf will panic.
  177. func LinesOf(it Lines) []Line {
  178. if it == nil {
  179. return nil
  180. }
  181. len := it.Len()
  182. switch {
  183. case len == 0:
  184. return nil
  185. case len < 0:
  186. panic("graph: called LinesOf on indeterminate iterator")
  187. }
  188. switch it := it.(type) {
  189. case LineSlicer:
  190. return it.LineSlice()
  191. }
  192. l := make([]Line, 0, len)
  193. for it.Next() {
  194. l = append(l, it.Line())
  195. }
  196. return l
  197. }
  198. // WeightedLines is a WeightedLine iterator.
  199. type WeightedLines interface {
  200. Iterator
  201. // Line returns the current Line from the iterator.
  202. WeightedLine() WeightedLine
  203. }
  204. // WeightedLineSlicer wraps the WeightedLineSlice method.
  205. type WeightedLineSlicer interface {
  206. // LineSlice returns the set of lines remaining
  207. // to be iterated by an Lines iterator.
  208. // The holder of the iterator may arbitrarily
  209. // change elements in the returned slice, but
  210. // those changes may be reflected to other
  211. // iterators.
  212. WeightedLineSlice() []WeightedLine
  213. }
  214. // WeightedLinesOf returns it.Len() weighted line from it. If it is a WeightedLineSlicer, the
  215. // WeightedLineSlice method is used to obtain the lines. It is safe to pass a nil WeightedLines
  216. // to WeightedLinesOf.
  217. //
  218. // If the WeightedLines has an indeterminate length, WeightedLinesOf will panic.
  219. func WeightedLinesOf(it WeightedLines) []WeightedLine {
  220. if it == nil {
  221. return nil
  222. }
  223. len := it.Len()
  224. switch {
  225. case len == 0:
  226. return nil
  227. case len < 0:
  228. panic("graph: called WeightedLinesOf on indeterminate iterator")
  229. }
  230. switch it := it.(type) {
  231. case WeightedLineSlicer:
  232. return it.WeightedLineSlice()
  233. }
  234. l := make([]WeightedLine, 0, len)
  235. for it.Next() {
  236. l = append(l, it.WeightedLine())
  237. }
  238. return l
  239. }
  240. // Empty is an empty set of nodes, edges or lines. It should be used when
  241. // a graph returns a zero-length Iterator. Empty implements the slicer
  242. // interfaces for nodes, edges and lines, returning nil for each of these.
  243. const Empty = nothing
  244. var (
  245. _ Iterator = Empty
  246. _ Nodes = Empty
  247. _ NodeSlicer = Empty
  248. _ Edges = Empty
  249. _ EdgeSlicer = Empty
  250. _ WeightedEdges = Empty
  251. _ WeightedEdgeSlicer = Empty
  252. _ Lines = Empty
  253. _ LineSlicer = Empty
  254. _ WeightedLines = Empty
  255. _ WeightedLineSlicer = Empty
  256. )
  257. const nothing = empty(true)
  258. type empty bool
  259. func (empty) Next() bool { return false }
  260. func (empty) Len() int { return 0 }
  261. func (empty) Reset() {}
  262. func (empty) Node() Node { return nil }
  263. func (empty) NodeSlice() []Node { return nil }
  264. func (empty) Edge() Edge { return nil }
  265. func (empty) EdgeSlice() []Edge { return nil }
  266. func (empty) WeightedEdge() WeightedEdge { return nil }
  267. func (empty) WeightedEdgeSlice() []WeightedEdge { return nil }
  268. func (empty) Line() Line { return nil }
  269. func (empty) LineSlice() []Line { return nil }
  270. func (empty) WeightedLine() WeightedLine { return nil }
  271. func (empty) WeightedLineSlice() []WeightedLine { return nil }