summaryrefslogtreecommitdiff
path: root/src/geset.h
blob: 320aa516ca23967f2e9a0eab79fa31f6b8be02d3 (plain) (blame)
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#ifndef LIBGE_GESET_H
#define LIBGE_GESET_H

#include <stdbool.h>

#include <gehashmap.h>

#define GESET_FOREACH(n, t, e, s)                                               \
	for (size_t __ge_i = 0; __ge_i < (s).__cap; __ge_i++)                   \
		for (struct __##n##_hashmap_entry *__ge_e = (s).__ents[__ge_i]; \
		     __ge_e != NULL;                                            \
		     __ge_e = __ge_e->__next)                                   \
			for (bool __ge_c = true; __ge_c; __ge_c = false)        \
				for (t e = __ge_e->key; __ge_c; __ge_c = false)

#define GESET_FOREACH_SAFE(n, t, e, s)                                          \
	for (size_t __ge_i = 0; __ge_i < (s).__cap; __ge_i++)                   \
		for (struct __##n##_hashmap_entry *__ge_e = (s).__ents[__ge_i], \
		     *__ge_t = __ge_e ? __ge_e->__next : NULL;                  \
		     __ge_e != NULL;                                            \
		     __ge_e = __ge_t, __ge_t = __ge_e ? __ge_e->__next : NULL)  \
			for (bool __ge_c = true; __ge_c; __ge_c = false)        \
				for (t e = __ge_e->key; __ge_c; __ge_c = false)

#define GESET_DEF(t, n)                                                         \
	GESET_DEF_API(t, n)                                                     \
	GESET_DEF_IMPL(t, n)

#define GESET_DEF_API(t, n)                                                     \
	GESET_DEF_API_HELPER(t, n, n##_t, __##n##_hashmap)
#define GESET_DEF_API_HELPER(t, n, n_t, int_n)                                  \
	GEHASHMAP_DEF_API(t, int, int_n)                                        \
	                                                                        \
	typedef int_n##_t n_t;                                                  \
	                                                                        \
	int    n##_new(n_t *, size_t, double);                                  \
	void   n##_free(n_t *);                                                 \
	int    n##_add(n_t *, t);                                               \
	bool   n##_has(n_t *, t);                                               \
	size_t n##_size(n_t *);                                                 \
	bool   n##_empty(n_t *);                                                \
	bool   n##_intersects(n_t *, n_t *);                                    \
	int    n##_remove(n_t *, t);                                            \
	int    n##_resize(n_t *, size_t);                                       \
	bool   int_n##_key_iseq(t, t);                                          \
	size_t int_n##_key_hash(t);                                             \
	bool   n##_elem_iseq(t, t);                                             \
	size_t n##_elem_hash(t);

#define GESET_DEF_IMPL(t, n)                                                    \
	GESET_DEF_IMPL_HELPER(t, n, n##_t, __##n##_hashmap)
#define GESET_DEF_IMPL_HELPER(t, n, n_t, int_n)                                 \
	GEHASHMAP_DEF_IMPL(t, int, int_n)                                       \
	                                                                        \
	bool                                                                    \
	int_n##_key_iseq(t a, t b)                                              \
	{                                                                       \
		return n##_elem_iseq(a, b);                                     \
	}                                                                       \
	                                                                        \
	size_t                                                                  \
	int_n##_key_hash(t e)                                                   \
	{                                                                       \
		return n##_elem_hash(e);                                        \
	}                                                                       \
	                                                                        \
	int                                                                     \
	n##_new(n_t *set, size_t cap, double loadf)                             \
	{                                                                       \
		return int_n##_new(set, cap, loadf);                            \
	}                                                                       \
	                                                                        \
	void                                                                    \
	n##_free(n_t *set)                                                      \
	{                                                                       \
		int_n##_free(set);                                              \
	}                                                                       \
	                                                                        \
	int                                                                     \
	n##_add(n_t *set, t e)                                                  \
	{                                                                       \
		return int_n##_set(set, e, 0);                                  \
	}                                                                       \
	                                                                        \
	bool                                                                    \
	n##_has(n_t *set, t e)                                                  \
	{                                                                       \
		return int_n##_has(set, e);                                     \
	}                                                                       \
	                                                                        \
	size_t                                                                  \
	n##_size(n_t *set)                                                      \
	{                                                                       \
		return int_n##_size(set);                                       \
	}                                                                       \
                                                                                \
	bool                                                                    \
	n##_empty(n_t *set)                                                     \
	{                                                                       \
		return int_n##_empty(set);                                      \
	}                                                                       \
                                                                                \
	bool                                                                    \
	n##_intersects(n_t *a, n_t *b)                                          \
	{                                                                       \
		GESET_FOREACH(n, t, e, *a) {                                    \
			if (n##_has(b, e))                                      \
				return true;                                    \
		}                                                               \
		return false;                                                   \
	}                                                                       \
                                                                                \
	int                                                                     \
	n##_remove(n_t *set, t e)                                               \
	{                                                                       \
		return int_n##_remove(set, e);                                  \
	}                                                                       \
	                                                                        \
	int                                                                     \
	n##_resize(n_t *set, size_t ncap)                                       \
	{                                                                       \
		return int_n##_resize(set, ncap);                               \
	}

#endif /* !LIBGE_GESET_H */