@@ -270,11 +270,30 @@ end
270270@inline function _fadj_0based (g:: SparseGraphRep , v:: Integer )
271271 # return the adjacency of vertex `v` as an array over nauty's edge list
272272 # the resulting indices are zero-based
273- # only the neighbour list is wrapped, rather than all three of nauty's arrays
274- offset = unsafe_load (g. v, v)
275- degree = unsafe_load (g. d, v)
273+ offset, degree = _adjacencybounds (g, v)
276274 return unsafe_wrap (Array, g. e + offset * sizeof (Cint), degree)
277275end
276+
277+ # Where vertex `v`'s neighbours sit in the edge list, as a zero-based offset and a length (degree).
278+ @inline _adjacencybounds (g:: SparseGraphRep , v:: Integer ) = (unsafe_load (g. v, v), unsafe_load (g. d, v))
279+ @inline _adjacencybounds (g:: SparseNautyGraph , v:: Integer ) = (g. v[v], g. d[v])
280+
281+ # The whole edge list as one array.
282+ @inline _edgelist (g:: SparseNautyGraph ) = g. e
283+ @inline function _edgelist (g:: SparseGraphRep )
284+ # nauty leaves the pointer null for a graph with no edges, which must not be wrapped
285+ return iszero (g. nde) ? Cint[] : unsafe_wrap (Array, g. e, g. nde)
286+ end
287+
288+ @inline _adjacencyview (edgelist, offset, degree) = @view edgelist[(offset + 1 ): (offset + degree)]
289+
290+ # Iterate the adjacency of every vertex of `g` in order, as zero-based views into its edge list.
291+ # Unlike calling `_fadj_0based` per vertex, this wraps nauty's edge array only once, which matters
292+ # for callers that walk the whole graph.
293+ @inline function _fadjs_0based (g)
294+ edgelist = _edgelist (g)
295+ return (_adjacencyview (edgelist, _adjacencybounds (g, v)... ) for v in Base. OneTo (Int (g. nv)))
296+ end
278297@inline function Graphs. outneighbors (g:: SparseNautyGraph , v:: Integer )
279298 # following the Graph.jl implementation, there is no boundscheck here
280299 return (zero2one (g. e[i]) for i in (zero2one (g. v[v])): (g. v[v] + g. d[v]))
0 commit comments