func (g *immutableDirected) ArcsFrom(v Vertex, f ArcStep) {
	if !g.hasVertex(v) {
		return
	}
	for adjacent := range g.list[v] {
		if f(NewArc(v, adjacent)) {
			return
		}
	}
}
Enumerates the set of out-edges for the provided vertex.
package al
import (
	. "github.com/sdboyer/gogl"
)
type mutableDirected struct {
	al_basic_mut
}
func (g *mutableDirected) OutDegreeOf(vertex Vertex) (degree int, exists bool) {
	g.mu.RLock()
	defer g.mu.RUnlock()
	if exists = g.hasVertex(vertex); exists {
		degree = len(g.list[vertex])
	}
	return
}
func (g *mutableDirected) InDegreeOf(vertex Vertex) (degree int, exists bool) {
	g.mu.RLock()
	defer g.mu.RUnlock()
	return inDegreeOf(g, vertex)
}
func (g *mutableDirected) DegreeOf(vertex Vertex) (degree int, exists bool) {
	g.mu.RLock()
	defer g.mu.RUnlock()
	indegree, exists := inDegreeOf(g, vertex)
	outdegree, exists := g.OutDegreeOf(vertex)
	return indegree + outdegree, exists
}
func (g *mutableDirected) Edges(f EdgeStep) {
	g.mu.RLock()
	defer g.mu.RUnlock()
	for source, adjacent := range g.list {
		for target := range adjacent {
			if f(NewEdge(source, target)) {
				return
			}
		}
	}
}
func (g *mutableDirected) Arcs(f ArcStep) {
	g.mu.RLock()
	defer g.mu.RUnlock()
	for source, adjacent := range g.list {
		for target := range adjacent {
			if f(NewArc(source, target)) {
				return
			}
		}
	}
}
func (g *mutableDirected) IncidentTo(v Vertex, f EdgeStep) {
	g.mu.RLock()
	defer g.mu.RUnlock()
	eachEdgeIncidentToDirected(g, v, f)
}
func (g *mutableDirected) AdjacentTo(start Vertex, f VertexStep) {
	g.mu.RLock()
	defer g.mu.RUnlock()
	g.IncidentTo(start, func(e Edge) bool {
		u, v := e.Both()
		if u == start {
			return f(v)
		} else {
			return f(u)
		}
	})
}
func (g *mutableDirected) ArcsFrom(v Vertex, f ArcStep) {
	g.mu.RLock()
	defer g.mu.RUnlock()
	if !g.hasVertex(v) {
		return
	}
	for adjacent := range g.list[v] {
		if f(NewArc(v, adjacent)) {
			return
		}
	}
}
func (g *mutableDirected) SuccessorsOf(v Vertex, f VertexStep) {
	g.mu.RLock()
	defer g.mu.RUnlock()
	eachVertexInAdjacencyList(g.list, v, f)
}
func (g *mutableDirected) ArcsTo(v Vertex, f ArcStep) {
	g.mu.RLock()
	defer g.mu.RUnlock()
	if !g.hasVertex(v) {
		return
	}
	for candidate, adjacent := range g.list {
		for target := range adjacent {
			if target == v {
				if f(NewArc(candidate, target)) {
					return
				}
			}
		}
	}
}
func (g *mutableDirected) PredecessorsOf(v Vertex, f VertexStep) {
	g.mu.RLock()
	defer g.mu.RUnlock()
	eachPredecessorOf(g.list, v, f)
}
func (g *mutableDirected) HasEdge(edge Edge) bool {
	g.mu.RLock()
	defer g.mu.RUnlock()
	u, v := edge.Both()
	_, exists := g.list[u][v]
	if !exists {
		_, exists = g.list[v][u]
	}
	return exists
}
func (g *mutableDirected) HasArc(arc Arc) bool {
	g.mu.RLock()
	defer g.mu.RUnlock()
	_, exists := g.list[arc.Source()][arc.Target()]
	return exists
}
func (g *mutableDirected) Density() float64 {
	g.mu.RLock()
	defer g.mu.RUnlock()
	order := g.Order()
	return float64(g.Size()) / float64(order*(order-1))
}
func (g *mutableDirected) RemoveVertex(vertices ...Vertex) {
	if len(vertices) == 0 {
		return
	}
	g.mu.Lock()
	defer g.mu.Unlock()
	for _, vertex := range vertices {
		if g.hasVertex(vertex) {
			g.size -= len(g.list[vertex])
			delete(g.list, vertex)
			for _, adjacent := range g.list {
				if _, has := adjacent[vertex]; has {
					delete(adjacent, vertex)
					g.size--
				}
			}
		}
	}
	return
}
func (g *mutableDirected) AddArcs(arcs ...Arc) {
	if len(arcs) == 0 {
		return
	}
	g.mu.Lock()
	defer g.mu.Unlock()
	g.addArcs(arcs...)
}
func (g *mutableDirected) addArcs(arcs ...Arc) {
	for _, arc := range arcs {
		g.ensureVertex(arc.Source(), arc.Target())
		if _, exists := g.list[arc.Source()][arc.Target()]; !exists {
			g.list[arc.Source()][arc.Target()] = keyExists
			g.size++
		}
	}
}
func (g *mutableDirected) RemoveArcs(arcs ...Arc) {
	if len(arcs) == 0 {
		return
	}
	g.mu.Lock()
	defer g.mu.Unlock()
	for _, arc := range arcs {
		s, t := arc.Both()
		if _, exists := g.list[s][t]; exists {
			delete(g.list[s], t)
			g.size--
		}
	}
}
func (g *mutableDirected) Transpose() Digraph {
	g.mu.RLock()
	defer g.mu.RUnlock()
	g2 := &mutableDirected{}
	g2.list = make(map[Vertex]map[Vertex]struct{})
	startcap := int(g.Size() / g.Order())
	for source, adjacent := range g.list {
		if !g2.hasVertex(source) {
			g2.list[source] = make(map[Vertex]struct{}, startcap+1)
		}
		for target := range adjacent {
			if !g2.hasVertex(target) {
				g2.list[target] = make(map[Vertex]struct{}, startcap+1)
			}
			g2.list[target][source] = keyExists
		}
	}
	return g2
}
type immutableDirected struct {
	al_basic_immut
}
func (g *immutableDirected) Edges(f EdgeStep) {
	for source, adjacent := range g.list {
		for target := range adjacent {
			if f(NewEdge(source, target)) {
				return
			}
		}
	}
}
func (g *immutableDirected) Arcs(f ArcStep) {
	for source, adjacent := range g.list {
		for target := range adjacent {
			if f(NewArc(source, target)) {
				return
			}
		}
	}
}
func (g *immutableDirected) IncidentTo(v Vertex, f EdgeStep) {
	eachEdgeIncidentToDirected(g, v, f)
}
func (g *immutableDirected) AdjacentTo(start Vertex, f VertexStep) {
	g.IncidentTo(start, func(e Edge) bool {
		u, v := e.Both()
		if u == start {
			return f(v)
		} else {
			return f(u)
		}
	})
}