summaryrefslogtreecommitdiff
path: root/ccan/agar/agar.h
blob: 495ef7c3bdf548b354234e365c9d7b50bd0b5ead (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/* Licensed under LGPLv2+ - see LICENSE file for details */
#ifndef CCAN_AGAR_H
#define CCAN_AGAR_H
#include "config.h"
#include <string.h>
#include <stdbool.h>

#include <ccan/aga/aga.h>

struct agar_edge_info {
	const void *to;
};

struct agar_graph;
struct agar_state;

typedef int (*agar_edge_info_fn)(const struct agar_graph *gr,
				 const void *nr,
				 const void *e,
				 struct agar_edge_info *ei);
typedef const void *(*agar_first_edge_fn)(const struct agar_graph *gr,
					  const void *nr);
typedef const void *(*agar_next_edge_fn)(const struct agar_graph *gr,
					 const void *nr,
					 const void *e);

struct agar_graph {
	agar_edge_info_fn edge_info;
	agar_first_edge_fn first_edge;
	agar_next_edge_fn next_edge;
};

void agar_init_graph(struct agar_graph *gr,
		     agar_first_edge_fn first_edge,
		     agar_next_edge_fn next_edge,
		     agar_edge_info_fn edge_info);
int agar_error(struct agar_state *sr);

const void *agar_first_edge(const struct agar_graph *g, const void *nr);
const void *agar_next_edge(const struct agar_graph *g, const void *nr,
			   const void *e);
int agar_edge_info(const struct agar_graph *g, const void *nr, const void *e,
		   struct agar_edge_info *eir);

#define agar_for_each_edge(_e, _gr, _nr)				\
	for ((_e) = agar_first_edge((_gr), (_nr)); (_e);		\
	     (_e) = aga_next_edge((_gr), (_nr), (_e)))

#define agar_for_each_edge_info(_e, _eir, _err, _gr, _nr)		\
	for ((_e) = agar_first_edge((_gr), (_nr));			\
	     (_e) && ((((_err) = agar_edge_info((_gr), (_nr), (_e), &(_eir)))) == 0); \
	     (_e) = agar_next_edge((_gr), (_nr), (_e)))			\
		if ((_eir).to)

/*
 * Depth first search
 */
struct agar_state *agar_dfs_new(void *ctx, struct agar_graph *gr);
bool agar_dfs_explore(struct agar_state *sr, const void *nr,
		      const void **nextr);
#define agar_dfs(_nr, _sr, _startr)					\
	for ((_nr) = (_startr); agar_dfs_explore((_sr), (_nr), &(_nr)); )

/*
 * Breadth first search
 */
struct agar_state *agar_bfs_new(void *ctx, struct agar_graph *gr);
bool agar_bfs_explore(struct agar_state *sr, const void *nr,
		      const void **nextr);
#define agar_bfs(_nr, _sr, _startr)					\
	for ((_nr) = (_startr); agar_bfs_explore((_sr), (_nr), &(_nr)); )

#endif /* CCAN_AGAR_H */